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.git
Navigate to the cloned repository:
cd git-bisect-demo
Step 2: Start the git bisect
Workflow
The
git-bisect-demo
repository contains a bug in thesquare()
function. Your task is to identify the commit that introduced the bug usinggit bisect
.Begin by starting the
git bisect
process:git bisect start
Mark 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 bad
Identify 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 log
to 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.R
file and inspect the code. If the bug is present, mark the commit asbad
:git bisect bad
If 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
good
andbad
marks. Repeat the process of inspecting the code and marking each commit as eithergood
orbad
until 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-bug
Open the
script.R
file and modify thesquare()
function to correct the bug:<- function(x) { square 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-bug
Step 5: Complete the Bisect and Create a Pull Request
End the
git bisect
session:git bisect reset
Push your changes to your GitHub fork:
git push origin master
Go to your GitHub repository and create a Pull Request from your fork’s
master
branch 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 log
to help you identify the commit hashes. - If you make a mistake or want to change your
good
/bad
marks, usegit bisect reset
to 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
square
function produces incorrect results for certain inputs, and you’ll need to test it during thegit bisect
process.
- The bug is that the
- Create a Test Script for Bisect
- Create a new file called
test-bisect.R
in 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 bisect
uses 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
square
function. 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")
<- square(2)
result
if (result != 4) {
quit(status = 1)
else {
} quit(status = 0)
}
Explanation of the Script:
- This script runs an R command using
Rscript
, sources thescript.R
file, calls thesquare
function 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 bisect
that 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 bisect
using 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 bisect
will automatically check each commit in the range between the good and bad commits by using thebisect_test.sh
script. When the process finishes,git bisect
will 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!