Merge branch 'js/maint-submodule-checkout'
[gitweb.git] / t / t6030-bisect-porcelain.sh
index 0626544823d6ff9d37ea86c752285d093788df3e..052a6c90f5a184ddc82f2db1a2907a1b1104166c 100755 (executable)
@@ -2,7 +2,7 @@
 #
 # Copyright (c) 2007 Christian Couder
 #
-test_description='Tests git-bisect functionality'
+test_description='Tests git bisect functionality'
 
 exec </dev/null
 
@@ -23,7 +23,7 @@ add_line_into_file()
     fi
 
     test_tick
-    git-commit --quiet -m "$MSG" $_file
+    git commit --quiet -m "$MSG" $_file
 }
 
 HASH1=
@@ -76,7 +76,7 @@ test_expect_success 'bisect fails if given any junk instead of revs' '
        test_must_fail git bisect start foo $HASH1 -- &&
        test_must_fail git bisect start $HASH4 $HASH1 bar -- &&
        test -z "$(git for-each-ref "refs/bisect/*")" &&
-       test_must_fail ls .git/BISECT_* &&
+       test -z "$(ls .git/BISECT_* 2>/dev/null)" &&
        git bisect start &&
        test_must_fail git bisect good foo $HASH1 &&
        test_must_fail git bisect good $HASH1 bar &&
@@ -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 \
@@ -313,8 +338,25 @@ test_expect_success 'bisect run & skip: find first bad' '
        grep "$HASH6 is first bad commit" my_bisect_log.txt
 '
 
-test_expect_success 'bisect starting with a detached HEAD' '
+test_expect_success 'bisect skip only one range' '
+       git bisect reset &&
+       git bisect start $HASH7 $HASH1 &&
+       git bisect skip $HASH1..$HASH5 &&
+       test "$HASH6" = "$(git rev-parse --verify HEAD)" &&
+       test_must_fail git bisect bad > my_bisect_log.txt &&
+       grep "first bad commit could be any of" my_bisect_log.txt
+'
+
+test_expect_success 'bisect skip many ranges' '
+       git bisect start $HASH7 $HASH1 &&
+       test "$HASH4" = "$(git rev-parse --verify HEAD)" &&
+       git bisect skip $HASH2 $HASH2.. ..$HASH5 &&
+       test "$HASH6" = "$(git rev-parse --verify HEAD)" &&
+       test_must_fail git bisect bad > my_bisect_log.txt &&
+       grep "first bad commit could be any of" my_bisect_log.txt
+'
 
+test_expect_success 'bisect starting with a detached HEAD' '
        git bisect reset &&
        git checkout master^ &&
        HEAD=$(git rev-parse --verify HEAD) &&
@@ -350,6 +392,120 @@ test_expect_success 'bisect does not create a "bisect" branch' '
        git branch -D bisect
 '
 
+# This creates a "side" branch to test "siblings" cases.
+#
+# H1-H2-H3-H4-H5-H6-H7  <--other
+#            \
+#             S5-S6-S7  <--side
+#
+test_expect_success 'side branch creation' '
+       git bisect reset &&
+       git checkout -b side $HASH4 &&
+       add_line_into_file "5(side): first line on a side branch" hello2 &&
+       SIDE_HASH5=$(git rev-parse --verify HEAD) &&
+       add_line_into_file "6(side): second line on a side branch" hello2 &&
+       SIDE_HASH6=$(git rev-parse --verify HEAD) &&
+       add_line_into_file "7(side): third line on a side branch" hello2 &&
+       SIDE_HASH7=$(git rev-parse --verify HEAD)
+'
+
+test_expect_success 'good merge base when good and bad are siblings' '
+       git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
+       grep "merge base must be tested" my_bisect_log.txt &&
+       grep $HASH4 my_bisect_log.txt &&
+       git bisect good > my_bisect_log.txt &&
+       test_must_fail grep "merge base must be tested" my_bisect_log.txt &&
+       grep $HASH6 my_bisect_log.txt &&
+       git bisect reset
+'
+test_expect_success 'skipped merge base when good and bad are siblings' '
+       git bisect start "$SIDE_HASH7" "$HASH7" > my_bisect_log.txt &&
+       grep "merge base must be tested" my_bisect_log.txt &&
+       grep $HASH4 my_bisect_log.txt &&
+       git bisect skip > my_bisect_log.txt 2>&1 &&
+       grep "Warning" my_bisect_log.txt &&
+       grep $SIDE_HASH6 my_bisect_log.txt &&
+       git bisect reset
+'
+
+test_expect_success 'bad merge base when good and bad are siblings' '
+       git bisect start "$HASH7" HEAD > my_bisect_log.txt &&
+       grep "merge base must be tested" my_bisect_log.txt &&
+       grep $HASH4 my_bisect_log.txt &&
+       test_must_fail git bisect bad > my_bisect_log.txt 2>&1 &&
+       grep "merge base $HASH4 is bad" my_bisect_log.txt &&
+       grep "fixed between $HASH4 and \[$SIDE_HASH7\]" my_bisect_log.txt &&
+       git bisect reset
+'
+
+# This creates a few more commits (A and B) to test "siblings" cases
+# when a good and a bad rev have many merge bases.
+#
+# We should have the following:
+#
+# H1-H2-H3-H4-H5-H6-H7
+#            \  \     \
+#             S5-A     \
+#              \        \
+#               S6-S7----B
+#
+# And there A and B have 2 merge bases (S5 and H5) that should be
+# reported by "git merge-base --all A B".
+#
+test_expect_success 'many merge bases creation' '
+       git checkout "$SIDE_HASH5" &&
+       git merge -m "merge HASH5 and SIDE_HASH5" "$HASH5" &&
+       A_HASH=$(git rev-parse --verify HEAD) &&
+       git checkout side &&
+       git merge -m "merge HASH7 and SIDE_HASH7" "$HASH7" &&
+       B_HASH=$(git rev-parse --verify HEAD) &&
+       git merge-base --all "$A_HASH" "$B_HASH" > merge_bases.txt &&
+       test $(wc -l < merge_bases.txt) = "2" &&
+       grep "$HASH5" merge_bases.txt &&
+       grep "$SIDE_HASH5" merge_bases.txt
+'
+
+test_expect_success 'good merge bases when good and bad are siblings' '
+       git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt &&
+       grep "merge base must be tested" my_bisect_log.txt &&
+       git bisect good > my_bisect_log2.txt &&
+       grep "merge base must be tested" my_bisect_log2.txt &&
+       {
+               {
+                       grep "$SIDE_HASH5" my_bisect_log.txt &&
+                       grep "$HASH5" my_bisect_log2.txt
+               } || {
+                       grep "$SIDE_HASH5" my_bisect_log2.txt &&
+                       grep "$HASH5" my_bisect_log.txt
+               }
+       } &&
+       git bisect reset
+'
+
+check_trace() {
+       grep "$1" "$GIT_TRACE" | grep "\^$2" | grep "$3" >/dev/null
+}
+
+test_expect_success 'optimized merge base checks' '
+       GIT_TRACE="$(pwd)/trace.log" &&
+       export GIT_TRACE &&
+       git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
+       grep "merge base must be tested" my_bisect_log.txt &&
+       grep "$HASH4" my_bisect_log.txt &&
+       check_trace "rev-list" "$HASH7" "$SIDE_HASH7" &&
+       git bisect good > my_bisect_log2.txt &&
+       test -f ".git/BISECT_ANCESTORS_OK" &&
+       test "$HASH6" = $(git rev-parse --verify HEAD) &&
+       : > "$GIT_TRACE" &&
+       git bisect bad > my_bisect_log3.txt &&
+       test_must_fail check_trace "rev-list" "$HASH6" "$SIDE_HASH7" &&
+       git bisect good "$A_HASH" > my_bisect_log4.txt &&
+       grep "merge base must be tested" my_bisect_log4.txt &&
+       test_must_fail test -f ".git/BISECT_ANCESTORS_OK" &&
+       check_trace "rev-list" "$HASH6" "$A_HASH" &&
+       unset GIT_TRACE
+'
+
 #
 #
 test_done