Git development
 help / color / mirror / Atom feed
* [PATCH/RFC] rev-list: understand bound commits.
@ 2006-01-21  8:23 Junio C Hamano
  0 siblings, 0 replies; only message in thread
From: Junio C Hamano @ 2006-01-21  8:23 UTC (permalink / raw)
  To: torvalds; +Cc: git

This adds support for "bind" lines in commit objects, so that
"rev-list --objects piped to pack-objects" pattern can be used
for git native transports.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * Linus, I would really appreciate if you can proofread and
   comment on this patch.  I am reasonably sure that I did not
   break things when no commit with "bind" lines are involved,
   but I am not sure if this makes --objects do the right thing
   to produce correct packs.  The goal is still to have:

   $ git rev-list --objects A..B

   to produce list of objects that are needed to complete B for
   somebody who has A, taking into account the objects contained
   in the subproject commits, while:

   $ git rev-list A..B

   should not worry anything about subproject commits.

 rev-list.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 61 insertions(+), 4 deletions(-)

e0571c156e9abd75473c6c85e224965dae842a65
diff --git a/rev-list.c b/rev-list.c
index f2534fd..339926a 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -201,6 +201,37 @@ static struct object_list **process_tree
 	return p;
 }
 
+static struct object_list **process_commit_part(struct commit *, struct object_list **, const char *);
+
+static struct object_list **process_bound_commit(struct commit *bound, struct object_list **p, const char *name)
+{
+	struct object *obj = &bound->object;
+
+	if (!list_objects)
+		return p;
+	if (obj->flags & (UNINTERESTING|SEEN))
+		return p;
+	if (parse_commit(bound) < 0)
+		die("bad commit object %s", sha1_to_hex(obj->sha1));
+	obj->flags |= SEEN;
+	p = add_object(obj, p, name);
+	return process_commit_part(bound, p, name);
+}
+
+static struct object_list **process_commit_part(struct commit *commit, struct object_list **p, const char *name)
+{
+	p = process_tree(commit->tree, p, name);
+	if (commit->binds) {
+		struct commit_list *bp = commit->binds;
+		while (bp) {
+			struct commit *bound = bp->item;
+			bp = bp->next;
+			p = process_bound_commit(bound, p, name);
+		}
+	}
+	return p;
+}
+
 static struct object_list *pending_objects = NULL;
 
 static void show_commit_list(struct commit_list *list)
@@ -209,7 +240,7 @@ static void show_commit_list(struct comm
 	while (list) {
 		struct commit *commit = pop_most_recent_commit(&list, SEEN);
 
-		p = process_tree(commit->tree, p, "");
+		p = process_commit_part(commit, p, "");
 		if (process_commit(commit) == STOP)
 			break;
 	}
@@ -231,6 +262,10 @@ static void show_commit_list(struct comm
 			p = process_blob((struct blob *)obj, p, name);
 			continue;
 		}
+		if (obj->type == commit_type) {
+			p = process_bound_commit((struct commit *)obj, p, name);
+			continue;
+		}
 		die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
 	}
 	while (objects) {
@@ -285,6 +320,16 @@ static void mark_tree_uninteresting(stru
 	}
 }
 
+static void mark_bound_commits(struct commit *commit, int flags)
+{
+	struct commit_list *clist = commit->binds;
+	while (clist) {
+		struct commit *bound = clist->item;
+		bound->object.flags |= flags;
+		clist = clist->next;
+	}
+}
+
 static void mark_parents_uninteresting(struct commit *commit)
 {
 	struct commit_list *parents = commit->parents;
@@ -305,6 +350,13 @@ static void mark_parents_uninteresting(s
 			mark_parents_uninteresting(commit);
 
 		/*
+		 * Subproject commits bound to an uninteresting
+		 * parent is not interesting.
+		 */
+		if (commit->binds)
+			mark_bound_commits(commit, UNINTERESTING);
+
+		/*
 		 * A missing commit is ok iff its parent is marked 
 		 * uninteresting.
 		 *
@@ -520,6 +572,7 @@ static void add_parents_to_list(struct c
 			p->object.flags |= UNINTERESTING;
 			if (p->parents)
 				mark_parents_uninteresting(p);
+			mark_bound_commits(p, UNINTERESTING);
 			if (p->object.flags & SEEN)
 				continue;
 			p->object.flags |= SEEN;
@@ -599,9 +652,12 @@ static struct commit_list *limit_list(st
 			obj->flags |= UNINTERESTING;
 		if (unpacked && has_sha1_pack(obj->sha1))
 			obj->flags |= UNINTERESTING;
-		add_parents_to_list(commit, &list);
+		if (commit->parents)
+			add_parents_to_list(commit, &list);
 		if (obj->flags & UNINTERESTING) {
-			mark_parents_uninteresting(commit);
+			if (commit->parents)
+				mark_parents_uninteresting(commit);
+			mark_bound_commits(commit, UNINTERESTING);
 			if (everybody_uninteresting(list))
 				break;
 			continue;
@@ -654,8 +710,9 @@ static struct commit *get_commit_referen
 		object->flags |= flags;
 		if (parse_commit(commit) < 0)
 			die("unable to parse commit %s", name);
-		if (flags & UNINTERESTING)
+		if ((flags & UNINTERESTING) && commit->parents)
 			mark_parents_uninteresting(commit);
+		mark_bound_commits(commit, flags);
 		return commit;
 	}
 
-- 
1.1.4.g5a4c

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2006-01-21  8:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-21  8:23 [PATCH/RFC] rev-list: understand bound commits Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox