[PATCH] bisect: error out when given any good rev that is not an ancestor of the bad rev

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Before this patch "git bisect" doesn't really work when it is given
some good revs that are siblings of the bad rev.

For example if there is the following history:

A-B-C-D
   \E-F

and we launch "git bisect start D F" then only C and D will be
considered as possible first bad commit. This is wrong because A, B and
E may be bad too if the bug exists everywhere except in F that fixes it.

Maybe there is a way to make the above work, but for now the purpose of
this patch is to fix the problem by checking that all good revs are
ancestor of the bad rev and by erroring out if this is not the case.

To do that we run "git rev-list ^bad good" and we check that it outputs
nothing.

This check will also catch the case where good and bad have been
mistaken. This means that we can remove the check that was done latter
on the output of "git rev-list --bisect-vars". The downside of that is
that now we can't tell between a mistake and a "siblings" case.

Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx>
---
 git-bisect.sh               |   32 +++++++++++++++-----------------
 t/t6030-bisect-porcelain.sh |   19 +++++++++++++++++++
 2 files changed, 34 insertions(+), 17 deletions(-)

	Maybe we can improve on this patch by trying to tell between
	a mistake and a "siblings" case to give a better error
	message.

diff --git a/git-bisect.sh b/git-bisect.sh
index 991b2ef..90a9d74 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -242,33 +242,18 @@ bisect_auto_next() {
 	bisect_next_check && bisect_next || :
 }
 
-eval_rev_list() {
-	_eval="$1"
-
-	eval $_eval
-	res=$?
-
-	if [ $res -ne 0 ]; then
-		echo >&2 "'git rev-list --bisect-vars' failed:"
-		echo >&2 "maybe you mistake good and bad revs?"
-		exit $res
-	fi
-
-	return $res
-}
-
 filter_skipped() {
 	_eval="$1"
 	_skip="$2"
 
 	if [ -z "$_skip" ]; then
-		eval_rev_list "$_eval"
+		eval "$_eval"
 		return
 	fi
 
 	# Let's parse the output of:
 	# "git rev-list --bisect-vars --bisect-all ..."
-	eval_rev_list "$_eval" | while read hash line
+	eval "$_eval" | while read hash line
 	do
 		case "$VARS,$FOUND,$TRIED,$hash" in
 			# We display some vars.
@@ -331,6 +316,18 @@ exit_if_skipped_commits () {
 	fi
 }
 
+check_good_are_ancestor_of_bad() {
+	_bad="^$1"
+	_good=$(echo $2 | sed -e 's/\^//g')
+	_side=$(git rev-list $_good $_bad)
+	if test -n "$_side"; then
+		echo >&2 "Some good revs are not ancestor of the bad rev."
+		echo >&2 "git bisect cannot work properly in this case."
+		echo >&2 "Maybe you mistake good and bad revs?"
+		return 1
+	fi
+}
+
 bisect_next() {
 	case "$#" in 0) ;; *) usage ;; esac
 	bisect_autostart
@@ -345,6 +342,7 @@ bisect_next() {
 	bad=$(git rev-parse --verify refs/bisect/bad) &&
 	good=$(git for-each-ref --format='^%(objectname)' \
 		"refs/bisect/good-*" | tr '\012' ' ') &&
+	check_good_are_ancestor_of_bad "$bad" "$good" &&
 	eval="git rev-list --bisect-vars $BISECT_OPT $good $bad --" &&
 	eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" &&
 	eval=$(filter_skipped "$eval" "$skip") &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 0626544..b3f3869 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -350,6 +350,25 @@ test_expect_success 'bisect does not create a "bisect" branch' '
 	git branch -D bisect
 '
 
+# This creates a "side" branch to test "siblings" cases.
+test_expect_success 'bisect errors out when good and bad are siblings' '
+	git bisect reset &&
+	git checkout -b side $HASH4 &&
+	add_line_into_file "5(side): first line on a side branch" hello &&
+	SIDE_HASH5=$(git rev-parse --verify HEAD) &&
+	add_line_into_file "6(side): second line on a side branch" hello &&
+	SIDE_HASH6=$(git rev-parse --verify HEAD) &&
+	add_line_into_file "7(side): third line on a side branch" hello &&
+	SIDE_HASH7=$(git rev-parse --verify HEAD) &&
+	test_must_fail git bisect start "$HASH7" "$SIDE_HASH7" &&
+	test_must_fail git bisect start "$SIDE_HASH7" "$HASH7" &&
+	test_must_fail git bisect start "$HASH7" HEAD &&
+	test_must_fail git bisect start "$SIDE_HASH5" "$HASH7" &&
+	test_must_fail test -e .git/BISECT_START &&
+	test -z "$(git for-each-ref "refs/bisect/*")" &&
+	test "$(git rev-parse --verify HEAD)" = "$SIDE_HASH7"
+'
+
 #
 #
 test_done
-- 
1.5.6.7.g5b8fa.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux