summaryrefslogtreecommitdiff
path: root/bisect.c
diff options
context:
space:
mode:
Diffstat (limited to 'bisect.c')
-rw-r--r--bisect.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/bisect.c b/bisect.c
index 2c14f4d616..115cf5fa41 100644
--- a/bisect.c
+++ b/bisect.c
@@ -521,14 +521,34 @@ static char *join_sha1_array_hex(struct sha1_array *array, char delim)
return strbuf_detach(&joined_hexs, NULL);
}
+/*
+ * In this function, passing a not NULL skipped_first is very special.
+ * It means that we want to know if the first commit in the list is
+ * skipped because we will want to test a commit away from it if it is
+ * indeed skipped.
+ * So if the first commit is skipped, we cannot take the shortcut to
+ * just "return list" when we find the first non skipped commit, we
+ * have to return a fully filtered list.
+ *
+ * We use (*skipped_first == -1) to mean "it has been found that the
+ * first commit is not skipped". In this case *skipped_first is set back
+ * to 0 just before the function returns.
+ */
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 +557,31 @@ 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) {
+ /* This means we know it's not skipped */
+ *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;
}
@@ -865,7 +897,7 @@ int bisect_next_all(const char *prefix)
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) {
/*