[PATCH 0/4] make it possible to skip away from broken commits

DORMANTno replies

5 messages, 1 author, 2016-06-15 · open the first message on its own page

[PATCH 0/4] make it possible to skip away from broken commits

From: Christian Couder <hidden>
Date: 2016-06-15 22:46:53

This patch series adds a "--ratio=x/y" option to "git bisect skip" so
that it is possible to skip away from an area were the commits cannot
be tested.

Note that in this series "--ratio=4" means the same as "--ratio=1/4".
But I am not sure if this shortcut is worth it.

After this series I plan to implement a similar "--skip-ratio" option
that can be passed to "git bisect start" and to add some documentation.

  bisect: add parameters to "filter_skipped"
  bisect: use the skip ratio to choose a commit away from a skipped
    commit
  bisect: add "--ratio=<ratio>" option to "git bisect skip"
  t6030: add test case for "git bisect skip --ratio=x/y"

 bisect.c                    |   74 ++++++++++++++++++++++++++++++++++++++++--
 bisect.h                    |    4 ++-
 builtin-rev-list.c          |    4 ++-
 git-bisect.sh               |   37 ++++++++++++++-------
 t/t6030-bisect-porcelain.sh |   12 +++++++
 5 files changed, 112 insertions(+), 19 deletions(-)

[PATCH 2/4] bisect: use the skip ratio to choose a commit away from a skipped commit

From: Christian Couder <hidden>
Date: 2016-06-15 22:46:53

To do that a new function "apply_skip_ratio" is added and another
function "managed_skipped" is created to wrap both "filter_skipped"
and the previous one.

Signed-off-by: Christian Couder <redacted>
---
 bisect.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 49 insertions(+), 1 deletions(-)
diff --git a/bisect.c b/bisect.c
index 5e5a248..0a50cba 100644
--- a/bisect.c
+++ b/bisect.c
@@ -571,6 +571,53 @@ struct commit_list *filter_skipped(struct commit_list *list,
 	return filtered;
 }
 
+static struct commit_list *apply_skip_ratio(struct commit_list *list,
+					    int count,
+					    int skip_num, int skip_denum)
+{
+	int index, i;
+	struct commit_list *cur, *previous;
+
+	cur = list;
+	previous = NULL;
+	index = count * skip_num / skip_denum;
+
+	for (i = 0; cur; cur = cur->next, i++) {
+		if (i == index) {
+			if (hashcmp(cur->item->object.sha1, current_bad_sha1))
+				return cur;
+			if (previous)
+				return previous;
+			return list;
+		}
+		previous = cur;
+	}
+
+	return list;
+}
+
+static struct commit_list *managed_skipped(struct commit_list *list,
+					   struct commit_list **tried,
+					   int skip_num, int skip_denum)
+{
+	int count, skipped_first;
+
+	*tried = NULL;
+
+	if (!skipped_revs.sha1_nr)
+		return list;
+
+	if (!skip_num)
+		return filter_skipped(list, tried, 0, NULL, NULL);
+
+	list = filter_skipped(list, tried, 0, &count, &skipped_first);
+
+	if (!skipped_first)
+		return list;
+
+	return apply_skip_ratio(list, count, skip_num, skip_denum);
+}
+
 static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
 			     const char *bad_format, const char *good_format,
 			     int read_paths)
@@ -927,7 +974,8 @@ int bisect_next_all(const char *prefix, const char *skip_ratio)
 
 	revs.commits = find_bisection(revs.commits, &reaches, &all,
 				       !!skipped_revs.sha1_nr);
-	revs.commits = filter_skipped(revs.commits, &tried, 0, NULL, NULL);
+	revs.commits = managed_skipped(revs.commits, &tried,
+				       skip_num, skip_denum);
 
 	if (!revs.commits) {
 		/*
-- 
1.6.3.GIT

[PATCH 3/4] bisect: add "--ratio=<ratio>" option to "git bisect skip"

From: Christian Couder <hidden>
Date: 2016-06-15 22:46:53

This option will be passed to "git bisect--helper" using its
"--skip-ratio" option.

Signed-off-by: Christian Couder <redacted>
---
 git-bisect.sh |   37 ++++++++++++++++++++++++-------------
 1 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/git-bisect.sh b/git-bisect.sh
index 8969553..176b21d 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>|<range>)...]
+git bisect skip [--ratio=<ratio>] [(<rev>|<range>)...]
         mark <rev>... untestable revisions.
 git bisect next
         find next bisection to test and check it out.
@@ -178,18 +178,27 @@ check_expected_revs() {
 }
 
 bisect_skip() {
-        all=''
-	for arg in "$@"
+	all=''
+	unset BISECT_SKIP_RATIO
+	while [ $# -gt 0 ]
 	do
-	    case "$arg" in
-            *..*)
-                revs=$(git rev-list "$arg") || die "Bad rev input: $arg" ;;
-            *)
-                revs=$(git rev-parse --sq-quote "$arg") ;;
-	    esac
-            all="$all $revs"
-        done
-        eval bisect_state 'skip' $all
+		arg="$1"
+		case "$arg" in
+		--ratio)
+			shift; BISECT_SKIP_RATIO="$1" ;;
+		--ratio=*)
+			BISECT_SKIP_RATIO=$(expr "$arg" : '--ratio=\(.*\)') ;;
+		*..*)
+			revs=$(git rev-list "$arg") ||
+			die "Bad rev input: $arg"
+			all="$all $revs" ;;
+		*)
+			revs=$(git rev-parse --sq-quote "$arg")
+			all="$all $revs" ;;
+		esac
+		shift
+	done
+	eval bisect_state 'skip' $all
 }
 
 bisect_state() {
@@ -270,8 +279,10 @@ bisect_next() {
 	bisect_autostart
 	bisect_next_check good
 
+	skip_ratio="${BISECT_SKIP_RATIO+--skip-ratio=$BISECT_SKIP_RATIO}"
+
 	# Perform all bisection computation, display and checkout
-	git bisect--helper --next-all
+	git bisect--helper --next-all $skip_ratio
 	res=$?
 
         # Check if we should exit because bisection is finished
-- 
1.6.3.GIT

[PATCH 4/4] t6030: add test case for "git bisect skip --ratio=x/y"

From: Christian Couder <hidden>
Date: 2016-06-15 22:46:53

Signed-off-by: Christian Couder <redacted>
---
 t/t6030-bisect-porcelain.sh |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 5254b23..79956e5 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -555,6 +555,18 @@ test_expect_success 'restricting bisection on one dir and a file' '
 	grep "$PARA_HASH4 is first bad commit" my_bisect_log.txt
 '
 
+test_expect_success 'skipping with skip ratio' '
+	git bisect start $PARA_HASH7 $HASH1 &&
+	para4=$(git rev-parse --verify HEAD) &&
+	test "$para4" = "$PARA_HASH4" &&
+        git bisect skip --ratio=1/2 &&
+	hash7=$(git rev-parse --verify HEAD) &&
+	test "$hash7" = "$HASH7" &&
+        git bisect skip --ratio=3 &&
+	para6=$(git rev-parse --verify HEAD) &&
+	test "$para6" = "$PARA_HASH6"
+'
+
 #
 #
 test_done
-- 
1.6.3.GIT

[PATCH 1/4] bisect: add parameters to "filter_skipped"

From: Christian Couder <hidden>
Date: 2016-06-15 22:46:53

because we will need to get more information from this function in
some later patches.

The new "int *count" parameter gives the number of commits left after
the skipped commit have been filtered out.

The new "int *skipped_first" parameter tells us if the first commit
in the list has been skipped. Note that using this parameter also
changes the behavior of the function if the first commit is indeed
skipped. Because we assume that in this case we will want all the
filtered commits, not just the first one, even if "show_all" is not
set.

Signed-off-by: Christian Couder <redacted>
---
 bisect.c           |   26 ++++++++++++++++++++++----
 bisect.h           |    4 +++-
 builtin-rev-list.c |    4 +++-
 3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/bisect.c b/bisect.c
index 2a273f3..5e5a248 100644
--- a/bisect.c
+++ b/bisect.c
@@ -523,12 +523,19 @@ static char *join_sha1_array_hex(struct sha1_array *array, char delim)
 
 struct commit_list *filter_skipped(struct commit_list *list,
 				   struct commit_list **tried,
-				   int show_all)
+				   int show_all,
+				   int *count,
+				   int *skipped_first)
 {
 	struct commit_list *filtered = NULL, **f = &filtered;
 
 	*tried = NULL;
 
+	if (skipped_first)
+		*skipped_first = 0;
+	if (count)
+		*count = 0;
+
 	if (!skipped_revs.sha1_nr)
 		return list;
 
@@ -537,19 +544,30 @@ struct commit_list *filter_skipped(struct commit_list *list,
 		list->next = NULL;
 		if (0 <= lookup_sha1_array(&skipped_revs,
 					   list->item->object.sha1)) {
+			if (skipped_first && !*skipped_first)
+				*skipped_first = 1;
 			/* Move current to tried list */
 			*tried = list;
 			tried = &list->next;
 		} else {
-			if (!show_all)
-				return list;
+			if (!show_all) {
+				if (!skipped_first || !*skipped_first)
+					return list;
+			} else if (skipped_first && !*skipped_first) {
+				*skipped_first = -1;
+			}
 			/* Move current to filtered list */
 			*f = list;
 			f = &list->next;
+			if (count)
+				(*count)++;
 		}
 		list = next;
 	}
 
+	if (skipped_first && *skipped_first == -1)
+		*skipped_first = 0;
+
 	return filtered;
 }
 
@@ -909,7 +927,7 @@ int bisect_next_all(const char *prefix, const char *skip_ratio)
 
 	revs.commits = find_bisection(revs.commits, &reaches, &all,
 				       !!skipped_revs.sha1_nr);
-	revs.commits = filter_skipped(revs.commits, &tried, 0);
+	revs.commits = filter_skipped(revs.commits, &tried, 0, NULL, NULL);
 
 	if (!revs.commits) {
 		/*
diff --git a/bisect.h b/bisect.h
index 6808389..6ac0ff5 100644
--- a/bisect.h
+++ b/bisect.h
@@ -7,7 +7,9 @@ extern struct commit_list *find_bisection(struct commit_list *list,
 
 extern struct commit_list *filter_skipped(struct commit_list *list,
 					  struct commit_list **tried,
-					  int show_all);
+					  int show_all,
+					  int *count,
+					  int *skipped_first);
 
 extern void print_commit_list(struct commit_list *list,
 			      const char *format_cur,
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 73bff84..69753dc 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -262,7 +262,9 @@ int show_bisect_vars(struct rev_list_info *info, int reaches, int all)
 	if (!revs->commits && !(flags & BISECT_SHOW_TRIED))
 		return 1;
 
-	revs->commits = filter_skipped(revs->commits, &tried, flags & BISECT_SHOW_ALL);
+	revs->commits = filter_skipped(revs->commits, &tried,
+				       flags & BISECT_SHOW_ALL,
+				       NULL, NULL);
 
 	/*
 	 * revs->commits can reach "reaches" commits among
-- 
1.6.3.GIT
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help