How to Identify the Commit That Introduced the Bug in Git
In Git, to identify which commit introduced the bug, we typically use the git bisect tool. git bisect is a binary search utility that helps us efficiently pinpoint the commit responsible for the bug. Below are the detailed steps and examples:
-
Start
git bisect: First, initiate the binary search mode using the commandgit bisect start. -
Mark the bad commit: Next, identify and mark a known bad commit containing the bug, typically the latest commit. This is done with
git bisect bad. You can specify a particular commit; if omitted, it defaults to the current HEAD. -
Mark the good commit: Then, locate an earlier commit that does not contain the bug and mark it as good using
git bisect good [commit-id]. -
Binary search: Once both good and bad commits are marked, Git automatically switches the repository to the middle commit. Test this commit to determine if it contains the bug. If it does, mark it with
git bisect bad; if not, mark it withgit bisect good. Git will continue selecting middle commits for testing. -
Repeat testing: Repeat step 4. After each test, Git automatically narrows the range of potential bug-introducing commits until the exact commit is identified.
-
End the search: Once the bug-introducing commit is found, use
git bisect resetto terminate thegit bisectprocess, restoring the repository to its state before the search began.
Example: Suppose we have a project where the latest commit has a non-functional feature. We know the version from one month ago is working. We can proceed as follows:
bashgit bisect start git bisect bad # Assume current HEAD contains the bug git bisect good commit-id-of-one-month-ago # Mark the commit from one month ago as good # Git automatically switches to the middle commit # Run tests: if the test fails, execute `git bisect bad`; if it passes, execute `git bisect good` # Repeat this until the bug commit is found git bisect reset # End bisect and return to initial state
By using this method, we can systematically and effectively determine the specific commit that introduced the bug. This approach is highly beneficial for maintaining large-scale projects.