diff options
Diffstat (limited to 'git-bisect.sh')
-rwxr-xr-x | git-bisect.sh | 303 |
1 files changed, 157 insertions, 146 deletions
diff --git a/git-bisect.sh b/git-bisect.sh index b9c18dd207..e0ca3fb853 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -2,34 +2,33 @@ USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]' LONG_USAGE='git bisect help - print this long help message. + print this long help message. git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...] - reset bisect state and start bisection. + reset bisect state and start bisection. git bisect bad [<rev>] - mark <rev> a known-bad revision. + mark <rev> a known-bad revision. git bisect good [<rev>...] - mark <rev>... known-good revisions. + mark <rev>... known-good revisions. git bisect skip [(<rev>|<range>)...] - mark <rev>... untestable revisions. + mark <rev>... untestable revisions. git bisect next - find next bisection to test and check it out. + find next bisection to test and check it out. git bisect reset [<commit>] - finish bisection search and go back to commit. + finish bisection search and go back to commit. git bisect visualize - show bisect status in gitk. + show bisect status in gitk. git bisect replay <logfile> - replay bisection log. + replay bisection log. git bisect log - show bisect log. + show bisect log. git bisect run <cmd>... - use <cmd>... to automatically bisect. + use <cmd>... to automatically bisect. Please use "git help bisect" to get the full man page.' OPTIONS_SPEC= . git-sh-setup . git-sh-i18n -require_work_tree _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" @@ -55,7 +54,7 @@ bisect_autostart() { # TRANSLATORS: Make sure to include [Y] and [n] in your # translation. The program will only accept English input # at this point. - gettext "Do you want me to do it for you [Y/n]? " >&2 + gettext "Do you want me to do it for you [Y/n]? " >&2 read yesno case "$yesno" in [Nn]*) @@ -74,38 +73,43 @@ bisect_start() { # has_double_dash=0 for arg; do - case "$arg" in --) has_double_dash=1; break ;; esac + case "$arg" in --) has_double_dash=1; break ;; esac done orig_args=$(git rev-parse --sq-quote "$@") bad_seen=0 eval='' - mode='' + if test "z$(git rev-parse --is-bare-repository)" != zfalse + then + mode=--no-checkout + else + mode='' + fi while [ $# -gt 0 ]; do - arg="$1" - case "$arg" in - --) - shift - break + arg="$1" + case "$arg" in + --) + shift + break ;; - --no-checkout) - mode=--no-checkout - shift ;; - --*) - die "$(eval_gettext "unrecognised option: '\$arg'")" ;; - *) - rev=$(git rev-parse -q --verify "$arg^{commit}") || { - test $has_double_dash -eq 1 && - die "$(eval_gettext "'\$arg' does not appear to be a valid revision")" - break - } - case $bad_seen in - 0) state='bad' ; bad_seen=1 ;; - *) state='good' ;; + --no-checkout) + mode=--no-checkout + shift ;; + --*) + die "$(eval_gettext "unrecognised option: '\$arg'")" ;; + *) + rev=$(git rev-parse -q --verify "$arg^{commit}") || { + test $has_double_dash -eq 1 && + die "$(eval_gettext "'\$arg' does not appear to be a valid revision")" + break + } + case $bad_seen in + 0) state='bad' ; bad_seen=1 ;; + *) state='good' ;; + esac + eval="$eval bisect_write '$state' '$rev' 'nolog' &&" + shift + ;; esac - eval="$eval bisect_write '$state' '$rev' 'nolog' &&" - shift - ;; - esac done # @@ -125,7 +129,7 @@ bisect_start() { start_head=$(cat "$GIT_DIR/BISECT_START") if test "z$mode" != "z--no-checkout" then - git checkout "$start_head" -- + git checkout "$start_head" -- fi else # Get rev from where we start. @@ -198,7 +202,8 @@ is_expected_rev() { check_expected_revs() { for _rev in "$@"; do - if ! is_expected_rev "$_rev"; then + if ! is_expected_rev "$_rev" + then rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" rm -f "$GIT_DIR/BISECT_EXPECTED_REV" return @@ -207,18 +212,18 @@ check_expected_revs() { } bisect_skip() { - all='' + all='' for arg in "$@" do - case "$arg" in - *..*) - revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;; - *) - revs=$(git rev-parse --sq-quote "$arg") ;; - esac - all="$all $revs" - done - eval bisect_state 'skip' $all + case "$arg" in + *..*) + revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;; + *) + revs=$(git rev-parse --sq-quote "$arg") ;; + esac + all="$all $revs" + done + eval bisect_state 'skip' $all } bisect_state() { @@ -316,7 +321,7 @@ bisect_next() { git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout) res=$? - # Check if we should exit because bisection is finished + # Check if we should exit because bisection is finished test $res -eq 10 && exit 0 # Check for an error in the bisection process @@ -331,7 +336,8 @@ bisect_visualize() { if test $# = 0 then if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" && - type gitk >/dev/null 2>&1; then + type gitk >/dev/null 2>&1 + then set gitk else set git log @@ -355,20 +361,18 @@ bisect_reset() { case "$#" in 0) branch=$(cat "$GIT_DIR/BISECT_START") ;; 1) git rev-parse --quiet --verify "$1^{commit}" > /dev/null || { - invalid="$1" - die "$(eval_gettext "'\$invalid' is not a valid commit")" - } - branch="$1" ;; + invalid="$1" + die "$(eval_gettext "'\$invalid' is not a valid commit")" + } + branch="$1" ;; *) - usage ;; + usage ;; esac - if ! test -f "$GIT_DIR/BISECT_HEAD" + + if ! test -f "$GIT_DIR/BISECT_HEAD" && ! git checkout "$branch" -- then - if ! git checkout "$branch" -- - then - die "$(eval_gettext "Could not check out original HEAD '\$branch'. + die "$(eval_gettext "Could not check out original HEAD '\$branch'. Try 'git bisect reset <commit>'.")" - fi fi bisect_clean_state } @@ -400,7 +404,8 @@ bisect_replay () { while read git bisect command rev do test "$git $bisect" = "git bisect" -o "$git" = "git-bisect" || continue - if test "$git" = "git-bisect"; then + if test "$git" = "git-bisect" + then rev="$command" command="$bisect" fi @@ -418,65 +423,71 @@ bisect_replay () { } bisect_run () { - bisect_next_check fail - - while true - do - command="$@" - eval_gettext "running \$command"; echo - "$@" - res=$? - - # Check for really bad run error. - if [ $res -lt 0 -o $res -ge 128 ]; then - ( - eval_gettext "bisect run failed: + bisect_next_check fail + + while true + do + command="$@" + eval_gettext "running \$command"; echo + "$@" + res=$? + + # Check for really bad run error. + if [ $res -lt 0 -o $res -ge 128 ] + then + ( + eval_gettext "bisect run failed: exit code \$res from '\$command' is < 0 or >= 128" && - echo - ) >&2 - exit $res - fi - - # Find current state depending on run success or failure. - # A special exit code of 125 means cannot test. - if [ $res -eq 125 ]; then - state='skip' - elif [ $res -gt 0 ]; then - state='bad' - else - state='good' - fi - - # We have to use a subshell because "bisect_state" can exit. - ( bisect_state $state > "$GIT_DIR/BISECT_RUN" ) - res=$? - - cat "$GIT_DIR/BISECT_RUN" - - if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ - > /dev/null; then - ( - gettext "bisect run cannot continue any more" && - echo - ) >&2 - exit $res - fi - - if [ $res -ne 0 ]; then - ( - eval_gettext "bisect run failed: + echo + ) >&2 + exit $res + fi + + # Find current state depending on run success or failure. + # A special exit code of 125 means cannot test. + if [ $res -eq 125 ] + then + state='skip' + elif [ $res -gt 0 ] + then + state='bad' + else + state='good' + fi + + # We have to use a subshell because "bisect_state" can exit. + ( bisect_state $state > "$GIT_DIR/BISECT_RUN" ) + res=$? + + cat "$GIT_DIR/BISECT_RUN" + + if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ + > /dev/null + then + ( + gettext "bisect run cannot continue any more" && + echo + ) >&2 + exit $res + fi + + if [ $res -ne 0 ] + then + ( + eval_gettext "bisect run failed: 'bisect_state \$state' exited with error code \$res" && - echo - ) >&2 - exit $res - fi + echo + ) >&2 + exit $res + fi - if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then - gettext "bisect run success"; echo - exit 0; - fi + if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null + then + gettext "bisect run success"; echo + exit 0; + fi - done + done } bisect_log () { @@ -486,33 +497,33 @@ bisect_log () { case "$#" in 0) - usage ;; + usage ;; *) - cmd="$1" - shift - case "$cmd" in - help) - git bisect -h ;; - start) - bisect_start "$@" ;; - bad|good) - bisect_state "$cmd" "$@" ;; - skip) - bisect_skip "$@" ;; - next) - # Not sure we want "next" at the UI level anymore. - bisect_next "$@" ;; - visualize|view) - bisect_visualize "$@" ;; - reset) - bisect_reset "$@" ;; - replay) - bisect_replay "$@" ;; - log) - bisect_log ;; - run) - bisect_run "$@" ;; - *) - usage ;; - esac + cmd="$1" + shift + case "$cmd" in + help) + git bisect -h ;; + start) + bisect_start "$@" ;; + bad|good) + bisect_state "$cmd" "$@" ;; + skip) + bisect_skip "$@" ;; + next) + # Not sure we want "next" at the UI level anymore. + bisect_next "$@" ;; + visualize|view) + bisect_visualize "$@" ;; + reset) + bisect_reset "$@" ;; + replay) + bisect_replay "$@" ;; + log) + bisect_log ;; + run) + bisect_run "$@" ;; + *) + usage ;; + esac esac |