summaryrefslogtreecommitdiff
path: root/t/t6030-bisect-porcelain.sh
diff options
context:
space:
mode:
Diffstat (limited to 't/t6030-bisect-porcelain.sh')
-rwxr-xr-xt/t6030-bisect-porcelain.sh327
1 files changed, 312 insertions, 15 deletions
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index a1baf4e..cdc0270 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -34,6 +34,36 @@ HASH2=
HASH3=
HASH4=
+test_bisect_usage () {
+ local code="$1" &&
+ shift &&
+ cat >expect &&
+ test_expect_code $code "$@" >out 2>actual &&
+ test_must_be_empty out &&
+ test_cmp expect actual
+}
+
+test_expect_success 'bisect usage' "
+ test_bisect_usage 1 git bisect reset extra1 extra2 <<-\EOF &&
+ error: 'git bisect reset' requires either no argument or a commit
+ EOF
+ test_bisect_usage 1 git bisect terms extra1 extra2 <<-\EOF &&
+ error: 'git bisect terms' requires 0 or 1 argument
+ EOF
+ test_bisect_usage 1 git bisect next extra1 <<-\EOF &&
+ error: 'git bisect next' requires 0 arguments
+ EOF
+ test_bisect_usage 1 git bisect log extra1 <<-\EOF &&
+ error: We are not bisecting.
+ EOF
+ test_bisect_usage 1 git bisect replay <<-\EOF &&
+ error: no logfile given
+ EOF
+ test_bisect_usage 1 git bisect run <<-\EOF
+ error: 'git bisect run' failed: no command provided.
+ EOF
+"
+
test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' '
add_line_into_file "1: Hello World" hello &&
HASH1=$(git rev-parse --verify HEAD) &&
@@ -92,6 +122,29 @@ test_expect_success 'bisect start without -- takes unknown arg as pathspec' '
grep bar ".git/BISECT_NAMES"
'
+test_expect_success 'bisect reset: back in a branch checked out also elsewhere' '
+ echo "shared" > branch.expect &&
+ test_bisect_reset() {
+ git -C $1 bisect start &&
+ git -C $1 bisect good $HASH1 &&
+ git -C $1 bisect bad $HASH3 &&
+ git -C $1 bisect reset &&
+ git -C $1 branch --show-current > branch.output &&
+ cmp branch.expect branch.output
+ } &&
+ test_when_finished "
+ git worktree remove wt1 &&
+ git worktree remove wt2 &&
+ git branch -d shared
+ " &&
+ git worktree add wt1 -b shared &&
+ git worktree add wt2 -f shared &&
+ # we test in both worktrees to ensure that works
+ # as expected with "first" and "next" worktrees
+ test_bisect_reset wt1 &&
+ test_bisect_reset wt2
+'
+
test_expect_success 'bisect reset: back in the main branch' '
git bisect reset &&
echo "* main" > branch.expect &&
@@ -117,6 +170,12 @@ test_expect_success 'bisect reset when not bisecting' '
cmp branch.expect branch.output
'
+test_expect_success 'bisect reset cleans up even when not bisecting' '
+ echo garbage >.git/BISECT_LOG &&
+ git bisect reset &&
+ test_path_is_missing .git/BISECT_LOG
+'
+
test_expect_success 'bisect reset removes packed refs' '
git bisect reset &&
git bisect start &&
@@ -167,7 +226,7 @@ test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if
cp .git/BISECT_START saved &&
test_must_fail git bisect start $HASH4 foo -- &&
git branch > branch.output &&
- test_i18ngrep "* (no branch, bisect started on other)" branch.output > /dev/null &&
+ test_grep "* (no branch, bisect started on other)" branch.output > /dev/null &&
test_cmp saved .git/BISECT_START
'
test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
@@ -252,6 +311,124 @@ test_expect_success 'bisect skip: with commit both bad and skipped' '
grep $HASH4 my_bisect_log.txt
'
+test_bisect_run_args () {
+ test_when_finished "rm -f run.sh actual" &&
+ >actual &&
+ cat >expect.args &&
+ cat <&6 >expect.out &&
+ cat <&7 >expect.err &&
+ write_script run.sh <<-\EOF &&
+ while test $# != 0
+ do
+ echo "<$1>" &&
+ shift
+ done >actual.args
+ EOF
+
+ test_when_finished "git bisect reset" &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run ./run.sh $@ >actual.out.raw 2>actual.err &&
+ # Prune just the log output
+ sed -n \
+ -e '/^Author:/d' \
+ -e '/^Date:/d' \
+ -e '/^$/d' \
+ -e '/^commit /d' \
+ -e '/^ /d' \
+ -e 'p' \
+ <actual.out.raw >actual.out &&
+ test_cmp expect.out actual.out &&
+ test_cmp expect.err actual.err &&
+ test_cmp expect.args actual.args
+}
+
+test_expect_success 'git bisect run: args, stdout and stderr with no arguments' "
+ test_bisect_run_args <<-'EOF_ARGS' 6<<-EOF_OUT 7<<-'EOF_ERR'
+ EOF_ARGS
+ running './run.sh'
+ $HASH4 is the first bad commit
+ bisect found first bad commit
+ EOF_OUT
+ EOF_ERR
+"
+
+test_expect_success 'git bisect run: args, stdout and stderr: "--" argument' "
+ test_bisect_run_args -- <<-'EOF_ARGS' 6<<-EOF_OUT 7<<-'EOF_ERR'
+ <-->
+ EOF_ARGS
+ running './run.sh' '--'
+ $HASH4 is the first bad commit
+ bisect found first bad commit
+ EOF_OUT
+ EOF_ERR
+"
+
+test_expect_success 'git bisect run: args, stdout and stderr: "--log foo --no-log bar" arguments' "
+ test_bisect_run_args --log foo --no-log bar <<-'EOF_ARGS' 6<<-EOF_OUT 7<<-'EOF_ERR'
+ <--log>
+ <foo>
+ <--no-log>
+ <bar>
+ EOF_ARGS
+ running './run.sh' '--log' 'foo' '--no-log' 'bar'
+ $HASH4 is the first bad commit
+ bisect found first bad commit
+ EOF_OUT
+ EOF_ERR
+"
+
+test_expect_success 'git bisect run: args, stdout and stderr: "--bisect-start" argument' "
+ test_bisect_run_args --bisect-start <<-'EOF_ARGS' 6<<-EOF_OUT 7<<-'EOF_ERR'
+ <--bisect-start>
+ EOF_ARGS
+ running './run.sh' '--bisect-start'
+ $HASH4 is the first bad commit
+ bisect found first bad commit
+ EOF_OUT
+ EOF_ERR
+"
+
+test_expect_success 'git bisect run: negative exit code' "
+ write_script fail.sh <<-'EOF' &&
+ exit 255
+ EOF
+ cat <<-'EOF' >expect &&
+ bisect run failed: exit code -1 from './fail.sh' is < 0 or >= 128
+ EOF
+ test_when_finished 'git bisect reset' &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ ! git bisect run ./fail.sh 2>err &&
+ sed -En 's/.*(bisect.*code) (-?[0-9]+) (from.*)/\1 -1 \3/p' err >actual &&
+ test_cmp expect actual
+"
+
+test_expect_success 'git bisect run: unable to verify on good' "
+ write_script fail.sh <<-'EOF' &&
+ head=\$(git rev-parse --verify HEAD)
+ good=\$(git rev-parse --verify $HASH1)
+ if test "\$head" = "\$good"
+ then
+ exit 255
+ else
+ exit 127
+ fi
+ EOF
+ cat <<-'EOF' >expect &&
+ unable to verify './fail.sh' on good revision
+ EOF
+ test_when_finished 'git bisect reset' &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ ! git bisect run ./fail.sh 2>err &&
+ sed -n 's/.*\(unable to verify.*\)/\1/p' err >actual &&
+ test_cmp expect actual
+"
+
# We want to automatically find the commit that
# added "Another" into hello.
test_expect_success '"git bisect run" simple case' '
@@ -266,6 +443,16 @@ test_expect_success '"git bisect run" simple case' '
git bisect reset
'
+# We want to make sure no arguments has been eaten
+test_expect_success '"git bisect run" simple case' '
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run printf "%s %s\n" reset --bisect-skip >my_bisect_log.txt &&
+ grep -e "reset --bisect-skip" my_bisect_log.txt &&
+ git bisect reset
+'
+
# We want to automatically find the commit that
# added "Ciao" into hello.
test_expect_success '"git bisect run" with more complex "git bisect start"' '
@@ -278,6 +465,51 @@ test_expect_success '"git bisect run" with more complex "git bisect start"' '
git bisect reset
'
+test_expect_success 'bisect run accepts exit code 126 as bad' '
+ test_when_finished "git bisect reset" &&
+ write_script test_script.sh <<-\EOF &&
+ ! grep Another hello || exit 126 >/dev/null
+ EOF
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run ./test_script.sh >my_bisect_log.txt &&
+ grep "$HASH3 is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success POSIXPERM 'bisect run fails with non-executable test script' '
+ test_when_finished "git bisect reset" &&
+ >not-executable.sh &&
+ chmod -x not-executable.sh &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ test_must_fail git bisect run ./not-executable.sh >my_bisect_log.txt &&
+ ! grep "is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'bisect run accepts exit code 127 as bad' '
+ test_when_finished "git bisect reset" &&
+ write_script test_script.sh <<-\EOF &&
+ ! grep Another hello || exit 127 >/dev/null
+ EOF
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run ./test_script.sh >my_bisect_log.txt &&
+ grep "$HASH3 is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'bisect run fails with missing test script' '
+ test_when_finished "git bisect reset" &&
+ rm -f does-not-exist.sh &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ test_must_fail git bisect run ./does-not-exist.sh >my_bisect_log.txt &&
+ ! grep "is the first bad commit" my_bisect_log.txt
+'
+
# $HASH1 is good, $HASH5 is bad, we skip $HASH3
# but $HASH4 is good,
# so we should find $HASH5 as the first bad commit
@@ -362,7 +594,7 @@ test_expect_success 'bisect starting with a detached HEAD' '
test_expect_success 'bisect errors out if bad and good are mistaken' '
git bisect reset &&
test_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&
- test_i18ngrep "mistook good and bad" rev_list_error &&
+ test_grep "mistook good and bad" rev_list_error &&
git bisect reset
'
@@ -404,7 +636,7 @@ test_expect_success 'side branch creation' '
test_expect_success 'good merge base when good and bad are siblings' '
git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log.txt &&
+ test_grep "merge base must be tested" my_bisect_log.txt &&
grep $HASH4 my_bisect_log.txt &&
git bisect good > my_bisect_log.txt &&
! grep "merge base must be tested" my_bisect_log.txt &&
@@ -413,7 +645,7 @@ test_expect_success 'good merge base when good and bad are siblings' '
'
test_expect_success 'skipped merge base when good and bad are siblings' '
git bisect start "$SIDE_HASH7" "$HASH7" > my_bisect_log.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log.txt &&
+ test_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 &&
@@ -423,11 +655,11 @@ test_expect_success 'skipped merge base when good and bad are siblings' '
test_expect_success 'bad merge base when good and bad are siblings' '
git bisect start "$HASH7" HEAD > my_bisect_log.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log.txt &&
+ test_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 &&
- test_i18ngrep "merge base $HASH4 is bad" my_bisect_log.txt &&
- test_i18ngrep "fixed between $HASH4 and \[$SIDE_HASH7\]" my_bisect_log.txt &&
+ test_grep "merge base $HASH4 is bad" my_bisect_log.txt &&
+ test_grep "fixed between $HASH4 and \[$SIDE_HASH7\]" my_bisect_log.txt &&
git bisect reset
'
@@ -478,9 +710,9 @@ test_expect_success '"git bisect run --first-parent" simple case' '
test_expect_success 'good merge bases when good and bad are siblings' '
git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log.txt &&
+ test_grep "merge base must be tested" my_bisect_log.txt &&
git bisect good > my_bisect_log2.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log2.txt &&
+ test_grep "merge base must be tested" my_bisect_log2.txt &&
{
{
grep "$SIDE_HASH5" my_bisect_log.txt &&
@@ -495,14 +727,14 @@ test_expect_success 'good merge bases when good and bad are siblings' '
test_expect_success 'optimized merge base checks' '
git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log.txt &&
+ test_grep "merge base must be tested" my_bisect_log.txt &&
grep "$HASH4" my_bisect_log.txt &&
git bisect good > my_bisect_log2.txt &&
test -f ".git/BISECT_ANCESTORS_OK" &&
test "$HASH6" = $(git rev-parse --verify HEAD) &&
git bisect bad &&
git bisect good "$A_HASH" > my_bisect_log4.txt &&
- test_i18ngrep "merge base must be tested" my_bisect_log4.txt &&
+ test_grep "merge base must be tested" my_bisect_log4.txt &&
test_path_is_missing ".git/BISECT_ANCESTORS_OK"
'
@@ -580,7 +812,7 @@ test_expect_success 'skipping away from skipped commit' '
test_expect_success 'erroring out when using bad path arguments' '
test_must_fail git bisect start $PARA_HASH7 $HASH1 -- foobar 2> error.txt &&
- test_i18ngrep "bad path arguments" error.txt
+ test_grep "bad path arguments" error.txt
'
test_expect_success 'test bisection on bare repo - --no-checkout specified' '
@@ -646,7 +878,7 @@ test_expect_success 'broken branch creation' '
echo "" > expected.ok
cat > expected.missing-tree.default <<EOF
-fatal: unable to read tree $deleted
+fatal: unable to read tree ($deleted)
EOF
test_expect_success 'bisect fails if tree is broken on start commit' '
@@ -855,6 +1087,16 @@ test_expect_success 'bisect start with one term1 and term2' '
git bisect reset
'
+test_expect_success 'bogus command does not start bisect' '
+ git bisect reset &&
+ test_must_fail git bisect --bisect-terms 1 2 2>out &&
+ ! grep "You need to start" out &&
+ test_must_fail git bisect --bisect-terms 2>out &&
+ ! grep "You need to start" out &&
+ grep "git bisect.*visualize" out &&
+ git bisect reset
+'
+
test_expect_success 'bisect replay with term1 and term2' '
git bisect replay log_to_replay.txt >bisect_result &&
grep "$HASH2 is the first term1 commit" bisect_result &&
@@ -940,12 +1182,11 @@ test_expect_success 'git bisect reset cleans bisection state properly' '
git bisect bad $HASH4 &&
git bisect reset &&
test -z "$(git for-each-ref "refs/bisect/*")" &&
- test_path_is_missing ".git/BISECT_EXPECTED_REV" &&
+ test_ref_missing BISECT_EXPECTED_REV &&
test_path_is_missing ".git/BISECT_ANCESTORS_OK" &&
test_path_is_missing ".git/BISECT_LOG" &&
test_path_is_missing ".git/BISECT_RUN" &&
test_path_is_missing ".git/BISECT_TERMS" &&
- test_path_is_missing ".git/head-name" &&
test_path_is_missing ".git/BISECT_HEAD" &&
test_path_is_missing ".git/BISECT_START"
'
@@ -962,4 +1203,60 @@ test_expect_success 'bisect handles annotated tags' '
grep "$bad is the first bad commit" output
'
+test_expect_success 'bisect run fails with exit code equals or greater than 128' '
+ write_script test_script.sh <<-\EOF &&
+ exit 128
+ EOF
+ test_must_fail git bisect run ./test_script.sh &&
+ write_script test_script.sh <<-\EOF &&
+ exit 255
+ EOF
+ test_must_fail git bisect run ./test_script.sh
+'
+
+test_expect_success 'bisect visualize with a filename with dash and space' '
+ echo "My test line" >>"./-hello 2" &&
+ git add -- "./-hello 2" &&
+ git commit --quiet -m "Add test line" -- "./-hello 2" &&
+ git bisect visualize -p -- "-hello 2"
+'
+
+test_expect_success 'bisect state output with multiple good commits' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect log >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect good "$HASH1" >output &&
+ grep "waiting for bad commit, 1 good commit known" output &&
+ git bisect log >output &&
+ grep "waiting for bad commit, 1 good commit known" output &&
+ git bisect good "$HASH2" >output &&
+ grep "waiting for bad commit, 2 good commits known" output &&
+ git bisect log >output &&
+ grep "waiting for bad commit, 2 good commits known" output
+'
+
+test_expect_success 'bisect state output with bad commit' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect log >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect bad "$HASH4" >output &&
+ grep -F "waiting for good commit(s), bad commit known" output &&
+ git bisect log >output &&
+ grep -F "waiting for good commit(s), bad commit known" output
+'
+
+test_expect_success 'verify correct error message' '
+ git bisect reset &&
+ git bisect start $HASH4 $HASH1 &&
+ write_script test_script.sh <<-\EOF &&
+ rm .git/BISECT*
+ EOF
+ test_must_fail git bisect run ./test_script.sh 2>error &&
+ grep "git bisect good.*exited with error code" error
+'
+
test_done