* [PATCH] Implement --first-parent for git rev-list --bisect
@ 2018-05-09 21:57 Tiago Botelho
2018-05-10 5:39 ` Christian Couder
0 siblings, 1 reply; 2+ messages in thread
From: Tiago Botelho @ 2018-05-09 21:57 UTC (permalink / raw)
To: git; +Cc: christian.couder, Tiago Botelho
---
bisect.c | 53 +++++++++++++++++++++++++++++++----------------------
bisect.h | 1 +
builtin/rev-list.c | 3 +++
3 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/bisect.c b/bisect.c
index 4eafc8262..f43713574 100644
--- a/bisect.c
+++ b/bisect.c
@@ -34,7 +34,7 @@ static const char *term_good;
* We care just barely enough to avoid recursing for
* non-merge entries.
*/
-static int count_distance(struct commit_list *entry)
+static int count_distance(struct commit_list *entry, unsigned bisect_flags)
{
int nr = 0;
@@ -49,10 +49,10 @@ static int count_distance(struct commit_list *entry)
commit->object.flags |= COUNTED;
p = commit->parents;
entry = p;
- if (p) {
+ if (p && !(bisect_flags & BISECT_FIRST_PARENT)) {
p = p->next;
while (p) {
- nr += count_distance(p);
+ nr += count_distance(p, bisect_flags);
p = p->next;
}
}
@@ -82,15 +82,16 @@ static inline void weight_set(struct commit_list *elem, int weight)
*((int*)(elem->item->util)) = weight;
}
-static int count_interesting_parents(struct commit *commit)
+static int count_interesting_parents(struct commit *commit, unsigned bisect_flags)
{
struct commit_list *p;
int count;
for (count = 0, p = commit->parents; p; p = p->next) {
- if (p->item->object.flags & UNINTERESTING)
- continue;
- count++;
+ if (!(p->item->object.flags & UNINTERESTING))
+ count++;
+ if (bisect_flags & BISECT_FIRST_PARENT)
+ break;
}
return count;
}
@@ -117,10 +118,10 @@ static inline int halfway(struct commit_list *p, int nr)
}
#if !DEBUG_BISECT
-#define show_list(a,b,c,d) do { ; } while (0)
+#define show_list(a,b,c,d,e) do { ; } while (0)
#else
static void show_list(const char *debug, int counted, int nr,
- struct commit_list *list)
+ struct commit_list *list, unsigned bisect_flags)
{
struct commit_list *p;
@@ -146,10 +147,14 @@ static void show_list(const char *debug, int counted, int nr,
else
fprintf(stderr, "---");
fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid));
- for (pp = commit->parents; pp; pp = pp->next)
+ for (pp = commit->parents; pp; pp = pp->next) {
fprintf(stderr, " %.*s", 8,
oid_to_hex(&pp->item->object.oid));
+ if (bisect_flags & BISECT_FIRST_PARENT)
+ break;
+ }
+
subject_len = find_commit_subject(buf, &subject_start);
if (subject_len)
fprintf(stderr, " %.*s", subject_len, subject_start);
@@ -267,13 +272,13 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
unsigned flags = commit->object.flags;
p->item->util = &weights[n++];
- switch (count_interesting_parents(commit)) {
+ switch (count_interesting_parents(commit, bisect_flags)) {
case 0:
if (!(flags & TREESAME)) {
weight_set(p, 1);
counted++;
show_list("bisection 2 count one",
- counted, nr, list);
+ counted, nr, list, bisect_flags);
}
/*
* otherwise, it is known not to reach any
@@ -289,7 +294,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
}
}
- show_list("bisection 2 initialize", counted, nr, list);
+ show_list("bisection 2 initialize", counted, nr, list, bisect_flags);
/*
* If you have only one parent in the resulting set
@@ -310,7 +315,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
continue;
if (weight(p) != -2)
continue;
- weight_set(p, count_distance(p));
+ weight_set(p, count_distance(p, bisect_flags));
clear_distance(list);
/* Does it happen to be at exactly half-way? */
@@ -319,7 +324,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
counted++;
}
- show_list("bisection 2 count_distance", counted, nr, list);
+ show_list("bisection 2 count_distance", counted, nr, list, bisect_flags);
while (counted < nr) {
for (p = list; p; p = p->next) {
@@ -329,9 +334,10 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
if (0 <= weight(p))
continue;
for (q = p->item->parents; q; q = q->next) {
- if (q->item->object.flags & UNINTERESTING)
- continue;
- if (0 <= weight(q))
+ if (!(q->item->object.flags & UNINTERESTING))
+ if (0 <= weight(q))
+ break;
+ if (bisect_flags & BISECT_FIRST_PARENT)
break;
}
if (!q)
@@ -346,7 +352,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
weight_set(p, weight(q)+1);
counted++;
show_list("bisection 2 count one",
- counted, nr, list);
+ counted, nr, list, bisect_flags);
}
else
weight_set(p, weight(q));
@@ -357,7 +363,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
}
}
- show_list("bisection 2 counted all", counted, nr, list);
+ show_list("bisection 2 counted all", counted, nr, list, bisect_flags);
if (!find_all)
return best_bisection(list, nr);
@@ -372,7 +378,7 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
struct commit_list *list, *p, *best, *next, *last;
int *weights;
- show_list("bisection 2 entry", 0, 0, *commit_list);
+ show_list("bisection 2 entry", 0, 0, *commit_list, bisect_flags);
/*
* Count the number of total and tree-changing items on the
@@ -395,7 +401,7 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
on_list++;
}
list = last;
- show_list("bisection 2 sorted", 0, nr, list);
+ show_list("bisection 2 sorted", 0, nr, list, bisect_flags);
*all = nr;
weights = xcalloc(on_list, sizeof(*weights));
@@ -962,6 +968,9 @@ int bisect_next_all(const char *prefix, int no_checkout)
if (skipped_revs.nr)
bisect_flags |= BISECT_FIND_ALL;
+ if (revs.first_parent_only)
+ bisect_flags |= BISECT_FIRST_PARENT;
+
find_bisection(&revs.commits, &reaches, &all, bisect_flags);
revs.commits = managed_skipped(revs.commits, &tried);
diff --git a/bisect.h b/bisect.h
index 1d40a33ad..9d69940e6 100644
--- a/bisect.h
+++ b/bisect.h
@@ -1,6 +1,7 @@
#ifndef BISECT_H
#define BISECT_H
+#define BISECT_FIRST_PARENT (1u<<1)
#define BISECT_FIND_ALL (1u<<0)
/*
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 8752f5bbe..66439e1b3 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -538,6 +538,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
if (bisect_list) {
int reaches, all;
+ if (revs.first_parent_only)
+ bisect_flags |= BISECT_FIRST_PARENT;
+
find_bisection(&revs.commits, &reaches, &all, bisect_flags);
if (bisect_show_vars)
--
2.16.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Implement --first-parent for git rev-list --bisect
2018-05-09 21:57 [PATCH] Implement --first-parent for git rev-list --bisect Tiago Botelho
@ 2018-05-10 5:39 ` Christian Couder
0 siblings, 0 replies; 2+ messages in thread
From: Christian Couder @ 2018-05-10 5:39 UTC (permalink / raw)
To: Tiago Botelho; +Cc: git, Tiago Botelho
Hi Tiago,
On Wed, May 9, 2018 at 11:57 PM, Tiago Botelho <tiagonbotelho@gmail.com> wrote:
> ---
Please add something in the commit message (above the "---") about why
this new feature is useful. For example you could just say that it
will make it possible to implement bisecting on first parents which is
useful for people who don't test all the commits in the feature branch
they merge.
Outside the commit message, so after the "---", you could say that
this patch is based on pu so that it can be on top of
hn/bisect-first-parent, and that this patch is not finished as it
needs some tests. You could also have signaled that by using [RFC
PATCH] in the subject (see the --rfc option of git format-patch).
Thanks,
Christian.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-05-10 5:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-09 21:57 [PATCH] Implement --first-parent for git rev-list --bisect Tiago Botelho
2018-05-10 5:39 ` Christian Couder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).