Code

Bisect visualize: use "for-each-ref" to list all good refs.
[git.git] / git-bisect.sh
index 180c6c280c8dd2e9622dff26399a6b91540d54fd..2b20037a11687d4d867038d5544c81d709fce8ac 100755 (executable)
@@ -1,12 +1,14 @@
 #!/bin/sh
 
-USAGE='[start|bad|good|next|reset|visualize|replay|log|run]'
+USAGE='[start|bad|good|skip|next|reset|visualize|replay|log|run]'
 LONG_USAGE='git bisect start [<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 skip [<rev>...]
+        mark <rev>... untestable revisions.
 git bisect next
         find next bisection to test and check it out.
 git bisect reset [<branch>]
@@ -17,8 +19,6 @@ git bisect replay <logfile>
         replay bisection log.
 git bisect log
         show bisect log.
-git bisect skip [<rev>...]
-        mark <rev>... untestable revisions.
 git bisect run <cmd>...
         use <cmd>... to automatically bisect.'
 
@@ -71,7 +71,7 @@ bisect_start() {
                ;;
        refs/heads/*)
                [ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
-               echo "$head" | sed 's#^refs/heads/##' >"$GIT_DIR/head-name"
+               echo "${head#refs/heads/}" >"$GIT_DIR/head-name"
                ;;
        *)
                die "Bad HEAD - strange symbolic ref"
@@ -130,7 +130,7 @@ bisect_write() {
                good|skip)      tag="$state"-"$rev" ;;
                *)              die "Bad bisect_write argument: $state" ;;
        esac
-       echo "$rev" >"$GIT_DIR/refs/bisect/$tag"
+       git update-ref "refs/bisect/$tag" "$rev"
        echo "# $state: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG"
        test -z "$nolog" && echo "git-bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
 }
@@ -275,7 +275,7 @@ exit_if_skipped_commits () {
        if expr "$_tried" : ".*[|].*" > /dev/null ; then
                echo "There are only 'skip'ped commit left to test."
                echo "The first bad commit could be any of:"
-               echo "$_tried" | sed -e 's/[|]/\n/g'
+               echo "$_tried" | tr '[|]' '[\012]'
                echo "We cannot bisect more!"
                exit 2
        fi
@@ -316,17 +316,16 @@ bisect_next() {
        exit_if_skipped_commits "$bisect_rev"
 
        echo "Bisecting: $bisect_nr revisions left to test after this"
-       echo "$bisect_rev" >"$GIT_DIR/refs/heads/new-bisect"
+       git branch -f new-bisect "$bisect_rev"
        git checkout -q new-bisect || exit
-       mv "$GIT_DIR/refs/heads/new-bisect" "$GIT_DIR/refs/heads/bisect" &&
-       GIT_DIR="$GIT_DIR" git symbolic-ref HEAD refs/heads/bisect
+       git branch -M new-bisect bisect
        git show-branch "$bisect_rev"
 }
 
 bisect_visualize() {
        bisect_next_check fail
-       not=`cd "$GIT_DIR/refs" && echo bisect/good-*`
-       eval gitk bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES")
+       not=$(git for-each-ref --format='%(refname)' "refs/bisect/good-*")
+       eval gitk refs/bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES")
 }
 
 bisect_reset() {
@@ -350,7 +349,13 @@ bisect_reset() {
 
 bisect_clean_state() {
        rm -fr "$GIT_DIR/refs/bisect"
-       rm -f "$GIT_DIR/refs/heads/bisect"
+
+       # There may be some refs packed during bisection.
+       git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* refs/heads/bisect |
+       while read ref hash
+       do
+               git update-ref -d $ref $hash
+       done
        rm -f "$GIT_DIR/BISECT_LOG"
        rm -f "$GIT_DIR/BISECT_NAMES"
        rm -f "$GIT_DIR/BISECT_RUN"