gitgit-bisect

Keeping git bisect on the ancestry path


I have a repository with a complicated tree of branches and merges, and I want to use git bisect to find when a bug was introduced.

I have a good commit and bad commit to start the bisect, where the good commit is an ancestor of the bad one.

I'd expect git bisect to go to commits which have the good commit as an ancestor, but it doesn't (using git 2.21.0).

Currently I'm doing the bisect manually by keeping a list of commits and using git rev-list --ancestry-path GOOD..BAD and picking a commit in the middle. Is there a way to automate this with git bisect? Does it have a flag to stay in the ancestry path?

Reasoning for bisecting in the ancestry path first

The features relating to the bug one is searching may not exist in all branches, making the check irrelevant there. They should exist in the ancestry path though.

Once bisecting the ancestry path is done, one would probably get a merge commit as the blame, and they would know the bug originates from that branch. This already teaches one a lot about the bug.

To continue bisecting over the branch which introduced the bug, one needs to test not each commit on its own (as they don't necessarily have the features needed for the bug to surface), but one should merge each one with the last good commit and then check if the bug exists. Then one can pinpoint a specific commit, that when merged with the good commit, introduces the bug.

Note that I've done this process several times and it was very useful to me, and I'm merely looking for methods to make it more convinient.


Solution

  • git bisect doesn't have an option to follow the ancestry path. Such an option isn't generally useful for several reasons:

    Unless you have specific knowledge about your repository such that commits not on the ancestry path will produce false positives or false negatives, it's usually fine to just let git rebase do its thing. Since its behavior is O(log N), the additional costs tend to be negligible. You can, however, use git bisect skip RANGE to specify a range to skip if need be.

    If you can automate the testing of your branch with a shell script or command, you can use git bisect run with that shell script. It should exit 0 if the commit is good, 125 if the commit should be skipped, and any other code between 1 and 127 inclusive if the commit is bad. This can be used to avoid checking commits that are not suitable for whatever reason.