Git Bisect
The git bisect command in Git efficiently identifies the commit introducing a bug by employing a binary search mechanism, significantly streamlining the debugging process. Rather than manually checking each commit sequentially, which could be time-consuming, git bisect automates this by narrowing down potential faulty commits through a series of binary searches. The user provides a "good" commit (where the code functions correctly) and a "bad" commit (where the bug appears). git bisect then intelligently navigates between commits, pinpointing the exact one that transitions the code from a working to a faulty state. ---image
Pre-requisites
The prerequisites for learning the bisect command can be a basic understanding of Version Control Systems, Branching, and Git. Before learning about the bisect command, let us discuss them briefly.
A version control system is a tool in software development that tracks the changes in the code, documents, and other important information regarding a certain code base (or project), etc. Git is a version control system that tracks the changes in the code, documents, and other important information regarding a certain code base (or project), etc. Git is free and one of the most widely used version control systems. Apart from that, we must know the concepts of the git log command and the git status command as both of these commands will help us to know the exact scenario of the Git repository.
Basic bisect commands
Let us look at the various commands associated with the bisect command.
- git bisect start: This command is used to make the Git work in the bisect mode apart from this, it also lets the Git wait for the further bisect commands.
- git bisect bad (commit hash or tag): This command is used to inform the commit that is bad. It can provide the hash or tag that we want.
- git bisect good (commit hash or tag): This command is used to inform the commit that is good. It can also provide the hash or tag that we want.
- git bisect reset: As the name suggests, this command is used to exit the bisect mode. Hence, when we execute this command, the Git is returned to its original mode exiting the bisect mode.
OPTIONS
Let us look at the various options associated with the bisect command.
- old: The old option is used to indicate the commit that was there before the sought change.
- new: The new option is used to indicate the commit that was there after the sought change.
- terms: The terms option is used to get the remainder of the terms that are currently used. Some of its variations are: git bisect terms --term-old and git bisect terms --term-good.
- view or visualize: Both the view and visualize options are used interchangeably to see all the suspects remaining in the gitk. We can also use the git log command for the same if the DISPLAY environment variable is not set. Apart from these, we can also provide the -p and --stat options from the command line.
- skip: The skip option is used to make Git choose a nearby commit instead of doing it by ourselves.
- --no-checkout: This option makes Git not check out the new working tree every time there is an iteration of the git bisection process. It updates the BISECT_HEAD which is a special reference. This special reference lets Git point to a commit that has to be tested. We must know that if our repository is bare then we cannot assume the --no-checkout option.
- --first-parent: This option sets the first parent commit when Git sees a merge commit. This command is used in scenarios where we want to avoid false positives in a merged branch that contains broken or non-buildable commits. Here the merge is okay to be made.
To learn more about the various commands and options associated with the bisect command, you can refer to the official documentation here.
Example: Use of Git Bisect to Find the Faulty Commit
Let us take an example of seeing how the bisect command works. Suppose we have a repository named test and we have initialized the test repository as a git repository. Suppose we have made numerous commits on the repository, the most recent commit made is a bad commit (with commit id: b428150c2d21) and the very first commit that we have made is a good commit (with commit id: dd28150c2d21).
As we have the good and bad commits, we are now ready with the process of elimination using the bisect command. Let us look at the stepwise approach for the same.
- The very first step that we need to follow is to start the bisect wizard using the command:
- The second step is letting the command know the good commit using the command:
Here, dd28150c2d21 is the good commit's commit id.
- The third step is letting the command know the bad commit using the command:
Here, b428150c2d21 is the bad commit's commit id. This command will internally check the old commits halfway between the already known good commit and the latest bad commit.
After this, we can fix the issue, and hence the work is done. So finally when the work is done, we can run the following command to end the bisect wizard.
Automating git bisect
We have another awesome feature associated with the bisect command, it is git bisect run. This run subcommand or option helps us to run any script or pass any program. Git will interpret the zero code as a successful or a good commit, on the other hand, Git will interpret the non-zero code as a bad or failed commit.
For example, if we have a script present in the file: test.sh then we can run the following command:
A sample script for testing good and bad commit can be:
Conclusion
- Git is a version control system that tracks the changes in the code, documents, and other important information regarding a certain code base (or project), etc.
- If there are numerous commits and we want to check which commit is bad and causing errors then it will be a very tedious task.
- The bisect command walks us through the most recent commits in order and then lets us decide whether the commit is good or not. This process helps us to narrow down the search for the broken commit.
- The bisect command internally uses the concept of binary search to detect the commit that introduced the bug.
- The bisect start command is used to make the Git work in the bisect mode apart from this, it also lets the Git wait for further bisect commands.
- The bisect bad (commit hash or tag) command is used to inform the commit that is bad. It can provide the hash or tag that we want.
- The bisect good (commit hash or tag) command is used to inform the commit that is good. It can also provide the hash or tag that we want.
- The git bisect reset command is used to exit the bisect mode. Hence, when we execute this command, the Git is returned to its original mode exiting the bisect mode.
- The old option is used to indicate the commit that was there before the sought change. The new option is used to indicate the commit that was there after the sought change.
- The --no-checkout option makes Git not check out the new working tree every time there is an iteration of the git bisection process. It updates the BISECT_HEAD which is a special reference. This special reference lets Git point to a commit that has to be tested.
- The --first-parent option sets the first parent commit when Git sees a merge commit. This command is used in scenarios where we want to avoid false positives in a merged branch that contains broken or non-buildable commits. Here the merge is okay to be made.
- The run subcommand or option helps us to run any script or pass any program. Git will interpret the zero code as a successful or a good commit, on the other hand, Git will interpret the non-zero code as a bad or failed commit.