git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
To: git@vger.kernel.org
Cc: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>,
	Lucien Kong <Lucien.Kong@ensimag.imag.fr>,
	Franck Jonas <Franck.Jonas@ensimag.imag.fr>,
	Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>,
	Huynh Khoi Nguyen Nguyen 
	<Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>,
	Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
Subject: [PATCH] git bisect old/new
Date: Tue, 12 Jun 2012 04:03:45 +0200	[thread overview]
Message-ID: <1339466625-17461-1-git-send-email-Valentin.Duperray@ensimag.imag.fr> (raw)

When not looking for a regression during a bisect but for a fix or a
change in another given property, it can be confusing to use 'good'
and 'bad'.
This patch introduce `git bisect new` and `git bisect old` as an
alternative to 'bad' and good' : the commits which have the most
recent version of the property must be marked as `new` and the ones
with the older version as `old`.
The output will be the first commit after the change in the property.
During a new/old bisect session you cannot use bad/good commands and
vice-versa.
Some commands are still not available for old/new:
     * git bisect start [<new> [<old>...]] is not possible : the
       commits will be treated as bad and good.
     * git rev-list --bisect does not treat the revs/bisect/new and
       revs/bisect/old-SHA1 files.
     * thus, git bisect run <cmd> is not available for new/old.
     * git bisect visualize seem to work partially : the tags are
       displayed correctly but the tree is not limited to the bisect
       section.

Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
 Documentation/git-bisect.txt |   40 +++++++++++++++
 bisect.c                     |   88 ++++++++++++++++++++++++---------
 git-bisect.sh                |  113 ++++++++++++++++++++++++++++++++---------
 t/t6030-bisect-porcelain.sh  |   33 ++++++++++++
 4 files changed, 226 insertions(+), 48 deletions(-)

diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index e4f46bc..25673c9 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -20,6 +20,8 @@ on the subcommand:
  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
  git bisect bad [<rev>]
  git bisect good [<rev>...]
+ git bisect new [<rev>]
+ git bisect old [<rev>...]
  git bisect skip [(<rev>|<range>)...]
  git bisect reset [<commit>]
  git bisect visualize
@@ -104,6 +106,44 @@ For example, `git bisect reset HEAD` will leave you on the current
 bisection commit and avoid switching commits at all, while `git bisect
 reset bisect/bad` will check out the first bad revision.
 
+Alternative research: bisect new and bisect old
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are not looking for a regression but for a change of a given
+property, you can use:
+
+------------------------------------------------
+git bisect new [<rev>]
+------------------------------------------------
+
+Mark the commits that have the new version of the property.
+
+------------------------------------------------
+git bisect old [<rev>...]
+------------------------------------------------
+
+Mark the commits that have the old version of the property.
+
+For example, when looking for a fix in the code, the "new" commits are
+the fixed ones and the "old" commits are the unfixed ones.
+
+------------------------------------------------
+$ git bisect start
+$ git bisect new		# Current version is fixed
+$ git bisect old bugged_version	# bugged_version was the last version
+				# known to be unfixed
+------------------------------------------------
+
+At the end of the commit session, you will have the first commit that
+have the new version of the property ("fixed" here).
+
+You must run `git bisect start` without commits as argument and run
+`git bisect new <rev>`/`git bisect old <rev>...` after to add the
+commits.
+The bisect old/new sessions and the good/bad ones cannot be mixed.
+You must use `git bisect reset` and start again in order to change
+the mode.
+
 Bisect visualize
 ~~~~~~~~~~~~~~~~
 
diff --git a/bisect.c b/bisect.c
index 48acf73..474b615 100644
--- a/bisect.c
+++ b/bisect.c
@@ -21,6 +21,9 @@ static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
 static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
 static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
 
+static const char *bisect_term_bad;
+static const char *bisect_term_good;
+
 /* bits #0-15 in revision.h */
 
 #define COUNTED		(1u<<16)
@@ -403,9 +406,10 @@ struct commit_list *find_bisection(struct commit_list *list,
 static int register_ref(const char *refname, const unsigned char *sha1,
 			int flags, void *cb_data)
 {
-	if (!strcmp(refname, "bad")) {
+	if (!strcmp(refname, bisect_term_bad)) {
 		current_bad_sha1 = sha1;
-	} else if (!prefixcmp(refname, "good-")) {
+	} else if (!prefixcmp(refname, "good-") ||
+			!prefixcmp(refname, "old-")) {
 		sha1_array_append(&good_revs, sha1);
 	} else if (!prefixcmp(refname, "skip-")) {
 		sha1_array_append(&skipped_revs, sha1);
@@ -633,7 +637,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,
 		return;
 
 	printf("There are only 'skip'ped commits left to test.\n"
-	       "The first bad commit could be any of:\n");
+	       "The first %s commit could be any of:\n", bisect_term_bad);
 	print_commit_list(tried, "%s\n", "%s\n");
 	if (bad)
 		printf("%s\n", sha1_to_hex(bad));
@@ -731,18 +735,25 @@ static void handle_bad_merge_base(void)
 	if (is_expected_rev(current_bad_sha1)) {
 		char *bad_hex = sha1_to_hex(current_bad_sha1);
 		char *good_hex = join_sha1_array_hex(&good_revs, ' ');
-
-		fprintf(stderr, "The merge base %s is bad.\n"
-			"This means the bug has been fixed "
-			"between %s and [%s].\n",
-			bad_hex, bad_hex, good_hex);
-
+		if (!strcmp(bisect_term_bad,"bad")) {
+			fprintf(stderr, "The merge base %s is bad.\n"
+				"This means the bug has been fixed "
+				"between %s and [%s].\n",
+				bad_hex, bad_hex, good_hex);
+		} else {
+			fprintf(stderr, "The merge base %s is new.\n"
+				"The property has changed "
+				"between %s and [%s].\n",
+				bad_hex, bad_hex, good_hex);
+		}
 		exit(3);
 	}
 
-	fprintf(stderr, "Some good revs are not ancestor of the bad rev.\n"
+	fprintf(stderr, "Some %s revs are not ancestor of the %s rev.\n"
 		"git bisect cannot work properly in this case.\n"
-		"Maybe you mistake good and bad revs?\n");
+		"Maybe you mistake %s and %s revs?\n",
+		bisect_term_good, bisect_term_bad, bisect_term_good,
+		bisect_term_bad);
 	exit(1);
 }
 
@@ -754,19 +765,19 @@ static void handle_skipped_merge_base(const unsigned char *mb)
 
 	warning("the merge base between %s and [%s] "
 		"must be skipped.\n"
-		"So we cannot be sure the first bad commit is "
+		"So we cannot be sure the first %s commit is "
 		"between %s and %s.\n"
 		"We continue anyway.",
-		bad_hex, good_hex, mb_hex, bad_hex);
+		bad_hex, good_hex, bisect_term_bad, mb_hex, bad_hex);
 	free(good_hex);
 }
 
 /*
- * "check_merge_bases" checks that merge bases are not "bad".
+ * "check_merge_bases" checks that merge bases are not "bad" (resp. "new").
  *
- * - If one is "bad", it means the user assumed something wrong
+ * - If one is "bad" (resp. "new"), it means the user assumed something wrong
  * and we must exit with a non 0 error code.
- * - If one is "good", that's good, we have nothing to do.
+ * - If one is "good" (resp. "old"), that's good, we have nothing to do.
  * - If one is "skipped", we can't know but we should warn.
  * - If we don't know, we should check it out and ask the user to test.
  */
@@ -825,7 +836,8 @@ static int check_ancestors(const char *prefix)
 
 /*
  * "check_good_are_ancestors_of_bad" checks that all "good" revs are
- * ancestor of the "bad" rev.
+ * ancestor of the "bad" rev. (resp. all "old" revs are ancestor of
+ * the "new" rev).
  *
  * If that's not the case, we need to check the merge bases.
  * If a merge base must be tested by the user, its source code will be
@@ -838,7 +850,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
 	int fd;
 
 	if (!current_bad_sha1)
-		die("a bad revision is needed");
+		die("a %s revision is needed", bisect_term_bad);
 
 	/* Check if file BISECT_ANCESTORS_OK exists. */
 	if (!stat(filename, &st) && S_ISREG(st.st_mode))
@@ -889,6 +901,30 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
 }
 
 /*
+ * The terms used for this bisect session are stocked in
+ * BISECT_TERMS: it can be bad/good or new/old.
+ * We read them and stock them to adapt the messages
+ * accordingly.
+ */
+void read_bisect_terms(void)
+{
+	struct strbuf str = STRBUF_INIT;
+	const char *filename = git_path("BISECT_TERMS");
+	FILE *fp = fopen(filename, "r");
+
+	if (!fp)
+		die_errno("Could not open file '%s'", filename);
+
+	strbuf_getline(&str, fp, '\n');
+	bisect_term_bad = strbuf_detach(&str, NULL);
+	strbuf_getline(&str, fp, '\n');
+	bisect_term_good = strbuf_detach(&str, NULL);
+
+	strbuf_release(&str);
+	fclose(fp);
+}
+
+/*
  * We use the convention that exiting with an exit code 10 means that
  * the bisection process finished successfully.
  * In this case the calling shell script should exit 0.
@@ -898,6 +934,8 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
  */
 int bisect_next_all(const char *prefix, int no_checkout)
 {
+	read_bisect_terms();
+
 	struct rev_info revs;
 	struct commit_list *tried;
 	int reaches = 0, all = 0, nr, steps;
@@ -920,13 +958,14 @@ int bisect_next_all(const char *prefix, int no_checkout)
 
 	if (!revs.commits) {
 		/*
-		 * We should exit here only if the "bad"
+		 * We should exit here only if the "bad" (or "new")
 		 * commit is also a "skip" commit.
 		 */
 		exit_if_skipped_commits(tried, NULL);
 
-		printf("%s was both good and bad\n",
-		       sha1_to_hex(current_bad_sha1));
+		printf("%s was both %s and %s\n",
+		       sha1_to_hex(current_bad_sha1), bisect_term_good,
+		       bisect_term_bad);
 		exit(1);
 	}
 
@@ -941,7 +980,8 @@ int bisect_next_all(const char *prefix, int no_checkout)
 
 	if (!hashcmp(bisect_rev, current_bad_sha1)) {
 		exit_if_skipped_commits(tried, current_bad_sha1);
-		printf("%s is the first bad commit\n", bisect_rev_hex);
+		printf("%s is the first %s commit\n", bisect_rev_hex,
+			bisect_term_bad);
 		show_diff_tree(prefix, revs.commits->item);
 		/* This means the bisection process succeeded. */
 		exit(10);
@@ -953,6 +993,8 @@ int bisect_next_all(const char *prefix, int no_checkout)
 	       "(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
 	       steps, (steps == 1 ? "" : "s"));
 
+	free((char*)bisect_term_bad);
+	free((char*)bisect_term_good);
+
 	return bisect_checkout(bisect_rev_hex, no_checkout);
 }
-
diff --git a/git-bisect.sh b/git-bisect.sh
index 99efbe8..152b4f3 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
+USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run|new|old]'
 LONG_USAGE='git bisect help
 	print this long help message.
 git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
@@ -22,7 +22,15 @@ git bisect replay <logfile>
 git bisect log
 	show bisect log.
 git bisect run <cmd>...
-	use <cmd>... to automatically bisect.
+	use <cmd>... to automatically bisect
+
+When looking for a change in a given property instead of a regression
+you can use
+
+git bisect new [<rev>]
+	mark <rev> as not having the property anymore
+git bisect old [<rev>]
+	mark <rev>... as having the property
 
 Please use "git help bisect" to get the full man page.'
 
@@ -32,6 +40,8 @@ OPTIONS_SPEC=
 
 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+NEW="bad"
+OLD="good"
 
 bisect_head()
 {
@@ -66,7 +76,7 @@ bisect_autostart() {
 
 bisect_start() {
 	#
-	# Check for one bad and then some good revisions.
+	# Check for one bad (or new) and then some good (or old) revisions.
 	#
 	has_double_dash=0
 	for arg; do
@@ -75,6 +85,7 @@ bisect_start() {
 	orig_args=$(git rev-parse --sq-quote "$@")
 	bad_seen=0
 	eval=''
+	start_bad_good=0
 	if test "z$(git rev-parse --is-bare-repository)" != zfalse
 	then
 		mode=--no-checkout
@@ -99,6 +110,16 @@ bisect_start() {
 				die "$(eval_gettext "'\$arg' does not appear to be a valid revision")"
 				break
 			}
+
+			if test -s "$GIT_DIR/BISECT_TERMS"
+			then
+				if $(sed -n 1p "$GIT_DIR/BISECT_TERMS") != 'bad'
+				then
+					die "$(gettext "you are already bisecting in old/new mode")"
+				fi
+			fi
+			start_bad_good=1
+
 			case $bad_seen in
 			0) state='bad' ; bad_seen=1 ;;
 			*) state='good' ;;
@@ -170,6 +191,11 @@ bisect_start() {
 	} &&
 	git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
 	eval "$eval true" &&
+	if test $start_bad_good -eq 1 -a ! -s "$GIT_DIR/BISECT_TERMS"
+	then
+		echo "bad" >"$GIT_DIR/BISECT_TERMS" &&
+		echo "good" >>"$GIT_DIR/BISECT_TERMS"
+	fi &&
 	echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
 	#
 	# Check if we can proceed to the next bisect state.
@@ -184,8 +210,8 @@ bisect_write() {
 	rev="$2"
 	nolog="$3"
 	case "$state" in
-		bad)		tag="$state" ;;
-		good|skip)	tag="$state"-"$rev" ;;
+		bad|new)		tag="$state" ;;
+		good|skip|old)	tag="$state"-"$rev" ;;
 		*)		die "$(eval_gettext "Bad bisect_write argument: \$state")" ;;
 	esac
 	git update-ref "refs/bisect/$tag" "$rev" || exit
@@ -230,12 +256,12 @@ bisect_state() {
 	case "$#,$state" in
 	0,*)
 		die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
-	1,bad|1,good|1,skip)
+	1,bad|1,good|1,skip|1,new|1,old)
 		rev=$(git rev-parse --verify $(bisect_head)) ||
 			die "$(gettext "Bad rev input: $(bisect_head)")"
 		bisect_write "$state" "$rev"
 		check_expected_revs "$rev" ;;
-	2,bad|*,good|*,skip)
+	2,bad|*,good|*,skip|2,new|*,old)
 		shift
 		eval=''
 		for rev in "$@"
@@ -246,8 +272,8 @@ bisect_state() {
 		done
 		eval "$eval"
 		check_expected_revs "$@" ;;
-	*,bad)
-		die "$(gettext "'git bisect bad' can take only one argument.")" ;;
+	*,bad|*,new)
+		die "$(gettext "'git bisect $NEW' can take only one argument.")" ;;
 	*)
 		usage ;;
 	esac
@@ -256,21 +282,21 @@ bisect_state() {
 
 bisect_next_check() {
 	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
+	git show-ref -q --verify refs/bisect/$NEW || missing_bad=t
+	test -n "$(git for-each-ref "refs/bisect/$OLD-*")" || missing_good=t
 
 	case "$missing_good,$missing_bad,$1" in
 	,,*)
-		: have both good and bad - ok
+		: have both good and bad or old and new - ok
 		;;
 	*,)
 		# do not have both but not asked to fail - just report.
 		false
 		;;
-	t,,good)
-		# have bad but not good.  we could bisect although
+	t,,good|t,,old)
+		# have bad (or new) but not good (or old).  we could bisect although
 		# this is less optimum.
-		gettextln "Warning: bisecting only with a bad commit." >&2
+		gettextln "Warning: bisecting only with a $NEW commit." >&2
 		if test -t 0
 		then
 			# TRANSLATORS: Make sure to include [Y] and [n] in your
@@ -280,17 +306,17 @@ bisect_next_check() {
 			read yesno
 			case "$yesno" in [Nn]*) exit 1 ;; esac
 		fi
-		: bisect without good...
+		: bisect without $OLD...
 		;;
 	*)
 
 		if test -s "$GIT_DIR/BISECT_START"
 		then
-			gettextln "You need to give me at least one good and one bad revisions.
+			gettextln "You need to give me at least one good and one bad (or one old and one new) revisions.
 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
 		else
 			gettextln "You need to start by \"git bisect start\".
-You then need to give me at least one good and one bad revisions.
+You then need to give me at least one good and one bad (or one old and one new) revisions.
 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
 		fi
 		exit 1 ;;
@@ -304,7 +330,7 @@ bisect_auto_next() {
 bisect_next() {
 	case "$#" in 0) ;; *) usage ;; esac
 	bisect_autostart
-	bisect_next_check good
+	bisect_next_check $OLD
 
 	# Perform all bisection computation, display and checkout
 	git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
@@ -378,6 +404,7 @@ bisect_clean_state() {
 	rm -f "$GIT_DIR/BISECT_LOG" &&
 	rm -f "$GIT_DIR/BISECT_NAMES" &&
 	rm -f "$GIT_DIR/BISECT_RUN" &&
+	rm -f "$GIT_DIR/BISECT_TERMS" &&
 	# Cleanup head-name if it got left by an old version of git-bisect
 	rm -f "$GIT_DIR/head-name" &&
 	git update-ref -d --no-deref BISECT_HEAD &&
@@ -402,7 +429,7 @@ bisect_replay () {
 		start)
 			cmd="bisect_start $rev"
 			eval "$cmd" ;;
-		good|bad|skip)
+		good|bad|skip|old|new)
 			bisect_write "$command" "$rev" ;;
 		*)
 			die "$(gettext "?? what are you talking about?")" ;;
@@ -436,9 +463,9 @@ exit code \$res from '\$command' is < 0 or >= 128" >&2
 			state='skip'
 		elif [ $res -gt 0 ]
 		then
-			state='bad'
+			state="$NEW"
 		else
-			state='good'
+			state="$OLD"
 		fi
 
 		# We have to use a subshell because "bisect_state" can exit.
@@ -447,7 +474,7 @@ exit code \$res from '\$command' is < 0 or >= 128" >&2
 
 		cat "$GIT_DIR/BISECT_RUN"
 
-		if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
+		if sane_grep "first $NEW commit could be any of" "$GIT_DIR/BISECT_RUN" \
 			> /dev/null
 		then
 			gettextln "bisect run cannot continue any more" >&2
@@ -461,7 +488,7 @@ exit code \$res from '\$command' is < 0 or >= 128" >&2
 			exit $res
 		fi
 
-		if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null
+		if sane_grep "is the first $NEW commit" "$GIT_DIR/BISECT_RUN" > /dev/null
 		then
 			gettextln "bisect run success"
 			exit 0;
@@ -475,18 +502,54 @@ bisect_log () {
 	cat "$GIT_DIR/BISECT_LOG"
 }
 
+get_mode () {
+	if test -s "$GIT_DIR/BISECT_TERMS"
+	then
+		NEW="$(sed -n 1p "$GIT_DIR/BISECT_TERMS")"
+		OLD="$(sed -n 2p "$GIT_DIR/BISECT_TERMS")"
+	fi
+}
+
 case "$#" in
 0)
 	usage ;;
 *)
 	cmd="$1"
+	get_mode
+	case "$cmd" in
+	bad|good|new|old)
+		if test -s "$GIT_DIR/BISECT_TERMS" -a "$cmd" != "$NEW" -a "$cmd" != "$OLD"
+		then
+			die "$(eval_gettext "Invalid command : you're currently in a \$NEW/\$OLD bisect.")"
+		fi
+		case "$cmd" in
+		bad|good)
+			if test ! -s "$GIT_DIR/BISECT_TERMS"
+			then
+				echo "bad" >"$GIT_DIR/BISECT_TERMS" &&
+				echo "good" >>"$GIT_DIR/BISECT_TERMS"
+			fi
+			NEW="bad"
+			OLD="good";;
+		new|old)
+			if test ! -s "$GIT_DIR/BISECT_TERMS"
+			then
+				echo "new" >"$GIT_DIR/BISECT_TERMS" &&
+				echo "old" >>"$GIT_DIR/BISECT_TERMS"
+			fi
+			NEW="new"
+			OLD="old";;
+
+
+		esac;;
+	esac
 	shift
 	case "$cmd" in
 	help)
 		git bisect -h ;;
 	start)
 		bisect_start "$@" ;;
-	bad|good)
+	bad|good|new|old)
 		bisect_state "$cmd" "$@" ;;
 	skip)
 		bisect_skip "$@" ;;
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 72e28ee..28a9c95 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -741,6 +741,39 @@ test_expect_success 'bisect: demonstrate identification of damage boundary' "
 		test \$rc = 0' &&
 	check_same BROKEN_HASH6 bisect/bad &&
 	git bisect reset
+	git checkout master
+
 "
 
+test_expect_success 'bisect starts with only one new' '
+	git bisect reset &&
+	git bisect start &&
+	git bisect new $HASH4 &&
+	git bisect next
+'
+test_expect_success 'bisect does not start with only one old' '
+	git bisect reset &&
+	git bisect start &&
+	git bisect old $HASH1 || return 1
+	test_must_fail git bisect next
+
+'
+
+test_expect_success 'bisect start with one new and old' '
+	git bisect reset &&
+	git bisect start &&
+	git bisect old $HASH1 &&
+	git bisect new $HASH4 &&
+	git bisect new &&
+	git bisect new >bisect_result &&
+	grep "$HASH2 is the first new commit" bisect_result &&
+	git bisect reset
+'
+
+test_expect_success 'bisect cannot mix old/new and good/bad' '
+	git bisect start &&
+	git bisect bad $HASH4 &&
+	test_must_fail git bisect old $HASH1
+'
+
 test_done
-- 
1.7.8

             reply	other threads:[~2012-06-12  2:41 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-12  2:03 Valentin Duperray [this message]
2012-06-12  5:25 ` [PATCH] git bisect old/new Christian Couder
2012-06-12  5:43   ` Junio C Hamano
2012-06-12 19:41     ` Phil Hord
2012-06-13 10:12       ` Christian Couder
2012-06-13 17:30       ` Junio C Hamano
2012-06-12 22:56 ` [PATCHv2] " Valentin Duperray
2012-06-12 23:54   ` Junio C Hamano
2012-06-13 18:06     ` duperrav
2012-06-14  9:56       ` Christian Couder
2012-06-14 17:34         ` Junio C Hamano
2012-06-15 20:20           ` Phil Hord
2012-06-15 21:06             ` Junio C Hamano
2012-06-13 10:05   ` Christian Couder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1339466625-17461-1-git-send-email-Valentin.Duperray@ensimag.imag.fr \
    --to=valentin.duperray@ensimag.imag.fr \
    --cc=Franck.Jonas@ensimag.imag.fr \
    --cc=Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr \
    --cc=Lucien.Kong@ensimag.imag.fr \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=Thomas.Nguy@ensimag.imag.fr \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).