[PATCH v3] bisect: teach "skip" to accept a range using "-r|--range" option

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

 



The current "git bisect skip" syntax is "git bisect skip [<rev>...]",
so it's already possible to skip a range of revisions using
something like:

$ git bisect skip $(git rev-list A..B)

where A and B are the bounds of the range of commits we want to skip.
In this case A itself will not be skipped, but B will be, because
that's how "git rev-list" works.

This patch teaches "git bisect skip" to accept:

$ git bisect skip --range=A,B

or:

$ git bisect skip -r A,B

to skip the whole range of commits between A included and B included.

Because we believe that users, in most cases, will want the first
bound to be skipped too.

If either A or B is ommited, HEAD will be used instead.

This is done by expanding each range argument using:

git rev-list "${B:-HEAD}" --not $(git rev-parse "${A:-HEAD}^@")

So the following command:

$ git bisect skip A -r B,C D E --range=F, --range ,G

should work as expected.

Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx>
---
 Documentation/git-bisect.txt |   30 +++++++++++++++++++++++-
 git-bisect.sh                |   52 ++++++++++++++++++++++++++++++++++++++++-
 t/t6030-bisect-porcelain.sh  |   10 +++++++-
 3 files changed, 88 insertions(+), 4 deletions(-)

	Junio wrote:
	>
	> Although I fully realize that the established semantics of A..B in git is
	> bottom-exclusive, top-inclusive, and this suggestion breaks the UI
	> uniformity by deviating from that convention, I have to wonder if it would
	> be more useful if you let the bottom commit (A in your example) also be
	> skipped.

	I agree that it would be perhaps more usefull to skip the bottom commit.
	But in this case I think we should not use the .. notation as it would be
	inconsistent. So here is a patch that adds an all inclusive "-r|--range"
	option.

	This patch adds some documentation and a test case too.

	After coming up with this patch, I saw that the previous version has
	already been merged into "next" and "master", but perhaps it can be reverted
	and this version applied. Otherwise if the previous version is preferred, I
	will come up with another patch to just add some documentation and tests on
	top of the previous version.

diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 39034ec..86f6ad2 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -19,7 +19,7 @@ on the subcommand:
  git bisect start [<bad> [<good>...]] [--] [<paths>...]
  git bisect bad [<rev>]
  git bisect good [<rev>...]
- git bisect skip [<rev>...]
+ git bisect skip [(<rev>|<range>)...]
  git bisect reset [<branch>]
  git bisect visualize
  git bisect replay <logfile>
@@ -164,6 +164,34 @@ But computing the commit to test may be slower afterwards and git may
 eventually not be able to tell the first bad among a bad and one or
 more "skip"ped commits.
 
+You can even skip a range of commits, instead of just one commit,
+using option -r|--range. For example:
+
+------------
+$ git bisect skip --range=v2.5,v2.6
+------------
+
+or:
+
+------------
+$ git bisect skip -r v2.5,v2.6
+------------
+
+would mean that no commit between versions 2.5 included and 2.6
+included can be tested.
+
+Note that you must take care that the first commit in the given range
+is an ancestor of the second commit.
+
+Also note that if you don't want to skip the first commit of a range
+you can use something like:
+
+------------
+$ git bisect skip $(git rev-list v2.5..v2.6)
+------------
+
+and the commit pointed to by v2.5 will not be skipped.
+
 Cutting down bisection by giving more parameters to bisect start
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/git-bisect.sh b/git-bisect.sh
index 0d0e278..29a5c2e 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -9,7 +9,7 @@ git bisect bad [<rev>]
         mark <rev> a known-bad revision.
 git bisect good [<rev>...]
         mark <rev>... known-good revisions.
-git bisect skip [<rev>...]
+git bisect skip [(<rev>|<range>)...]
         mark <rev>... untestable revisions.
 git bisect next
         find next bisection to test and check it out.
@@ -191,6 +191,52 @@ check_expected_revs() {
 	done
 }
 
+list_range() {
+	case "$1" in
+	*,*) ;; # Ok
+	*) die "Bad range: $1" ;;
+	esac
+
+	_A=$(expr "z$1" : 'z\([^,]*\),.*')
+	_B=$(expr "z$1" : 'z[^,]*,\(.*\)')
+
+	#
+	# We want a range with both bounds included.
+	# ("git rev-list ^A B" would exclude commit A.)
+	# This means we want to exclude starting from the parents of _A,
+	# not starting from _A itself.
+	#
+	git rev-list "${_B:-HEAD}" --not $(git rev-parse "${_A:-HEAD}^@")
+}
+
+bisect_skip() {
+        all=''
+	while test $# != 0
+	do
+		case "$1" in
+		-r|--range*)
+			case "$#,$1" in
+			*,*=*)
+				range=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
+			1,*)
+				die "Bad or incomplete range: $1" ;;
+			*)
+				range="$2"; shift ;;
+			esac
+			revs=$(list_range "$range") ||
+				die "Bad rev input: $1"
+			;;
+		*)
+			revs="'$arg'"
+			;;
+		esac
+		shift
+		all="$all $revs"
+        done
+        bisect_state 'skip' $all
+}
+
+
 bisect_state() {
 	bisect_autostart
 	state=$1
@@ -630,8 +676,10 @@ case "$#" in
         git bisect -h ;;
     start)
         bisect_start "$@" ;;
-    bad|good|skip)
+    bad|good)
         bisect_state "$cmd" "$@" ;;
+    skip)
+        bisect_skip "$@" ;;
     next)
         # Not sure we want "next" at the UI level anymore.
         bisect_next "$@" ;;
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 85fa39c..e76546c 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -313,8 +313,16 @@ test_expect_success 'bisect run & skip: find first bad' '
 	grep "$HASH6 is first bad commit" my_bisect_log.txt
 '
 
-test_expect_success 'bisect starting with a detached HEAD' '
+test_expect_success 'bisect skip range' '
+	git bisect reset &&
+	git bisect start $HASH7 $HASH1 &&
+	git bisect skip --range=$HASH2,$HASH5 &&
+	test "$HASH6" = "$(git rev-parse --verify HEAD)" &&
+	test_must_fail git bisect bad > my_bisect_log.txt &&
+	grep "first bad commit could be any of" my_bisect_log.txt
+'
 
+test_expect_success 'bisect starting with a detached HEAD' '
 	git bisect reset &&
 	git checkout master^ &&
 	HEAD=$(git rev-parse --verify HEAD) &&
-- 
1.6.0.4.772.ge8f9a

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

  Powered by Linux