How to `git bisect` only on one branch's commits? How to `git bisect` only on one branch's commits? git git

How to `git bisect` only on one branch's commits?


There is no easy way to accomplish this without further work. After playing with it for a little while I have something that might help you.

git bisect start master f9d5924for rev in $(git rev-list f9d5924..master --merges --first-parent); do  git rev-list $rev^2 --not $rev^done | xargs git bisect skip

This starts git bisect with f9d5924 as your good commit and master as your bad commit. Then it finds the ancestors of the right side of each merge commit that are not on the left side. It passes those ancestors to git bisect skip to skip them. However when it figures out which commit is bad it will show all possible skipped commits from the bad merge commit. like the following

$ git bisect goodThere are only 'skip'ped commits left to test.The first bad commit could be any of:0622204625d8817c5d8fd1a2a68b3aa91f2dcdf90c771566b9e77e3bdc0a66a7404c8eae9f321a685098b44f43f84b213eaab110073a6acd26a5cc028b05a808d5e15852fbddaa529ba241fdac8ff693b0c755c3fa57e3c8d527e76fae38bc9925c01353We cannot bisect more!

In this case b0c755c3fa57e3c8d527e76fae38bc9925c01353 was the merge commit it failed on.

Note: This will not work if you have an octopus merge (a merge that merges more than two branches together).


I too would like a proper and native-to-git solution to this question, only checking commits on a single branch and thus "blaming" an entire merge and/or Pull Request. However:

since the master branch's commits are the only (supposedly) stable ones, I want to git bisect only on that branch.

If the issue prompting this question is that some of the commits you're being given are broken and you cannot test, you can use:

git bisect skip

To skip that commit entirely and check a different one. This will solve the problem you're having with broken commits. Once you find the commit that broke the feature, you can follow it to the merge into the branch you're tracking.

I suppose you could even git bisect skip ALL commits that are not merges, either by manually checking or via a script. That would give the behavior asked in the question.


I think git bisect with a --no-parent flag could do this easily, but it doesn't exist.

The only thing I can think of involves recreating just the branch commits in a new branch. Here's an example in the Linux shell:

$ git branch bisecttemp <first>$ for h in `git log --oneline --decorate --first-parent --reverse --format=%H <first>..<last>`; do git checkout -f $h; sleep .5; git reset bisecttemp; git commit -am"$h"; git checkout testing; git reset --hard HEAD@{1}; done

That makes a bisecttemp branch off the <first> commit we care about, gets a list of just the hashes between the <first> and <last> commits in the range we care about, visits each, resets back to the bisecttemp branch after each, without changing the working tree, commits everything different with the hash of the commit it came from, checks out bisecttemp again, and then resets it back to the last place head was, which is the new commit.

There may be a smarter way to do all of this, but the basics are that it creates a new branch off the start of the range of commits we care about, then commits the state of the branch-only commits (regular commits and merges, but not any sub-branch commits) to it, in order. You can't just cherry-pick here, as cherry-picks look at parents, and that would fail on the merge commits.

This isn't really tested, and could all be wrong. It's just a thought. It could all be rolled up in a function that takes a range of commits.