Hi all, Following proposed patch try to implement reverse mode for git bisect. The git bisect command is written in the regression-finding in mind. IOW it expects the good commit is older than the later one, which caused a regression. However common usage for (at least) package maintainer is not to find a regression and fix it. The main task it to identify a bugfix!. In this case git bisect is still helpfull as it reduces a time a lot, but user needs to exchange the good<->bad in his mind, which is confusing and in case there are delays in the work, it's trivial to forgot that I have to type git bisect good, when I'm in the bad revision. This simple patch try to address the problem of poor package maintainer's brain and introduces --reverse argument for the git bisect start command. In this mode, bisect internally exchange the behavior of good/bad itself, so there's no need to do it manually. I did some basic testing and git bisect start --reverse HEAD~999 HEAD git bisect good/bad/skip/run really works well, allowing user to identify a first good commit instead of the first bad one. I did not test other commands like visualize or replay. What do you think about it? Do you see other problems I'm not aware of? --- bisect.c | 2 +- git-bisect.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/bisect.c b/bisect.c index c7b7d79..33aaeaa 100644 --- a/bisect.c +++ b/bisect.c @@ -768,7 +768,7 @@ static void handle_bad_merge_base(void) fprintf(stderr, "Some good revs are not ancestor of the bad rev.\n" "git bisect cannot work properly in this case.\n" - "Maybe you mistake good and bad revs?\n"); + "Try --reverse to switch the bisect logic.\n"); exit(1); } diff --git a/git-bisect.sh b/git-bisect.sh index 2524060..5c95f25 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -33,6 +33,25 @@ 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" +bisect_reverse_mode() { + test -f "$GIT_DIR/BISECT_REVERSE" +} + +bisect_reverse_state() { + + if bisect_reverse_mode; then + if test "$1" = "good"; then + echo "bad" + return 0 + elif test "$1" = "bad"; then + echo "good" + return 0 + fi + fi + + echo $1 +} + bisect_head() { if test -f "$GIT_DIR/BISECT_HEAD" @@ -69,6 +88,11 @@ bisect_start() { # Check for one bad and then some good revisions. # has_double_dash=0 + # + # Exchange the internal meainng of good/bad allowing bisect to find + # a commit fixing a bug, not "only" the one causes a regression + # + reverse_mode=1 for arg; do case "$arg" in --) has_double_dash=1; break ;; esac done @@ -91,6 +115,9 @@ bisect_start() { --no-checkout) mode=--no-checkout shift ;; + --reverse) + reverse_mode=0 + shift ;; --*) die "$(eval_gettext "unrecognised option: '\$arg'")" ;; *) @@ -99,10 +126,17 @@ bisect_start() { die "$(eval_gettext "'\$arg' does not appear to be a valid revision")" break } - case $bad_seen in - 0) state='bad' ; bad_seen=1 ;; - *) state='good' ;; - esac + if test $reverse_mode -ne 0; then + case $bad_seen in + 0) state='bad' ; bad_seen=1 ;; + *) state='good' ;; + esac + else + case $bad_seen in + 0) state='good' ; bad_seen=1 ;; + *) state='bad' ;; + esac + fi eval="$eval bisect_write '$state' '$rev' 'nolog' &&" shift ;; @@ -170,6 +204,9 @@ bisect_start() { git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" && eval "$eval true" && echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit + if test $reverse_mode -eq 0; then + /bin/touch "$GIT_DIR/BISECT_REVERSE" || exit + fi # # Check if we can proceed to the next bisect state. # @@ -225,7 +262,7 @@ bisect_skip() { bisect_state() { bisect_autostart - state=$1 + state=$(bisect_reverse_state $1) case "$#,$state" in 0,*) die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;; @@ -377,6 +414,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_REVERSE" && # 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,6 +440,7 @@ bisect_replay () { cmd="bisect_start $rev" eval "$cmd" ;; good|bad|skip) + command=$(bisect_reverse_state $1) bisect_write "$command" "$rev" ;; *) die "$(gettext "?? what are you talking about?")" ;; -- 1.7.6.3
Attachment:
pgpQDeOkzt8WL.pgp
Description: PGP signature