[RFC/PATCH]: reverse bisect v 2.0

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

 



The bugfix command works like the previous git bisect start --reverse.
It switch the meaning of good(s) and bad from the default regression
search approach to the bugfix one.

I don't like adding more new subcommands into bisect, so I decided to
not add ideas I have found on this mailinglist, like 'git bisect
regression' or 'yes', 'no', 'fixed', 'unfixed' or whatever.

The git bisect start/bugfix good/bad/skip log replay and vizualize were
tested (however on simple linear example).

The missing points:
 * git-bisect--helper has the "bad" hardcoded, so the commit fixing a
   bug is reffered as a bad one
 * in git bisect vizualize, the good commit is shown under refs/bad in
   gitk (however that's the same problem if user reverse the usage of
   good/bad itself).
 * documentation and tests of course

Regards
Michal Vyskocil
---
 bisect.c      |    2 +-
 git-bisect.sh |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/bisect.c b/bisect.c
index c7b7d79..2eb34db 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 git bisect bugfix to switch the default bisect logic.\n");
 	exit(1);
 }
 
diff --git a/git-bisect.sh b/git-bisect.sh
index 2524060..6959cf8 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -4,7 +4,9 @@ USAGE='[help|start|bad|good|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.
+	reset bisect state and start bisection to find a regression.
+git bisect bugfix [--no-checkout] [<good> [<bad>...]] [--] [<pathspec>...]
+	reset bisect state and start bisection to find a bugfix.
 git bisect bad [<rev>]
 	mark <rev> a known-bad revision.
 git bisect good [<rev>...]
@@ -33,6 +35,29 @@ 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"
 
+setup_bugfix_mode() {
+	/bin/touch "$GIT_DIR/BISECT_BUGFIX"
+}
+
+bisect_bugfix_mode() {
+	test -f "$GIT_DIR/BISECT_BUGFIX"
+}
+
+bisect_check_state() {
+
+	if bisect_bugfix_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 +94,15 @@ bisect_start() {
 	# Check for one bad and then some good revisions.
 	#
 	has_double_dash=0
+	#
+	# Exchange the internal meaning of good/bad allowing bisect to find
+	# a commit fixing a bug, not "only" the one causes a regression
+	#
+	cmd="start"
+	if test -n "$1" && test "$1" = "bugfix"; then
+		cmd="bugfix"
+		shift 1
+	fi
 	for arg; do
 		case "$arg" in --) has_double_dash=1; break ;; esac
 	done
@@ -99,10 +133,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 $cmd = "bisect"; 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
 			;;
@@ -169,7 +210,10 @@ 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
+	echo "git bisect $cmd$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
+	if test $cmd = "bugfix"; then
+		setup_bugfix_mode || exit
+	fi
 	#
 	# Check if we can proceed to the next bisect state.
 	#
@@ -225,7 +269,7 @@ bisect_skip() {
 
 bisect_state() {
 	bisect_autostart
-	state=$1
+	state=$(bisect_check_state $1)
 	case "$#,$state" in
 	0,*)
 		die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
@@ -377,6 +421,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_BUGFIX" &&
 	# 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 &&
@@ -401,7 +446,12 @@ bisect_replay () {
 		start)
 			cmd="bisect_start $rev"
 			eval "$cmd" ;;
+		bugfix)
+			cmd="bisect_start 'bugfix' $rev"
+			setup_bugfix_mode || exit
+			eval "$cmd" ;;
 		good|bad|skip)
+			command=$(bisect_check_state $1)
 			bisect_write "$command" "$rev" ;;
 		*)
 			die "$(gettext "?? what are you talking about?")" ;;
@@ -485,6 +535,8 @@ case "$#" in
 		git bisect -h ;;
 	start)
 		bisect_start "$@" ;;
+	bugfix)
+		bisect_start "bugfix" "$@" ;;
 	bad|good)
 		bisect_state "$cmd" "$@" ;;
 	skip)
-- 
1.7.6.3

Attachment: pgpTEyzsomF4H.pgp
Description: PGP signature


[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]