Skip to content, Skip to search


Pinpoint regressions with Git

274 bytes added, 10:43, 22 March 2017
no edit summary
= How to bisect with Git =
== How to find which commit introduced a regression ==
So you found a regression? I.e. you know that the version worked perfectly that you had yesterday of, say, the Fiji launcher[[ImageJ Ops]] library, but today it crashes?
Git-bisect to the rescue!
<presource lang="bash">~/fiji$ git bisect start~/fiji$ git bisect bad HEAD~/fiji$ git bisect good HEAD@{yesterday}</presource>
This will start the bisection process, i.e. it will try to find a revision that is as much "in the middle" between the bad commit(s) and the good commit(s) (you will mark more and more commits as good or bad in the process, and by inference, the ancestors of good commits will be considered good, and the offspring of bad commits will be considered bad, too), and let you test that.
In our case, let's just test run the Fiji launcherunit tests:
<presource lang="bash">~/fiji$ ./ fiji && ./fijimvn clean test</presource>
If the test is undecided (for example, e.g.: it does not compile at all, so you do not know if the unit test in question passes), mark it with
<presource lang="bash">~/fiji$ git bisect skip</presource>
otherwise, mark it as "bad" or "good".
Sooner or later (usually rather sooner), Git will tell you which commit is the culprit. You can look at the corresponding patch with
<presource lang="bash">~/fiji$ git show <commit name></presource>
where the commit name is that 40-digit hex string Git told you was the first bad commit. Usually you end the bisection process then and there:
<presource lang="bash">~/fiji$ git bisect reset</presource>
This will bring you back to the revision and branch you were on before starting the bisection.
If there is an obvious flaw in the patch, just try to patch it. You have to move to the first bad revision first:
<presource lang="bash">~/fiji$ git checkout <commit name></presource>
(This will warn you that you are not on any branch, but that is okay.) Then just apply the fix you have in mind, and commit (after making sure that it worked, of course ;-). Now, tag it with a temporary label:
<presource lang="bash">~/fiji$ git tag my-fix</presource>
and go back to the branch you came from:
<presource lang="bash">~/fiji$ git checkout master</presource>
If you are unsure which branch you came from, look at the [[Git_reflogs|reflog]] first.
Now you can cherry-pick (or forward-port) your patch:
<presource lang="bash">~/fiji$ git cherry-pick my-fix</presource>
If there are conflicts, resolve them and commit ("git commit fiji.cxx").
After that, you can get rid of the now-obsolete tag:
<presource lang="bash">~/fiji$ git tag -d my-fix</presource>
Note: instead of using a temporary tag, you can use the [[Git_reflogs|reflog]] of the HEAD ref ("<code>git cherry-pick HEAD@{1}"</code>), but if you are not familiar with the concept, tags are probably easier to handle. = See also = * [ Binary search tutorial] in the Git book
Bureaucrat, emailconfirmed, incoming, administrator, uploaders