2

I have a git repo with a combination of commits and merges containing multiple commits. I am trying to use git bisect to determine where a bug was introduced, but when the resulting commit points to a merge commit with a dozen different commits, this is not as helpful.

Is there a way to retroactively flatten a merge commit into its individual commits? Or is there some other method of performing a git bisect that will allow you to continue into the individual commits of a merge commit?

1 Answers1

1

Yes. The key factor here is to recognize that when using git-bisect to track down a bug you do not necessarily have to run along the original branch, you can also create a copy branch that you slightly modify.

The modifications I think of are things like for instance

  • Temporary add some more files to .gitignore as the first commit in the bisect branch to make git status output clean.
  • Fix commits that does not compile for trivial things like missing include statements etc.
  • Disable unit test for parts of the system that are not affected by the bug you are trying to find (this can be a huge time saver).
  • Split a large commit into multiple commits.
  • Etc

Now of course any change might mask/fix errors/add new errors, but if you keep the changes small/unrelated to what you are suspecting this should normally be fine. In worst case this will not work, but most likely it can identify the problem in a commit on the copy branch which you then need to correlate with the same commit on the original branch.


Now for the case you describe I assume the you have something like the following

gitk screenshot, start

and you want to bisect between main and Test-A. To flatten merge commit you can use interactive rebase which by default flattens the history1. So with

git branch Test-A.bisect Test-A
git checkout Test-A.bisect
git rebase --interactive main       # Just saving and exiting the editor here.
git diff Test-A.bisect Test-A  # Verify that there are no unexpected differences.

then you end up with a Test-A.bisect branch without merges, which you then can run bisect on (with the caveat that it is not exactly the same as the original branch, but this very seldomly is a significant problem).

gitk screenshot, end


1 You need to specify --rebase-merges for it to keep merge commits. I do include it by default in my ri alias for interactive rebase.

hlovdal
  • 26,565
  • 10
  • 94
  • 165