git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v10.1 7/7] bisect: allow any terms set by user

From
Matthieu Moy <matthieu.moy@imag.fr>
Date
Jun 26, 2015, 20:39 UTC
Message-ID
<1435351183-27100-1-git-send-email-Matthieu.Moy@imag.fr>
In-Reply-To
<xmqqsi9etjwy.fsf@gitster.dls.corp.google.com>
From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>

Introduction of the git bisect terms command. The user can set his own terms. It will work exactly like before. The terms must be set before the start.

Signed-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>
Signed-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
Junio C Hamano <gitster@pobox.com> writes:
Show 5 quoted lines
> Matthieu Moy <Matthieu.Moy@imag.fr> writes:
>
>> + git bisect terms <term-old> <term-new>
>
> I think this is the other way around.
Indeed.
The test scripts were messed up, I sent too quickly after refactoring.

There was also a small bug: "git bisect reset" was not reseting the terms when ran before "git bisect start".

My branch https://github.com/moy/git/commits/bisect-terms is up to date in case the individual resend are too messy. I can also resend later, but I was too ashamed of my bugs with tests to leave it as is ;-).

 Documentation/git-bisect.txt | 36 +++++++++++++++++++-
 git-bisect.sh                | 67 +++++++++++++++++++++++++++++++++---
 t/t6030-bisect-porcelain.sh  | 81 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index abaf462..28f6104 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -19,6 +19,7 @@ on the subcommand:
  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
  git bisect (bad|new) [<rev>]
  git bisect (good|old) [<rev>...]
+ git bisect terms <term-new> <term-old>
  git bisect skip [(<rev>|<range>)...]
  git bisect reset [<commit>]
  git bisect visualize
@@ -40,7 +41,7 @@ In fact, `git bisect` can be used to find the commit that changed
 *any* property of your project; e.g., the commit that fixed a bug, or
 the commit that caused a benchmark's performance to improve. To
 support this more general usage, the terms "old" and "new" can be used
-in place of "good" and "bad". See
+in place of "good" and "bad", or you can choose your own terms. See
 section "Alternate terms" below for more information.
 
 Basic bisect commands: start, bad, good
@@ -157,6 +158,31 @@ git bisect new [<rev>...]
 
 to indicate that it was after.
 
+If you would like to use your own terms instead of "bad"/"good" or
+"new"/"old", you can choose any names you like by typing
+
+------------------------------------------------
+git bisect terms <term-new> <term-old>
+------------------------------------------------
+
+before starting a bisection session. For example, if you are looking
+for a commit that introduced a performance regression, you might use
+
+------------------------------------------------
+git bisect terms slow fast
+------------------------------------------------
+
+Or if you are looking for the commit that fixed a bug, you might use
+
+------------------------------------------------
+git bisect terms fixed broken
+------------------------------------------------
+
+Only the bisection following the `git bisect terms` will use the
+terms. If you mistyped one of the terms you can do again `git bisect
+terms <term-new> <term-old>`, but that is possible only before you
+start the bisection.
+
 Bisect visualize
 ~~~~~~~~~~~~~~~~
 
@@ -440,6 +466,14 @@ $ git bisect start
 $ git bisect new HEAD    # current commit is marked as new
 $ git bisect old HEAD~10 # the tenth commit from now is marked as old
 ------------
++
+or:
+------------
+$ git bisect terms fixed broken
+$ git bisect start
+$ git bisect fixed
+$ git bisect broken HEAD~10
+------------
 
 Getting help
 ~~~~~~~~~~~~
diff --git a/git-bisect.sh b/git-bisect.sh
index 5769eaf..cf07a91 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'
+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'
 LONG_USAGE='git bisect help
 	print this long help message.
 git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
@@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]
 git bisect (good|old) [<rev>...]
 	mark <rev>... known-good revisions/
 		revisions before change in a given property.
+git bisect terms <term-new> <term-old>
+	set up <term-new> and <term-old> as terms (default: bad, good)
 git bisect skip [(<rev>|<range>)...]
 	mark <rev>... untestable revisions.
 git bisect next
@@ -80,6 +82,16 @@ bisect_start() {
 	bad_seen=0
 	eval=''
 	must_write_terms=0
+	must_log_terms=0
+	if test -s "$GIT_DIR/BISECT_TERMS"
+	then
+		# We're going to restart from a clean state and the
+		# file will be deleted. Record the old state in
+		# variables and restore it below.
+		must_write_terms=1
+		must_log_terms=1
+		get_terms
+	fi
 	if test "z$(git rev-parse --is-bare-repository)" != zfalse
 	then
 		mode=--no-checkout
@@ -185,7 +197,12 @@ bisect_start() {
 	eval "$eval true" &&
 	if test $must_write_terms -eq 1
 	then
-		write_terms "$NAME_BAD" "$NAME_GOOD"
+		write_terms "$NAME_BAD" "$NAME_GOOD" &&
+		if test $must_log_terms -eq 1
+		then
+			echo "git bisect terms $NAME_BAD $NAME_GOOD" \
+			    >>"$GIT_DIR/BISECT_LOG"
+		fi
 	fi &&
 	echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
 	#
@@ -387,6 +404,8 @@ bisect_visualize() {
 bisect_reset() {
 	test -s "$GIT_DIR/BISECT_START" || {
 		gettextln "We are not bisecting."
+		# We may still have leftovers like BISECT_TERMS
+		bisect_clean_state
 		return
 	}
 	case "$#" in
@@ -449,6 +468,8 @@ bisect_replay () {
 			eval "$cmd" ;;
 		"$NAME_GOOD"|"$NAME_BAD"|skip)
 			bisect_write "$command" "$rev" ;;
+		terms)
+			bisect_terms $rev ;;
 		*)
 			die "$(gettext "?? what are you talking about?")" ;;
 		esac
@@ -533,13 +554,22 @@ get_terms () {
 write_terms () {
 	NAME_BAD=$1
 	NAME_GOOD=$2
+	check_term_format "$NAME_BAD"
+	check_term_format "$NAME_GOOD"
 	printf '%s\n%s\n' "$NAME_BAD" "$NAME_GOOD" >"$GIT_DIR/BISECT_TERMS"
 }
 
+check_term_format () {
+	term=$1
+	git check-ref-format refs/bisect/"$term" ||
+	die "$(eval_gettext "'\$term' is not a valid term")"
+}
+
 check_and_set_terms () {
 	cmd="$1"
 	case "$cmd" in
-	bad|good|new|old)
+	skip|start|terms) ;;
+	*)
 		if test -s "$GIT_DIR/BISECT_TERMS" && test "$cmd" != "$NAME_BAD" && test "$cmd" != "$NAME_GOOD"
 		then
 			die "$(eval_gettext "Invalid command: you're currently in a \$NAME_BAD/\$NAME_GOOD bisect.")"
@@ -568,6 +598,33 @@ bisect_voc () {
 	esac
 }
 
+bisect_terms () {
+	case "$#" in
+	0)
+		if test -s "$GIT_DIR/BISECT_TERMS"
+		then
+			get_terms
+			gettextln "Your current terms are $NAME_GOOD for the old state
+and $NAME_BAD for the new state."
+		else
+			die "$(gettext "No terms defined.")"
+		fi ;;
+	2)
+		if ! test -s "$GIT_DIR/BISECT_START"
+		then
+			write_terms "$1" "$2"
+			echo "git bisect terms $NAME_BAD $NAME_GOOD" >>"$GIT_DIR/BISECT_LOG" || exit
+		else
+			die "$(gettext "A bisection has already started, and you can't change terms in the middle of it.
+Use 'git bisect terms' to see the current terms.
+Otherwise, to start a new bisection with new terms, please use
+'git bisect reset' and set the terms before the start")"
+		fi ;;
+	*)
+		usage ;;
+	esac
+}
+
 case "$#" in
 0)
 	usage ;;
@@ -580,7 +637,7 @@ case "$#" in
 		git bisect -h ;;
 	start)
 		bisect_start "$@" ;;
-	bad|good|new|old)
+	bad|good|new|old|"$NAME_BAD"|"$NAME_GOOD")
 		bisect_state "$cmd" "$@" ;;
 	skip)
 		bisect_skip "$@" ;;
@@ -597,6 +654,8 @@ case "$#" in
 		bisect_log ;;
 	run)
 		bisect_run "$@" ;;
+	terms)
+		bisect_terms "$@" ;;
 	*)
 		usage ;;
 	esac
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 983c503..eb8cc80 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -797,4 +797,85 @@ test_expect_success 'bisect cannot mix old/new and good/bad' '
 	test_must_fail git bisect old $HASH1
 '
 
+test_expect_success 'bisect start with one term1 and term2' '
+	git bisect reset &&
+	git bisect terms term1 term2 &&
+	git bisect start &&
+	git bisect term2 $HASH1 &&
+	git bisect term1 $HASH4 &&
+	git bisect term1 &&
+	git bisect term1 >bisect_result &&
+	grep "$HASH2 is the first term1 commit" bisect_result &&
+	git bisect log >log_to_replay.txt &&
+	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 &&
+	git bisect reset
+'
+
+test_expect_success 'bisect start term1 term2' '
+	git bisect reset &&
+	git bisect terms term1 term2 &&
+	git bisect start $HASH4 $HASH1 &&
+	git bisect term1 &&
+	git bisect term1 >bisect_result &&
+	grep "$HASH2 is the first term1 commit" bisect_result &&
+	git bisect log >log_to_replay.txt &&
+	git bisect reset
+'
+
+test_expect_success 'bisect cannot mix terms' '
+	git bisect reset &&
+	git bisect terms a b &&
+	git bisect terms term1 term2 &&
+	git bisect start $HASH4 $HASH1 &&
+	test_must_fail git bisect a &&
+	test_must_fail git bisect b &&
+	test_must_fail git bisect bad &&
+	test_must_fail git bisect good &&
+	test_must_fail git bisect new &&
+	test_must_fail git bisect old
+'
+
+test_expect_success 'bisect terms rejects invalid terms' '
+	git bisect reset &&
+	test_must_fail git bisect terms invalid..term term2 &&
+	test_must_fail git bisect terms term1 invalid..term &&
+	test_path_is_missing .git/BISECT_TERMS
+'
+
+test_expect_success 'bisect terms needs 0 or 2 arguments' '
+	git bisect reset &&
+	test_must_fail git bisect terms only-one &&
+	test_must_fail git bisect terms 1 2 3 &&
+	test_must_fail git bisect terms 2>actual &&
+	echo "No terms defined." >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'bisect terms does store terms' '
+	git bisect reset &&
+	git bisect terms one two &&
+	git bisect terms >actual &&
+	cat <<-EOF >expected &&
+	Your current terms are two for the old state
+	and one for the new state.
+	EOF
+	test_cmp expected actual'
+
+test_expect_success 'bisect start keeps defined terms' '
+	git bisect reset &&
+	git bisect terms one two &&
+	git bisect start &&
+	git bisect terms >actual &&
+	cat <<-EOF >expected &&
+	Your current terms are two for the old state
+	and one for the new state.
+	EOF
+	test_cmp expected actual
+'
+
 test_done
-- 
2.5.0.rc0.7.g0f487ca.dirty
Previous: Junio C HamanoNext: Junio C Hamano
Message 14 of 38 in “bisect terms”
  1. 0/7 bisect termsMatthieu Moy, Jun 26, 2015
  2. 1/7 bisect: correction of typoMatthieu Moy, Jun 26, 2015
  3. 2/7 Documentation/bisect: move getting help section to the endMatthieu Moy, Jun 26, 2015
  4. 3/7 Documentation/bisect: revise overall contentMatthieu Moy, Jun 26, 2015
  5. 4/7 bisect: replace hardcoded "bad|good" by variablesMatthieu Moy, Jun 26, 2015
  6. 5/7 bisect: simplify the addition of new bisect termsMatthieu Moy, Jun 26, 2015
  7. Christian CouderJun 26, 2015
  8. 5/7 bisect: simplify the addition of new bisect termsMatthieu Moy, Jun 26, 2015
  9. Junio C HamanoJun 26, 2015
  10. Matthieu MoyJun 26, 2015
  11. 6/7 bisect: add the terms old/newMatthieu Moy, Jun 26, 2015
  12. 7/7 bisect: allow any terms set by userMatthieu Moy, Jun 26, 2015
  13. Junio C HamanoJun 26, 2015
  14. 7/7 bisect: allow any terms set by userMatthieu Moy, Jun 26, 2015
  15. Junio C HamanoJun 26, 2015
  16. Christian CouderJun 27, 2015
  17. Junio C HamanoJun 27, 2015
  18. Christian CouderJun 27, 2015
  19. Matthieu MoyJun 27, 2015
  20. Junio C HamanoJun 27, 2015
  21. Matthieu MoyJun 29, 2015
  22. Junio C HamanoJun 29, 2015
  23. Michael HaggertyJun 28, 2015
  24. Junio C HamanoJun 28, 2015
  25. Michael HaggertyJun 28, 2015
  26. Junio C HamanoJun 28, 2015
  27. Michael HaggertyJun 28, 2015
  28. Junio C HamanoJun 28, 2015
  29. Matthieu MoyJun 29, 2015
  30. Junio C HamanoJun 29, 2015
  31. Christian CouderJun 29, 2015
  32. Matthieu MoyJun 29, 2015
  33. Christian CouderJun 29, 2015
  34. Matthieu MoyJun 29, 2015
  35. Christian CouderJun 29, 2015
  36. Matthieu MoyJun 29, 2015
  37. Christian CouderJun 26, 2015
  38. Matthieu MoyJun 26, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.