How to use `git bisect`

When Doom Emacs (or your sleepness nights tinkering at your config) cause Emacs to misbehave, you may not know where to start looking. This is where git bisect comes in; this powerful tool will walk you through your git history and help you isolate the commit where the problem was introduced. This guide will walk you through understanding and using git bisect.

The Timeline

Let’s establish a hypothetical timeline: 20 commits ago doom or a personal config was working just fine. Now in the latest HEAD, it’s broken.

1-timeline

It’s important to know the commit sha (at least the first 7 chars) of the last known working commit and the current broken commit. Use git log to get commit id shas.

Start Bisecting

git bisect start <broken-commit-or-tag> <working-commit-or-tag>

2-start

Git bisect starts by checking out a commit between the start and end commits specified, in this case the 10th commit.

Testing

Now it’s time to test. If doom or a personal config is working correctly you can mark it as good with:

git bisect good

If it is still not working, mark it as bad:

git bisect bad

Narrowing Down Commits

Marking a commit as good or bad will then checkout a commit between most recently working commit and the known bad commit.

3-branches

After testing, if the previous commit was marked as good, that means the 10th commit was working but the 20th commit is broken so git bisect will check out the 15th commit to test.

If after the previous commit was marked as good, that means the 10th commit was broken too but the 1st, and oldest commit was good so git bisect will check out the 5th commit to test.

Now test for the breaking bug again. If it works mark it as good with git bisect good and if it’s still broken use git bisect bad. Keep repeating this process to narrow down to the last possible commit. The last commit is the likely culprit that introduced the breaking change, which can then be used to revert or patch the bug.

Git bisect uses a binary search algorithm to quickly narrow down all possible commits until the culprit commit is discovered. It picks the halfway commit between the last known working and broken commits and keeps halving commits down to the last, culprit commit.

Exiting Bisect Mode

To stop git bisect use the following:

git bisect reset

This reverts back to the previous commit before calling git bisect start.

Bisecting Emacs Doom or Package Config

If tracking down a breaking change for doom itself, or packages change in a personal config, the process is mostly the same except that the following command needs to run before testing each commit:

doom sync -u

This installs the specified version of each package otherwise you may get inaccurate results when testing because doom is using the package versions from the last update.

11 Likes