bisect: add the terms old/new
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 a certain property must be marked as `new` and the ones which do not 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 rev-list --bisect does not treat the revs/bisect/new and revs/bisect/old-SHA1 files. Old discussions: - http://thread.gmane.org/gmane.comp.version-control.git/86063 introduced bisect fix unfixed to find fix. - http://thread.gmane.org/gmane.comp.version-control.git/182398 discussion around bisect yes/no or old/new. - http://thread.gmane.org/gmane.comp.version-control.git/199758 last discussion and reviews New discussions: - http://thread.gmane.org/gmane.comp.version-control.git/271320 ( v2 1/7-4/7 ) - http://comments.gmane.org/gmane.comp.version-control.git/271343 ( v2 5/7-7/7 ) Signed-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr> Signed-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr> Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr> Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr> Signed-off-by: Lucien Kong <Lucien.Kong@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@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
fe67687bb1
commit
21e5cfd8b3
@ -17,8 +17,8 @@ The command takes various subcommands, and different options depending
|
||||
on the subcommand:
|
||||
|
||||
git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
|
||||
git bisect bad [<rev>]
|
||||
git bisect good [<rev>...]
|
||||
git bisect (bad|new) [<rev>]
|
||||
git bisect (good|old) [<rev>...]
|
||||
git bisect skip [(<rev>|<range>)...]
|
||||
git bisect reset [<commit>]
|
||||
git bisect visualize
|
||||
@ -36,6 +36,13 @@ whether the selected commit is "good" or "bad". It continues narrowing
|
||||
down the range until it finds the exact commit that introduced the
|
||||
change.
|
||||
|
||||
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
|
||||
section "Alternate terms" below for more information.
|
||||
|
||||
Basic bisect commands: start, bad, good
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -111,6 +118,45 @@ bad revision, while `git bisect reset HEAD` will leave you on the
|
||||
current bisection commit and avoid switching commits at all.
|
||||
|
||||
|
||||
Alternate terms
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes you are not looking for the commit that introduced a
|
||||
breakage, but rather for a commit that caused a change between some
|
||||
other "old" state and "new" state. For example, you might be looking
|
||||
for the commit that introduced a particular fix. Or you might be
|
||||
looking for the first commit in which the source-code filenames were
|
||||
finally all converted to your company's naming standard. Or whatever.
|
||||
|
||||
In such cases it can be very confusing to use the terms "good" and
|
||||
"bad" to refer to "the state before the change" and "the state after
|
||||
the change". So instead, you can use the terms "old" and "new",
|
||||
respectively, in place of "good" and "bad". (But note that you cannot
|
||||
mix "good" and "bad" with "old" and "new" in a single session.)
|
||||
|
||||
In this more general usage, you provide `git bisect` with a "new"
|
||||
commit has some property and an "old" commit that doesn't have that
|
||||
property. Each time `git bisect` checks out a commit, you test if that
|
||||
commit has the property. If it does, mark the commit as "new";
|
||||
otherwise, mark it as "old". When the bisection is done, `git bisect`
|
||||
will report which commit introduced the property.
|
||||
|
||||
To use "old" and "new" instead of "good" and bad, you must run `git
|
||||
bisect start` without commits as argument and then run the following
|
||||
commands to add the commits:
|
||||
|
||||
------------------------------------------------
|
||||
git bisect old [<rev>]
|
||||
------------------------------------------------
|
||||
|
||||
to indicate that a commit was before the sought change, or
|
||||
|
||||
------------------------------------------------
|
||||
git bisect new [<rev>...]
|
||||
------------------------------------------------
|
||||
|
||||
to indicate that it was after.
|
||||
|
||||
Bisect visualize
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -387,6 +433,14 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit
|
||||
has at least one parent whose reachable graph is fully traversable in the sense
|
||||
required by 'git pack objects'.
|
||||
|
||||
* Look for a fix instead of a regression in the code
|
||||
+
|
||||
------------
|
||||
$ 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
|
||||
------------
|
||||
|
||||
Getting help
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
11
bisect.c
11
bisect.c
@ -746,6 +746,11 @@ static void handle_bad_merge_base(void)
|
||||
"This means the bug has been fixed "
|
||||
"between %s and [%s].\n",
|
||||
bad_hex, bad_hex, good_hex);
|
||||
} else if (!strcmp(term_bad, "new") && !strcmp(term_good, "old")) {
|
||||
fprintf(stderr, "The merge base %s is new.\n"
|
||||
"The property has changed "
|
||||
"between %s and [%s].\n",
|
||||
bad_hex, bad_hex, good_hex);
|
||||
} else {
|
||||
fprintf(stderr, "The merge base %s is %s.\n"
|
||||
"This means the first '%s' commit is "
|
||||
@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb)
|
||||
}
|
||||
|
||||
/*
|
||||
* "check_merge_bases" checks that merge bases are not "bad".
|
||||
* "check_merge_bases" checks that merge bases are not "bad" (or "new").
|
||||
*
|
||||
* - If one is "bad", it means the user assumed something wrong
|
||||
* - If one is "bad" (or "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" (or "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.
|
||||
*/
|
||||
|
@ -1,14 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
|
||||
USAGE='[help|start|bad|good|new|old|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>...]
|
||||
reset bisect state and start bisection.
|
||||
git bisect bad [<rev>]
|
||||
mark <rev> a known-bad revision.
|
||||
git bisect good [<rev>...]
|
||||
mark <rev>... known-good revisions.
|
||||
git bisect (bad|new) [<rev>]
|
||||
mark <rev> a known-bad revision/
|
||||
a revision after change in a given property.
|
||||
git bisect (good|old) [<rev>...]
|
||||
mark <rev>... known-good revisions/
|
||||
revisions before change in a given property.
|
||||
git bisect skip [(<rev>|<range>)...]
|
||||
mark <rev>... untestable revisions.
|
||||
git bisect next
|
||||
@ -294,7 +296,7 @@ bisect_next_check() {
|
||||
false
|
||||
;;
|
||||
t,,"$TERM_GOOD")
|
||||
# have bad but not good. we could bisect although
|
||||
# have bad (or new) but not good (or old). we could bisect although
|
||||
# this is less optimum.
|
||||
eval_gettextln "Warning: bisecting only with a \$TERM_BAD commit." >&2
|
||||
if test -t 0
|
||||
@ -587,14 +589,20 @@ check_and_set_terms () {
|
||||
write_terms bad good
|
||||
fi
|
||||
;;
|
||||
new|old)
|
||||
if ! test -s "$GIT_DIR/BISECT_TERMS"
|
||||
then
|
||||
write_terms new old
|
||||
fi
|
||||
;;
|
||||
esac ;;
|
||||
esac
|
||||
}
|
||||
|
||||
bisect_voc () {
|
||||
case "$1" in
|
||||
bad) echo "bad" ;;
|
||||
good) echo "good" ;;
|
||||
bad) echo "bad|new" ;;
|
||||
good) echo "good|old" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -610,7 +618,7 @@ case "$#" in
|
||||
git bisect -h ;;
|
||||
start)
|
||||
bisect_start "$@" ;;
|
||||
bad|good|"$TERM_BAD"|"$TERM_GOOD")
|
||||
bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
|
||||
bisect_state "$cmd" "$@" ;;
|
||||
skip)
|
||||
bisect_skip "$@" ;;
|
||||
|
@ -759,4 +759,42 @@ test_expect_success '"git bisect bad HEAD" behaves as "git bisect bad"' '
|
||||
git bisect reset
|
||||
'
|
||||
|
||||
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 &&
|
||||
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 log >log_to_replay.txt &&
|
||||
git bisect reset
|
||||
'
|
||||
|
||||
test_expect_success 'bisect replay with old and new' '
|
||||
git bisect replay log_to_replay.txt >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
|
||||
|
Loading…
Reference in New Issue
Block a user