[PATCH 2/2] git-bisect: allow bisecting with only one bad commit.

Subsystems: the rest

STALE3708d

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH 2/2] git-bisect: allow bisecting with only one bad commit.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:03

This allows you to say:

	git bisect start
	git bisect bad $bad
	git bisect next

to start bisection without knowing a good commit.  This would
have you try a commit that is half-way since the beginning of
the history, which is rather wasteful if you already know a good
commit, but if you don't (or your history is short enough that
you do not care), there is no reason not to allow this.

Signed-off-by: Junio C Hamano <redacted>
---

 * These two are on top of your "bisect start [B [G G...] [--] [paths...]".

 git-bisect.sh         |   87 ++++++++++++++++++++++++++++++-------------------
 t/t6030-bisect-run.sh |   17 +++------
 2 files changed, 59 insertions(+), 45 deletions(-)
diff --git a/git-bisect.sh b/git-bisect.sh
index c936533..85c374e 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -168,26 +168,40 @@ bisect_write_good() {
 }
 
 bisect_next_check() {
-	next_ok=no
-	git show-ref -q --verify refs/bisect/bad &&
-	test -n "$(git for-each-ref "refs/bisect/good-*")" &&
-	next_ok=yes
-
-	case "$next_ok,$1" in
-	no,) false ;;
-	no,fail)
-	    THEN=''
-	    test -d "$GIT_DIR/refs/bisect" || {
-		echo >&2 'You need to start by "git bisect start".'
-		THEN='then '
-	    }
-	    echo >&2 'You '$THEN'need to give me at least one good' \
-		'and one bad revisions.'
-	    echo >&2 '(You can use "git bisect bad" and' \
-		'"git bisect good" for that.)'
-	    exit 1 ;;
+	missing_good= missing_bad=
+	git show-ref -q --verify refs/bisect/bad || missing_bad=t
+	test -n "$(git for-each-ref "refs/bisect/good-*")" || missing_good=t
+
+	case "$missing_good,$missing_bad,$1" in
+	,,*)
+		: have both good and bad - ok
+		;;
+	*,)
+		# do not have both but not asked to fail - just report.
+		false
+		;;
+	t,,good)
+		# have bad but not good.  we could bisect although
+		# this is less optimum.
+		echo >&2 'Warning: bisecting only with a bad commit.'
+		if test -t 0
+		then
+			printf >&2 'Are you sure [Y/n]? '
+			case "$(read yesno)" in [Nn]*) exit 1 ;; esac
+		fi
+		: bisect without good...
+		;;
 	*)
-	    true ;;
+		THEN=''
+		test -d "$GIT_DIR/refs/bisect" || {
+			echo >&2 'You need to start by "git bisect start".'
+			THEN='then '
+		}
+		echo >&2 'You '$THEN'need to give me at least one good' \
+			'and one bad revisions.'
+		echo >&2 '(You can use "git bisect bad" and' \
+			'"git bisect good" for that.)'
+		exit 1 ;;
 	esac
 }
 
@@ -198,27 +212,32 @@ bisect_auto_next() {
 bisect_next() {
         case "$#" in 0) ;; *) usage ;; esac
 	bisect_autostart
-	bisect_next_check fail
+	bisect_next_check good
+
 	bad=$(git-rev-parse --verify refs/bisect/bad) &&
-	good=$(git-rev-parse --sq --revs-only --not \
-		$(cd "$GIT_DIR" && ls refs/bisect/good-*)) &&
-	rev=$(eval "git-rev-list --bisect $good $bad -- $(cat "$GIT_DIR/BISECT_NAMES")") || exit
-	if [ -z "$rev" ]; then
-	    echo "$bad was both good and bad"
-	    exit 1
+	good=$(git for-each-ref --format='^%(objectname)' \
+		"refs/bisect/good-*" | tr '[\012]' ' ') &&
+	eval="git-rev-list --bisect-vars $good $bad --" &&
+	eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" &&
+	eval=$(eval "$eval") &&
+	eval "$eval" || exit
+
+	if [ -z "$bisect_rev" ]; then
+		echo "$bad was both good and bad"
+		exit 1
 	fi
-	if [ "$rev" = "$bad" ]; then
-	    echo "$rev is first bad commit"
-	    git-diff-tree --pretty $rev
-	    exit 0
+	if [ "$bisect_rev" = "$bad" ]; then
+		echo "$bisect_rev is first bad commit"
+		git-diff-tree --pretty $bisect_rev
+		exit 0
 	fi
-	nr=$(eval "git-rev-list $rev $good -- $(cat $GIT_DIR/BISECT_NAMES)" | wc -l) || exit
-	echo "Bisecting: $nr revisions left to test after this"
-	echo "$rev" > "$GIT_DIR/refs/heads/new-bisect"
+
+	echo "Bisecting: $bisect_nr revisions left to test after this"
+	echo "$bisect_rev" >"$GIT_DIR/refs/heads/new-bisect"
 	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-show-branch "$rev"
+	git-show-branch "$bisect_rev"
 }
 
 bisect_visualize() {
diff --git a/t/t6030-bisect-run.sh b/t/t6030-bisect-run.sh
index 1c38f08..7f41807 100755
--- a/t/t6030-bisect-run.sh
+++ b/t/t6030-bisect-run.sh
@@ -4,6 +4,8 @@
 #
 test_description='Tests git-bisect run functionality'
 
+exec </dev/null
+
 . ./test-lib.sh
 
 add_line_into_file()
@@ -37,21 +39,14 @@ test_expect_success \
      HASH3=$(git rev-list HEAD | head -2 | tail -1) &&
      HASH4=$(git rev-list HEAD | head -1)'
 
-test_expect_success 'bisect does not start with only one bad' '
+test_expect_success 'bisect starts with only one bad' '
 	git bisect reset &&
 	git bisect start &&
-	git bisect bad $HASH4 || return 1
-
-	if git bisect next
-	then
-		echo Oops, should have failed.
-		false
-	else
-		:
-	fi
+	git bisect bad $HASH4 &&
+	git bisect next
 '
 
-test_expect_success 'bisect does not start with only one good' '
+test_expect_success 'bisect starts with only one good' '
 	git bisect reset &&
 	git bisect start &&
 	git bisect good $HASH1 || return 1
-- 
1.5.1.53.g77e6f

Re: [PATCH 2/2] git-bisect: allow bisecting with only one bad commit.

From: Christian Couder <hidden>
Date: 2016-06-15 22:43:04

Hi Junio,

You wrote:

[...]
-test_expect_success 'bisect does not start with only one bad' '
+test_expect_success 'bisect starts with only one bad' '
 	git bisect reset &&
 	git bisect start &&
-	git bisect bad $HASH4 || return 1
-
-	if git bisect next
-	then
-		echo Oops, should have failed.
-		false
-	else
-		:
-	fi
+	git bisect bad $HASH4 &&
+	git bisect next
 '
Ok, this is the purpose of your patch to make the above work.
-test_expect_success 'bisect does not start with only one good' '
+test_expect_success 'bisect starts with only one good' '
 	git bisect reset &&
 	git bisect start &&
 	git bisect good $HASH1 || return 1
But I don't understand the need to change the above comment when the test 
code for starting with one good commit is not changed.

Thanks,
Christian.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help