Code

bisect: fix quoting TRIED revs when "bad" commit is also "skip"ped
authorChristian Couder <chriscool@tuxfamily.org>
Fri, 27 Feb 2009 06:31:22 +0000 (07:31 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 27 Feb 2009 08:57:28 +0000 (00:57 -0800)
When the "bad" commit was also "skip"ped and when more than one
commit was skipped, the "filter_skipped" function would have
printed something like:

    bisect_rev=<hash1>|<hash2>

(where <hash1> and <hash2> are hexadecimal sha1 hashes)

and this would have been evaled later as piping "bisect_rev=<hash1>"
into "<hash2>", which would have failed.

So this patch makes the "filter_skipped" function properly quote
what it outputs, so that it will print something like:

bisect_rev='<hash1>|<hash2>'

which will be properly evaled later.  The caller was not stopping
properly because the scriptlet this function returned to be evaled
was not strung together with && and because of this, an error in
an earlier part of the output was simply ignored.

A test case is added to the test suite.

And while at it, we also initialize the VARS, FOUND and TRIED
variables, so that we protect ourselves from environment variables
the user may have with these names.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-bisect.sh
t/t6030-bisect-porcelain.sh

index 97ac600873ebd0dff6310071343403a41a867b8a..f9a5c0bdf4382c09a978ce42b013c507c0fb1e0c 100755 (executable)
@@ -269,56 +269,62 @@ filter_skipped() {
 
        # Let's parse the output of:
        # "git rev-list --bisect-vars --bisect-all ..."
-       eval_rev_list "$_eval" | while read hash line
-       do
-               case "$VARS,$FOUND,$TRIED,$hash" in
-                       # We display some vars.
-                       1,*,*,*) echo "$hash $line" ;;
-
-                       # Split line.
-                       ,*,*,---*) ;;
-
-                       # We had nothing to search.
+       eval_rev_list "$_eval" | {
+               VARS= FOUND= TRIED=
+               while read hash line
+               do
+                       case "$VARS,$FOUND,$TRIED,$hash" in
+                       1,*,*,*)
+                               # "bisect_foo=bar" read from rev-list output.
+                               echo "$hash &&"
+                               ;;
+                       ,*,*,---*)
+                               # Separator
+                               ;;
                        ,,,bisect_rev*)
-                               echo "bisect_rev="
+                               # We had nothing to search.
+                               echo "bisect_rev= &&"
                                VARS=1
                                ;;
-
-                       # We did not find a good bisect rev.
-                       # This should happen only if the "bad"
-                       # commit is also a "skip" commit.
                        ,,*,bisect_rev*)
-                               echo "bisect_rev=$TRIED"
+                               # We did not find a good bisect rev.
+                               # This should happen only if the "bad"
+                               # commit is also a "skip" commit.
+                               echo "bisect_rev='$TRIED' &&"
                                VARS=1
                                ;;
-
-                       # We are searching.
                        ,,*,*)
+                               # We are searching.
                                TRIED="${TRIED:+$TRIED|}$hash"
                                case "$_skip" in
                                *$hash*) ;;
                                *)
-                                       echo "bisect_rev=$hash"
-                                       echo "bisect_tried=\"$TRIED\""
+                                       echo "bisect_rev=$hash &&"
+                                       echo "bisect_tried='$TRIED' &&"
                                        FOUND=1
                                        ;;
                                esac
                                ;;
-
-                       # We have already found a rev to be tested.
-                       ,1,*,bisect_rev*) VARS=1 ;;
-                       ,1,*,*) ;;
-
-                       # ???
-                       *) die "filter_skipped error " \
-                           "VARS: '$VARS' " \
-                           "FOUND: '$FOUND' " \
-                           "TRIED: '$TRIED' " \
-                           "hash: '$hash' " \
-                           "line: '$line'"
-                       ;;
-               esac
-       done
+                       ,1,*,bisect_rev*)
+                               # We have already found a rev to be tested.
+                               VARS=1
+                               ;;
+                       ,1,*,*)
+                               ;;
+                       *)
+                               # Unexpected input
+                               echo "die 'filter_skipped error'"
+                               die "filter_skipped error " \
+                                   "VARS: '$VARS' " \
+                                   "FOUND: '$FOUND' " \
+                                   "TRIED: '$TRIED' " \
+                                   "hash: '$hash' " \
+                                   "line: '$line'"
+                               ;;
+                       esac
+               done
+               echo ':'
+       }
 }
 
 exit_if_skipped_commits () {
index 36c9a6965f2b200f712ae5a6ae008ca1ef5007a0..0b81e65aa3897f40f4ef420bae7ed4f7bf4c5675 100755 (executable)
@@ -224,6 +224,31 @@ test_expect_success 'bisect skip: cannot tell between 2 commits' '
        fi
 '
 
+# $HASH1 is good, $HASH4 is both skipped and bad, we skip $HASH3
+# and $HASH2 is good,
+# so we should not be able to tell the first bad commit
+# among $HASH3 and $HASH4
+test_expect_success 'bisect skip: with commit both bad and skipped' '
+       git bisect start &&
+       git bisect skip &&
+       git bisect bad &&
+       git bisect good $HASH1 &&
+       git bisect skip &&
+       if git bisect good > my_bisect_log.txt
+       then
+               echo Oops, should have failed.
+               false
+       else
+               test $? -eq 2 &&
+               grep "first bad commit could be any of" my_bisect_log.txt &&
+               ! grep $HASH1 my_bisect_log.txt &&
+               ! grep $HASH2 my_bisect_log.txt &&
+               grep $HASH3 my_bisect_log.txt &&
+               grep $HASH4 my_bisect_log.txt &&
+               git bisect reset
+       fi
+'
+
 # We want to automatically find the commit that
 # introduced "Another" into hello.
 test_expect_success \