• Automatically bisect a broken build between v1.2 and HEAD:
$ git bisect start HEAD v1.2 -- # HEAD is bad, v1.2 is good
$ git bisect run make # "make" builds the app
$ git bisect reset # quit the bisect session
• Automatically bisect a test failure between origin and HEAD:
$ git bisect start HEAD origin -- # HEAD is bad, origin is good
$ git bisect run make test # "make test" builds and tests
$ git bisect reset # quit the bisect session
• Automatically bisect a broken test case:
$ cat ~/test.sh
#!/bin/sh
make || exit 125 # this skips broken builds
~/check_test_case.sh # does the test case pass?
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
$ git bisect run ~/test.sh
$ git bisect reset # quit the bisect session
Here we use a test.sh
custom script. In this script, if make
fails, we skip the current commit. check_test_case.sh
should
exit 0
if the test case passes, and exit 1
otherwise.
It is safer if both test.sh
and check_test_case.sh
are
outside the repository to prevent interactions between the
bisect, make and test processes and the scripts.
• Automatically bisect with temporary modifications (hot-fix):
$ cat ~/test.sh
#!/bin/sh
# tweak the working tree by merging the hot-fix branch
# and then attempt a build
if git merge --no-commit --no-ff hot-fix &&
make
then
# run project specific test and report its status
~/check_test_case.sh
status=$?
else
# tell the caller this is untestable
status=125
fi
# undo the tweak to allow clean flipping to the next commit
git reset --hard
# return control
exit $status
This applies modifications from a hot-fix branch before each
test run, e.g. in case your build or test environment changed
so that older revisions may need a fix which newer ones have
already. (Make sure the hot-fix branch is based off a commit
which is contained in all revisions which you are bisecting,
so that the merge does not pull in too much, or use git
cherry-pick
instead of git merge
.)
• Automatically bisect a broken test case:
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
$ git bisect run sh -c "make || exit 125; ~/check_test_case.sh"
$ git bisect reset # quit the bisect session
This shows that you can do without a run script if you write
the test on a single line.
• Locate a good region of the object graph in a damaged
repository
$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout
$ git bisect run sh -c '
GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) &&
git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ &&
git pack-objects --stdout >/dev/null <tmp.$$
rc=$?
rm -f tmp.$$
test $rc = 0'
$ git bisect reset # quit the bisect session
In this case, when git bisect run finishes, bisect/bad will
refer to a commit that has at least one parent whose
reachable graph is fully traversable in the sense required by
git pack objects.
• Look for a fix instead of a regression in the code
$ git bisect start
$ git bisect new HEAD # current commit is marked as new
$ git bisect old HEAD~10 # the tenth commit from now is marked as old
or:
$ git bisect start --term-old broken --term-new fixed
$ git bisect fixed
$ git bisect broken HEAD~10
Getting help
Use git bisect
to get a short usage description, and git bisect
help
or git bisect -h
to get a long usage description.