Thread (38 messages) flat view 38 messages, 5 authors, 2016-06-15
STALE3714d

[PATCH] Introduce filter_independent() in commit.c

From: Miklos Vajna <hidden>
Date: 2016-06-15 22:44:48
Subsystem: the rest · Maintainer: Linus Torvalds

This is similar to git-show-branch --independent: It filters out commits
which are reachable from any other item from the input list.

Signed-off-by: Miklos Vajna <redacted>
---

On Thu, Jun 19, 2008 at 08:03:58PM -0700, Junio C Hamano [off-list ref] wrote:
quoted
+   for (i = heads; i; i = i->next)
+           if (!(i->item->object.flags & RESULT))
+                   pptr = &commit_list_insert(i->item, pptr)->next;
Hmm.  How well was this function tested?
As Dscho pointed out in an other mail there was no testcase for it, I
wrote one and it pointed out what you said: it was buggy.
Because RESULT is an implementation detail of merge_bases(), I do not
think we would want to expose it outside of it.
The new version does not have this problem, either.
More worryingly, the flag is supposed to be cleaned from the objects
after get_merge_bases() returns.  I am not sure what you'll learn by
looking at the flag here.
Yes, you are right. In fact the idea to use get_octopus_merge_bases()
was wrong, since it does not do what we need.

Here is an example:

	A - B
	  \ C
	  \ D
	  \ E - F

In this case get_octopus_merge_bases() will return only A, which is what
it should do, but we need E in filter_indepenent() as well.

Below is what I pushed to my working branch.

This version now passes the test that was failed for the previous one.

 commit.c |   32 ++++++++++++++++++++++++++++++++
 commit.h |    1 +
 2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/commit.c b/commit.c
index 6052ca3..17e18d7 100644
--- a/commit.c
+++ b/commit.c
@@ -705,3 +705,35 @@ int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 	free_commit_list(bases);
 	return ret;
 }
+
+struct commit_list *filter_independent(unsigned char *head,
+	struct commit_list *heads)
+{
+	struct commit_list *b, *i, *j, *k, *bases = NULL, *ret = NULL;
+	struct commit_list **pptr = &ret;
+
+	commit_list_insert(lookup_commit(head), &heads);
+
+	for (i = heads; i; i = i->next) {
+		for (j = heads; j; j = j->next) {
+			if (i == j)
+				continue;
+			b = get_merge_bases(i->item, j->item, 1);
+			for (k = b; k; k = k->next)
+				commit_list_insert(k->item, &bases);
+		}
+	}
+
+	for (i = heads; i; i = i->next) {
+		int found = 0;
+		for (b = bases; b; b = b->next) {
+			if (!hashcmp(i->item->object.sha1, b->item->object.sha1)) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			pptr = &commit_list_insert(i->item, pptr)->next;
+	}
+	return ret;
+}
diff --git a/commit.h b/commit.h
index dcec7fb..0aef7e4 100644
--- a/commit.h
+++ b/commit.h
@@ -131,6 +131,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
 		int depth, int shallow_flag, int not_shallow_flag);
 
 int in_merge_bases(struct commit *, struct commit **, int);
+struct commit_list *filter_independent(unsigned char *head, struct commit_list *heads);
 
 extern int interactive_add(int argc, const char **argv, const char *prefix);
 extern int rerere(void);
-- 
1.5.6
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help