A couple of days ago, one of my colleagues at robusta recommended an interesting git command to use, and it was my first time hearing about it. I started searching, and then I decided that I would write a summary about it.
Have you ever been into a situation where you are writing your code, and you push commits after commits, and after a while, you go around your project and find a bug, Now this bug could happen anytime between your last commit and the last 1000 commits, so this makes it extremely hard to track down what happened and from where did you know the bug occurred? So instead of going one commit by one commit, which is time-consuming and will probably frustrate you because it's a linear search, git bisect will be your answer.
In this blog, we will explore the
git bisect command, how it works, how to use it, and other useful commands to reduce your time of debugging and make you a Git Geek 😎
git bisect is a way to use a binary search algorithm to find the commit that introduced a bug easily and quickly. It's a very useful command to help you in your process of tracing and debugging. Imagine you have N commits, by using this command, you will find the buggy commit in only log(N) steps!
If you know the Binary Search concept, you can skip the next section.
Binary Search is an efficient algorithm for finding an item from a sorted list of items. It works by repeatedly dividing in half the portion of the list that could contain the item until you've narrowed down the possible locations to just one.
The example below explains the concept of binary search, we need to find 47 as fast as possible. We can achieve that by:
1. Dividing the array into two parts, and now the mid is 14, so 14 < 47
2. I will divide the right part and the mid is 45, so 45 < 47
3. I will divide the right part again, and the mid will be 47, so 47 = 47.
After understanding the concept of binary search,
git bisect works in the same way. It allows you to use binary search to find buggy commits. Binary search makes finding things faster, instead of looking at all commits one by one, you would divide your list of commits into two equal parts, you then look at each part and see which part contains the bug, you then continue on this process until you arrive at a single commit. The below image explains that!
Let's assume I have a website, and we released the second release yesterday. For example, a button on this website ran successfully in the first version 2 months ago, but it does not work now. And the history has about 300 commits, so how can I know the buggy commit quickly using git bisect?
1. start the git bisect session
2. mark a commit as bad "for example, the current one" if this version is broken
3. mark a commit as good, choose a commit that you know is working correctly and mark it as good
4. the git bisect will start to recommend commits "according to the binary search algorithm", and you should mark them as good or bad by compiling the checked-out version and testing it. Until you find the specific commit which makes the bug to fix it in your current release
5. exit from the git bisect tool and start to fix the bug.
The commands of these steps are below in the next two sections!
$ git bisect start
This starts the bisect process on our current commit which is "Head".
$ git bisect bad
The bug is present, so we need to designate it as a bad commit
or you can type:
$ git bisect bad <commit_id>
for example, the commit_id is 3acea60.
$ git bisect good <commit_id>
If this commit is working correctly.
$ git bisect reset
After a bisect session, clean up the bisection state and return to the original HEAD.
$ git bisect run
If you want to automate the bisect tool, you can use the above command and also read the official docs.
PS: I know how to use it manually, not automatically😅
If you need to examine the content of any file line by line, you need to use git blame. It helps you to determine who made the changes to a file.
$ git blame <your_file_name>
If you want to reset the current HEAD to a specified state or commit.
$ git reset --hard <commit_id>
To push these changes, you should force them by using:
$ git push -f
To show commit logs in detail or in an organized way.
$ git log
$ git log --oneline
$ git whatchanged
To restore a specific commit or switch to another branch
$ git checkout <commit_id>
$ git checkout <branch_name>
To see what's actually changed in a specific commit.
$ git show <commit_id>
It is a graphics alternative of
$ git citool
There are many commands in Git, and if you need more help with any command, you can use git help at any time from the terminal.
$ git help
$ git help <git_command>
I tried to tell you about this useful command "git bisect" and also some other important git commands to help you to reduce debugging time. If you know any other ways to make the debugging process faster, it would be great to share them with us :)