Merge branch 'js/wincred-empty-cred'
[gitweb.git] / git-bisect.sh
index ea63223ab3b5d4f8fb0a9af45db4278aef010fb7..0138a8860e3779cf62210d8d54d2eada020be12f 100755 (executable)
@@ -1,14 +1,19 @@
 #!/bin/sh
 
-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'
 LONG_USAGE='git bisect help
        print this long help message.
-git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
+git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
+                [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
        reset bisect state and start bisection.
-git bisect bad [<rev>]
-       mark <rev> a known-bad revision.
-git bisect good [<rev>...]
-       mark <rev>... known-good revisions.
+git bisect (bad|new) [<rev>]
+       mark <rev> a known-bad revision/
+               a revision after change in a given property.
+git bisect (good|old) [<rev>...]
+       mark <rev>... known-good revisions/
+               revisions before change in a given property.
+git bisect terms [--term-good | --term-bad]
+       show the terms used for old and new commits (default: bad, good)
 git bisect skip [(<rev>|<range>)...]
        mark <rev>... untestable revisions.
 git bisect next
@@ -28,7 +33,6 @@ Please use "git help bisect" to get the full man page.'
 
 OPTIONS_SPEC=
 . git-sh-setup
-. git-sh-i18n
 
 _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"
@@ -95,6 +99,24 @@ bisect_start() {
                --no-checkout)
                        mode=--no-checkout
                        shift ;;
+               --term-good|--term-old)
+                       shift
+                       must_write_terms=1
+                       TERM_GOOD=$1
+                       shift ;;
+               --term-good=*|--term-old=*)
+                       must_write_terms=1
+                       TERM_GOOD=${1#*=}
+                       shift ;;
+               --term-bad|--term-new)
+                       shift
+                       must_write_terms=1
+                       TERM_BAD=$1
+                       shift ;;
+               --term-bad=*|--term-new=*)
+                       must_write_terms=1
+                       TERM_BAD=${1#*=}
+                       shift ;;
                --*)
                        die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
                *)
@@ -164,7 +186,7 @@ bisect_start() {
        #
        # Get rid of any old bisect state.
        #
-       bisect_clean_state || exit
+       git bisect--helper --bisect-clean-state || exit
 
        #
        # Change state.
@@ -173,7 +195,7 @@ bisect_start() {
        # We have to trap this to be able to clean up using
        # "bisect_clean_state".
        #
-       trap 'bisect_clean_state' 0
+       trap 'git bisect--helper --bisect-clean-state' 0
        trap 'exit 255' 1 2 3 15
 
        #
@@ -187,7 +209,7 @@ bisect_start() {
        eval "$eval true" &&
        if test $must_write_terms -eq 1
        then
-               write_terms "$TERM_BAD" "$TERM_GOOD"
+               git bisect--helper --write-terms "$TERM_BAD" "$TERM_GOOD" || exit
        fi &&
        echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
        #
@@ -215,22 +237,6 @@ bisect_write() {
        test -n "$nolog" || echo "git bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
 }
 
-is_expected_rev() {
-       test -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
-       test "$1" = $(cat "$GIT_DIR/BISECT_EXPECTED_REV")
-}
-
-check_expected_revs() {
-       for _rev in "$@"; do
-               if ! is_expected_rev "$_rev"
-               then
-                       rm -f "$GIT_DIR/BISECT_ANCESTORS_OK"
-                       rm -f "$GIT_DIR/BISECT_EXPECTED_REV"
-                       return
-               fi
-       done
-}
-
 bisect_skip() {
        all=''
        for arg in "$@"
@@ -252,12 +258,13 @@ bisect_state() {
        check_and_set_terms $state
        case "$#,$state" in
        0,*)
-               die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
+               die "Please call 'bisect_state' with at least one argument." ;;
        1,"$TERM_BAD"|1,"$TERM_GOOD"|1,skip)
-               rev=$(git rev-parse --verify $(bisect_head)) ||
-                       die "$(gettext "Bad rev input: $(bisect_head)")"
+               bisected_head=$(bisect_head)
+               rev=$(git rev-parse --verify "$bisected_head") ||
+                       die "$(eval_gettext "Bad rev input: \$bisected_head")"
                bisect_write "$state" "$rev"
-               check_expected_revs "$rev" ;;
+               git bisect--helper --check-expected-revs "$rev" ;;
        2,"$TERM_BAD"|*,"$TERM_GOOD"|*,skip)
                shift
                hash_list=''
@@ -271,7 +278,7 @@ bisect_state() {
                do
                        bisect_write "$state" "$rev"
                done
-               check_expected_revs $hash_list ;;
+               git bisect--helper --check-expected-revs $hash_list ;;
        *,"$TERM_BAD")
                die "$(eval_gettext "'git bisect \$TERM_BAD' can take only one argument.")" ;;
        *)
@@ -294,7 +301,7 @@ bisect_next_check() {
                false
                ;;
        t,,"$TERM_GOOD")
-               # have bad but not good.  we could bisect although
+               # have bad (or new) but not good (or old).  we could bisect although
                # this is less optimum.
                eval_gettextln "Warning: bisecting only with a \$TERM_BAD commit." >&2
                if test -t 0
@@ -407,27 +414,7 @@ bisect_reset() {
                die "$(eval_gettext "Could not check out original HEAD '\$branch'.
 Try 'git bisect reset <commit>'.")"
        fi
-       bisect_clean_state
-}
-
-bisect_clean_state() {
-       # There may be some refs packed during bisection.
-       git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* |
-       while read ref hash
-       do
-               git update-ref -d $ref $hash || exit
-       done
-       rm -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
-       rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" &&
-       rm -f "$GIT_DIR/BISECT_LOG" &&
-       rm -f "$GIT_DIR/BISECT_NAMES" &&
-       rm -f "$GIT_DIR/BISECT_RUN" &&
-       rm -f "$GIT_DIR/BISECT_TERMS" &&
-       # Cleanup head-name if it got left by an old version of git-bisect
-       rm -f "$GIT_DIR/head-name" &&
-       git update-ref -d --no-deref BISECT_HEAD &&
-       # clean up BISECT_START last
-       rm -f "$GIT_DIR/BISECT_START"
+       git bisect--helper --bisect-clean-state || exit
 }
 
 bisect_replay () {
@@ -451,6 +438,8 @@ bisect_replay () {
                        eval "$cmd" ;;
                "$TERM_GOOD"|"$TERM_BAD"|skip)
                        bisect_write "$command" "$rev" ;;
+               terms)
+                       bisect_terms $rev ;;
                *)
                        die "$(gettext "?? what are you talking about?")" ;;
                esac
@@ -532,12 +521,6 @@ get_terms () {
        fi
 }
 
-write_terms () {
-       TERM_BAD=$1
-       TERM_GOOD=$2
-       printf '%s\n%s\n' "$TERM_BAD" "$TERM_GOOD" >"$GIT_DIR/BISECT_TERMS"
-}
-
 check_and_set_terms () {
        cmd="$1"
        case "$cmd" in
@@ -551,7 +534,17 @@ check_and_set_terms () {
                bad|good)
                        if ! test -s "$GIT_DIR/BISECT_TERMS"
                        then
-                               write_terms bad good
+                               TERM_BAD=bad
+                               TERM_GOOD=good
+                               git bisect--helper --write-terms "$TERM_BAD" "$TERM_GOOD" || exit
+                       fi
+                       ;;
+               new|old)
+                       if ! test -s "$GIT_DIR/BISECT_TERMS"
+                       then
+                               TERM_BAD=new
+                               TERM_GOOD=old
+                               git bisect--helper --write-terms "$TERM_BAD" "$TERM_GOOD" || exit
                        fi
                        ;;
                esac ;;
@@ -560,8 +553,39 @@ check_and_set_terms () {
 
 bisect_voc () {
        case "$1" in
-       bad) echo "bad" ;;
-       good) echo "good" ;;
+       bad) echo "bad|new" ;;
+       good) echo "good|old" ;;
+       esac
+}
+
+bisect_terms () {
+       get_terms
+       if ! test -s "$GIT_DIR/BISECT_TERMS"
+       then
+               die "$(gettext "no terms defined")"
+       fi
+       case "$#" in
+       0)
+               gettextln "Your current terms are $TERM_GOOD for the old state
+and $TERM_BAD for the new state."
+               ;;
+       1)
+               arg=$1
+               case "$arg" in
+                       --term-good|--term-old)
+                               printf '%s\n' "$TERM_GOOD"
+                               ;;
+                       --term-bad|--term-new)
+                               printf '%s\n' "$TERM_BAD"
+                               ;;
+                       *)
+                               die "$(eval_gettext "invalid argument \$arg for 'git bisect terms'.
+Supported options are: --term-good|--term-old and --term-bad|--term-new.")"
+                               ;;
+               esac
+               ;;
+       *)
+               usage ;;
        esac
 }
 
@@ -577,7 +601,7 @@ case "$#" in
                git bisect -h ;;
        start)
                bisect_start "$@" ;;
-       bad|good|"$TERM_BAD"|"$TERM_GOOD")
+       bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
                bisect_state "$cmd" "$@" ;;
        skip)
                bisect_skip "$@" ;;
@@ -594,6 +618,8 @@ case "$#" in
                bisect_log ;;
        run)
                bisect_run "$@" ;;
+       terms)
+               bisect_terms "$@" ;;
        *)
                usage ;;
        esac