diff options
-rwxr-xr-x | git-bisect.sh | 48 | ||||
-rwxr-xr-x | t/t6030-bisect-porcelain.sh | 24 |
2 files changed, 58 insertions, 14 deletions
diff --git a/git-bisect.sh b/git-bisect.sh index b314d47704..69a9a565e0 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -172,6 +172,25 @@ 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") +} + +mark_expected_rev() { + echo "$1" > "$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_state() { bisect_autostart state=$1 @@ -181,7 +200,8 @@ bisect_state() { 1,bad|1,good|1,skip) rev=$(git rev-parse --verify HEAD) || die "Bad rev input: HEAD" - bisect_write "$state" "$rev" ;; + bisect_write "$state" "$rev" + check_expected_revs "$rev" ;; 2,bad|*,good|*,skip) shift eval='' @@ -191,7 +211,8 @@ bisect_state() { die "Bad rev input: $rev" eval="$eval bisect_write '$state' '$sha'; " done - eval "$eval" ;; + eval "$eval" + check_expected_revs "$@" ;; *,bad) die "'git bisect bad' can take only one argument." ;; *) @@ -321,6 +342,7 @@ bisect_checkout() { _rev="$1" _msg="$2" echo "Bisecting: $_msg" + mark_expected_rev "$_rev" git checkout -q "$_rev" || exit git show-branch "$_rev" } @@ -332,18 +354,10 @@ is_among() { return 1 } -is_testing_merge_base() { - grep "^testing $1$" "$GIT_DIR/BISECT_MERGE_BASES" >/dev/null 2>&1 -} - -mark_testing_merge_base() { - echo "testing $1" >> "$GIT_DIR/BISECT_MERGE_BASES" -} - handle_bad_merge_base() { _badmb="$1" _good="$2" - if is_testing_merge_base "$_badmb"; then + if is_expected_rev "$_badmb"; then cat >&2 <<EOF The merge base $_badmb is bad. This means the bug has been fixed between $_badmb and [$_good]. @@ -383,7 +397,6 @@ check_merge_bases() { elif is_among "$_mb" "$_skip"; then handle_skipped_merge_base "$_mb" "$_bad" "$_good" else - mark_testing_merge_base "$_mb" bisect_checkout "$_mb" "a merge base must be tested" checkout_done=1 return @@ -392,6 +405,9 @@ check_merge_bases() { } check_good_are_ancestors_of_bad() { + test -f "$GIT_DIR/BISECT_ANCESTORS_OK" && + return + _bad="$1" _good=$(echo $2 | sed -e 's/\^//g') _skip="$3" @@ -401,8 +417,11 @@ check_good_are_ancestors_of_bad() { _side=$(git rev-list $_good ^$_bad) if test -n "$_side"; then - check_merge_bases "$_bad" "$_good" "$_skip" + check_merge_bases "$_bad" "$_good" "$_skip" || return + test "$checkout_done" -eq "1" && return fi + + : > "$GIT_DIR/BISECT_ANCESTORS_OK" } bisect_next() { @@ -491,7 +510,8 @@ bisect_clean_state() { do git update-ref -d $ref $hash || exit done - rm -f "$GIT_DIR/BISECT_MERGE_BASES" && + 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" && diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index a1ce95c5a6..c163114693 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -440,6 +440,30 @@ test_expect_success 'good merge bases when good and bad are siblings' ' 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 |