feat: move late modules
This commit is contained in:
231
module-13-bisect/README.md
Normal file
231
module-13-bisect/README.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# Module 14: Bisect - Finding Bugs with Binary Search
|
||||
|
||||
## Learning Objectives
|
||||
|
||||
By the end of this module, you will:
|
||||
- Understand what git bisect is and when to use it
|
||||
- Use binary search to find the commit that introduced a bug
|
||||
- Mark commits as good or bad during bisection
|
||||
- Automate bisect with test scripts
|
||||
- Understand the efficiency of binary search for debugging
|
||||
|
||||
## Challenge Description
|
||||
|
||||
A bug has appeared in your calculator application, but you don't know which commit introduced it. The project has many commits, and manually checking each one would take too long. You'll use `git bisect` to efficiently find the culprit commit using binary search.
|
||||
|
||||
Your task is to:
|
||||
1. Start a bisect session
|
||||
2. Mark the current commit as bad (bug exists)
|
||||
3. Mark an old commit as good (bug didn't exist)
|
||||
4. Test commits and mark them good or bad
|
||||
5. Let Git find the first bad commit
|
||||
6. Identify what change introduced the bug
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### What is Git Bisect?
|
||||
|
||||
Git bisect uses binary search to find the commit that introduced a bug. Instead of checking every commit linearly, it cuts the search space in half with each test, making it extremely efficient.
|
||||
|
||||
### Binary Search Efficiency
|
||||
|
||||
**Linear Search (manual checking):**
|
||||
- 100 commits = up to 100 tests
|
||||
- 1000 commits = up to 1000 tests
|
||||
|
||||
**Binary Search (bisect):**
|
||||
- 100 commits = ~7 tests
|
||||
- 1000 commits = ~10 tests
|
||||
|
||||
Formula: log₂(n) tests needed for n commits
|
||||
|
||||
### How Bisect Works
|
||||
|
||||
```
|
||||
Commits: A---B---C---D---E---F---G---H
|
||||
✓ ✓ ✓ ? ? ? ? ✗
|
||||
|
||||
1. Start: Mark H (bad) and A (good)
|
||||
2. Git checks middle: E
|
||||
3. You test E: bad ✗
|
||||
|
||||
Commits: A---B---C---D---E
|
||||
✓ ✓ ✓ ? ✗
|
||||
|
||||
4. Git checks middle: C
|
||||
5. You test C: good ✓
|
||||
|
||||
Commits: C---D---E
|
||||
✓ ? ✗
|
||||
|
||||
6. Git checks: D
|
||||
7. You test D: bad ✗
|
||||
|
||||
Result: D is the first bad commit!
|
||||
```
|
||||
|
||||
### When to Use Bisect
|
||||
|
||||
Use bisect when:
|
||||
- You know a bug exists now but didn't exist in the past
|
||||
- You have many commits to check
|
||||
- You can reliably test for the bug
|
||||
- You want to find exactly when something broke
|
||||
|
||||
## Useful Commands
|
||||
|
||||
```bash
|
||||
# Start bisect session
|
||||
git bisect start
|
||||
|
||||
# Mark current commit as bad
|
||||
git bisect bad
|
||||
|
||||
# Mark a commit as good
|
||||
git bisect good <commit-hash>
|
||||
git bisect good HEAD~10
|
||||
|
||||
# After testing current commit
|
||||
git bisect good # This commit is fine
|
||||
git bisect bad # This commit has the bug
|
||||
|
||||
# Skip a commit (if you can't test it)
|
||||
git bisect skip
|
||||
|
||||
# End bisect session and return to original state
|
||||
git bisect reset
|
||||
|
||||
# Visualize bisect process
|
||||
git bisect visualize
|
||||
git bisect view
|
||||
|
||||
# Automate with a test script
|
||||
git bisect run <test-script>
|
||||
git bisect run npm test
|
||||
git bisect run ./test.sh
|
||||
|
||||
# Show bisect log
|
||||
git bisect log
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Run the verification script to check your solution:
|
||||
|
||||
```bash
|
||||
.\verify.ps1
|
||||
```
|
||||
|
||||
The verification will check that:
|
||||
- You completed a bisect session
|
||||
- You identified the correct commit that introduced the bug
|
||||
- You understand which change caused the problem
|
||||
|
||||
## Challenge Steps
|
||||
|
||||
1. Navigate to the challenge directory
|
||||
2. View the bug: run the calculator and see it fails
|
||||
3. Start bisect: `git bisect start`
|
||||
4. Mark current as bad: `git bisect bad`
|
||||
5. Mark old commit as good: `git bisect good HEAD~10`
|
||||
6. Git will checkout a middle commit
|
||||
7. Test the current commit (run the test or check manually)
|
||||
8. Mark it: `git bisect good` or `git bisect bad`
|
||||
9. Repeat testing until Git identifies the bad commit
|
||||
10. Note the commit hash and message
|
||||
11. End bisect: `git bisect reset`
|
||||
12. Check the identified commit: `git show <bad-commit-hash>`
|
||||
13. Create a file named `bug-commit.txt` with the bad commit hash
|
||||
14. Run verification
|
||||
|
||||
## Tips
|
||||
|
||||
- Always start with a known good commit (far enough back)
|
||||
- Keep a clear way to test each commit (script or manual steps)
|
||||
- Use `git bisect log` to see your progress
|
||||
- `git bisect reset` returns you to your original state
|
||||
- You can bisect on any criteria, not just bugs (performance, features, etc.)
|
||||
- Automate with `git bisect run` for faster results
|
||||
- Each bisect step cuts remaining commits in half
|
||||
- Skip commits you can't build/test with `git bisect skip`
|
||||
|
||||
## Manual vs Automated Bisect
|
||||
|
||||
### Manual Bisect
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad
|
||||
git bisect good HEAD~20
|
||||
|
||||
# For each commit Git checks out:
|
||||
npm test
|
||||
git bisect good # or bad
|
||||
|
||||
git bisect reset
|
||||
```
|
||||
|
||||
### Automated Bisect
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad
|
||||
git bisect good HEAD~20
|
||||
git bisect run npm test
|
||||
# Git automatically tests each commit
|
||||
git bisect reset
|
||||
```
|
||||
|
||||
The test script should exit with:
|
||||
- 0 for good (test passes)
|
||||
- 1-127 (except 125) for bad (test fails)
|
||||
- 125 for skip (can't test this commit)
|
||||
|
||||
## Bisect Workflow Example
|
||||
|
||||
### Finding a Performance Regression
|
||||
```bash
|
||||
# App is slow now, was fast 50 commits ago
|
||||
git bisect start
|
||||
git bisect bad
|
||||
git bisect good HEAD~50
|
||||
|
||||
# Create test script
|
||||
echo '#!/bin/bash\ntime npm start | grep "Started in"' > test.sh
|
||||
chmod +x test.sh
|
||||
|
||||
git bisect run ./test.sh
|
||||
# Git finds the commit that made it slow
|
||||
```
|
||||
|
||||
### Finding When a Feature Broke
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad
|
||||
git bisect good v1.0.0 # Last known good version
|
||||
|
||||
# For each commit
|
||||
npm test -- user-login.test.js
|
||||
git bisect good # or bad
|
||||
|
||||
# Found! Commit abc123 broke login
|
||||
git show abc123
|
||||
```
|
||||
|
||||
## Common Bisect Pitfalls
|
||||
|
||||
### Pitfall 1: Testing Incorrectly
|
||||
- Make sure your test is consistent
|
||||
- Automate when possible to avoid human error
|
||||
- Use the same test for every commit
|
||||
|
||||
### Pitfall 2: Wrong Good Commit
|
||||
- If the "good" commit actually has the bug, bisect will fail
|
||||
- Choose a commit you're confident was working
|
||||
|
||||
### Pitfall 3: Multiple Bugs
|
||||
- Bisect finds one commit at a time
|
||||
- If multiple bugs exist, they might confuse the search
|
||||
- Fix found bugs and bisect again for others
|
||||
|
||||
## What You'll Learn
|
||||
|
||||
Git bisect is a powerful debugging tool that turns a tedious manual search into an efficient automated process. By leveraging binary search, you can quickly pinpoint problematic commits even in repositories with thousands of commits. This is invaluable for debugging regressions, performance issues, or any situation where something that worked before is now broken. Mastering bisect makes you a more effective debugger and shows deep Git proficiency.
|
||||
Reference in New Issue
Block a user