ETC5513: Collaborative and Reproducible Practices
Workshop 9
Workshop: Finding and Fixing a Bug with git bisect
Objective:
In this workshop, you will practice using git bisect to identify the commit that introduced a bug into a repository. You will also make a pull request to fix the bug once you’ve found it.
Pre-requisite:
Before beginning, make sure you have: - Forked the repository git-bisect-demo into your own GitHub account. - Cloned the repository from your fork to your local machine.
Step 1: Fork the Repository
Go to the git-bisect-demo repository.
In the top-right corner, click the Fork button to create your own copy of the repository on GitHub.
After forking, clone your fork to your local machine using the following command:
git clone https://github.com/<your-username>/git-bisect-demo.gitNavigate to the cloned repository:
cd git-bisect-demo
Step 2: Start the git bisect Workflow
The
git-bisect-demorepository contains a bug in thesquare()function. Your task is to identify the commit that introduced the bug usinggit bisect.Begin by starting the
git bisectprocess:git bisect startMark the current (bad) commit:
Since the latest commit has the bug in it (the
square()function is broken), we will mark it asbad:git bisect badIdentify a good commit:
The
square()function was working correctly before the bug was introduced. To identify a “good” commit, we need to mark a commit before the bug was introduced. You can look at the GitHub history or usegit logto find a commit before the bug was introduced (for example, commit 10).git bisect good <commit-hash>- Replace
<commit-hash>with the hash of a known good commit (such as the initial commit or the last commit before the bug was introduced).
- Replace
Step 3: Bisecting the Commits
Now, Git will automatically check out a commit halfway between the good and bad commits. Your job is to test whether the bug is present in this commit.
Open the
script.Rfile and inspect the code. If the bug is present, mark the commit asbad:git bisect badIf the bug is not present, mark the commit as
good:git bisect good
Git will continue to narrow down the commits by checking out commits halfway between the last
goodandbadmarks. Repeat the process of inspecting the code and marking each commit as eithergoodorbaduntil Git identifies the commit that introduced the bug.
Step 4: Fix the Bug
Once the commit has been identified, you should make a branch from that point to fix the bug.
git switch -C fix-square-bugOpen the
script.Rfile and modify thesquare()function to correct the bug:square <- function(x) { return(x * x) # Fix the bug (it was previously x + x) }Commit the fix:
git add script.R git commit -m "Fix bug in square function"Push the changes to GitHub:
git push origin fix-square-bugStep 5: Complete the Bisect and Create a Pull Request
End the
git bisectsession:git bisect resetPush your changes to your GitHub fork:
git push origin masterGo to your GitHub repository and create a Pull Request from your fork’s
masterbranch to the original repository (mikelydeamore/git-bisect-demo).- Make sure to provide a detailed description in the pull request, explaining:
- The bug that was fixed.
- The process you used to find the bug using
git bisect. - The fix you made.
- Make sure to provide a detailed description in the pull request, explaining:
Tips:
- If you’re not sure which commit is good or bad, use
git logto help you identify the commit hashes. - If you make a mistake or want to change your
good/badmarks, usegit bisect resetto start the process over. - Don’t forget to push your changes to your fork after fixing the bug!
Conclusion
In this workshop, you learned how to use git bisect to find the commit that introduced a bug in a Git repository. You also learned how to fix the bug and create a pull request with your fix. This process is very useful for debugging and narrowing down the source of issues in large codebases.
Advanced Exercise: Create a Script for Git Bisect Testing
In this exercise, you’ll write a test script that automatically checks for the bug in the square function, which you can use during the git bisect process. This script will be used to help you determine the exact commit that introduced the bug.
Steps:
- Understand the Bug
- The bug is that the
squarefunction produces incorrect results for certain inputs, and you’ll need to test it during thegit bisectprocess.
- The bug is that the
- Create a Test Script for Bisect
- Create a new file called
test-bisect.Rin the repository. This file will contain an R script for testing the bug. It will return0(success) if the bug is not present and1(failure) if the bug is present.git bisectuses this exit code to determine whether to continue searching in the good or bad commit range.
- Create a new file called
- Write the Bisect Test Script
- The script should check the functionality of the
squarefunction. For the purposes of this exercise, assume the bug is present when the result ofsquare(2)is not equal to4.
- The script should check the functionality of the
source("script.R")
result <- square(2)
if (result != 4) {
quit(status = 1)
} else {
quit(status = 0)
}Explanation of the Script:
- This script runs an R command using
Rscript, sources thescript.Rfile, calls thesquarefunction with an input of2, and checks if the result is4. - If the result is not
4, the script exits with a status code of1, which signalsgit bisectthat the bug is present in the current commit (bad commit). - If the result is
4, the script exits with a status code of0, signaling that the commit is “good”.
- Run
git bisect- Now, you can start
git bisectusing the following commands:
- Now, you can start
# Start the bisect process by specifying a good commit and a bad commit
git bisect start
git bisect bad # This marks the current commit as bad (contains the bug)
git bisect good <commit-hash> # This marks an older commit as good (before the bug)
# Use the bisect_test.sh script to automatically test each commit
git bisect run Rscript test-bisect.R- Interpreting the Results
git bisectwill automatically check each commit in the range between the good and bad commits by using thebisect_test.shscript. When the process finishes,git bisectwill tell you the first bad commit where the bug was introduced.- Once the bisect process completes, run the following command to reset the repository to its original state:
git bisect reset- Check whether the automatic bisect has worked
Check the contents of script.R and see if you have found the bug. If not, you may need to modify test-bisect.R to better capture the case where the bug is present!