|
|
# Bisection to find bad commits
|
|
|
|
|
|
|
|
|
Say you have a program `TestCase.hs` in which a rewrite rule stopped firing at some point between GHC 7.10.1 and 7.10. It can often be useful to know which commit introduced the regression. [ Bisection](https://en.wikipedia.org/wiki/Bisection_%28software_engineering%29) is an efficient way of determining this, requiring at most `log_2(N)` commits to find the culprit among `N` commits.
|
|
|
Say you have a program `TestCase.hs` in which a rewrite rule stopped firing at some point between GHC 7.10.1 and 7.10. It can often be useful to know which commit introduced the regression. [Bisection](https://en.wikipedia.org/wiki/Bisection_%28software_engineering%29) is an efficient way of determining this, requiring at most `log_2(N)` commits to find the culprit among `N` commits.
|
|
|
|
|
|
|
|
|
This approach is especially appealing as git provides convenient support in the form of [ \`git bisect\`](https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html). `git bisect` coupled with a reliable test case and the script below (with appropriate modifications) turns the task of bisection into a relatively painless exercise.
|
|
|
This approach is especially appealing as git provides convenient support in the form of [\`git bisect\`](https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html). `git bisect` coupled with a reliable test case and the script below (with appropriate modifications) turns the task of bisection into a relatively painless exercise.
|
|
|
|
|
|
**Note:** Bisecting revisions before the switch to submodules (i.e. more than a couple of months prior to the GHC 7.10.1 release) is quite difficult and is generally not worth the effort. The script below probably won't work in this regime.
|
|
|
|
... | ... | @@ -39,7 +39,7 @@ function skip_commit(){exit125;}function commit_good(){exit0;}function commit_ba |
|
|
log "Commit $rev: $step = $ret"return$ret}function build_ghc(){
|
|
|
do_it submodules git submodule update || skip_commit
|
|
|
# We run `make` twice as sometimes it will spuriously fail with -j
|
|
|
if[ -z "$ALWAYS_CLEAN" -o "x$ALWAYS_CLEAN"=="x0"];then# First try building without cleaning, if that fails then clean and try again
|
|
|
if[-z "$ALWAYS_CLEAN" -o "x$ALWAYS_CLEAN"=="x0"];then# First try building without cleaning, if that fails then clean and try again
|
|
|
do_it ghc1 make $make_opts||\
|
|
|
do_it ghc2 make $make_opts||\
|
|
|
do_it clean make clean &&\
|
... | ... | @@ -65,7 +65,7 @@ if["x$?"="x124"];then |
|
|
else
|
|
|
log "Commit $rev: passed"
|
|
|
commit_good
|
|
|
fi}if[ -z "$@"];then
|
|
|
fi}if[-z "$@"];then
|
|
|
build_ghc
|
|
|
run_test
|
|
|
else$@fi
|
... | ... | |