Find the commit that introduced a bug

Often times in project, something that was working fine breaks later. Mostly it is because of some commit that was made after when the project was working good.

Suppose for an android app, I got the task to make some design changes to a simple screen. After the task is done and few commits later, it looked like:

Here everything was fine except for the position of the round button which has moved to left-top of the screen.

Git log looks like this:

It was all good before I started to make change, i.e till commit A3- 86c07ee but during the test at commit A8- c20a76e I realized it is broken. In between the commits [A3...A8] break may have been introduced, after which all its following commits will have this issue. Lets call all the ones where the bug exists bad and others good.

Next thing anyone does, is to find the commit that caused the bug, i.e first bad commit. Generally what one does is, go back to every commit until working version is found i.e last good commit, or go to last known commit where project was working fine and checkout forward to find the broken version i.e first bad commit.

If the project is small, with one or couple of people working on it and there are few commits in between that route can work. But for large codebase or where the commits are frequent it can be not so fun task.

Here comes the use of git bisect

git-bisect — Use binary search to find the commit that introduced a bug

It is simple with following steps:

Start git bisect mode Let git know which of the last known commit is good, i.e A3- 86c07ee Let git know which of the commit you know is bad, i.e A8- c20a76e Start bisecting

git bisect start

git bisect good 86c07ee

git bisect bad c20a76e

Git checks out to some commit in between with message:

Bisecting: 2 revisions left to test after this (roughly 1 step)

[48ff1b19942da6e3e160c1a46de9cb5eb0183c8d] Changed color of floating button

Simple rule after the git bisect starts to search commits; Test the version and,

Use command git bisect bad if the commit has issue Use command git bisect good if the issue is gone Continue until the first bad commit is found

i.e, In our case Git checked out at commit 48ff1b19942da6e3e160c1a46de9cb5eb0183c8d which is A5- f8ff1b1 where I have changed the color of the round button from red to blue. When I built on this version and made a test on my phone issue was still there.

So I continued with command git bisect bad and the result message was:

Bisecting: 0 revisions left to test after this (roughly 0 steps)

[d95fc76105ccac011463e87fcdbb06dfaec3a308] Changed title

Git checked out at A4- d95fc76 , after the test there was no issue on this version, so I continued with command git bisect good and got the message



commit xxx

Author: Subhash Acharya <

Date: xxx 48ff1b19942da6e3e160c1a46de9cb5eb0183c8d is the first bad commitcommit xxxAuthor: Subhash Acharya < subhash@xyz.com Date: xxx Changed color of floating button

Finally, the culprit commit is found which turned out to be A5- 48ff1b1

Checking out to this commit,

git checkout 48ff1b1 and executing diff with A4, i.e

git diff d95fc76 ,

There was the change in line which affected the position of the button.

Now after the issue is identified move forward with git bisect reset which resets the bisect mode and checks out to head where git bisect was started.

Now, fix it and enjoy.

Why use git bisect?

You can for sure manually do these checkouts to previous version and test until the first bad commit is identified. Bisect simply helps by doing binary search on commits and makes the process much easier specially with large number of commits.

More?

You can automate the process using script, that runs test on each commit and can return non zero value when it fails.

Reads: