From: Junio C Hamano <junkio@cox.net>
To: torvalds@osdl.org
Cc: git@vger.kernel.org
Subject: [PATCH/RFC] rev-list: understand bound commits.
Date: Sat, 21 Jan 2006 00:23:14 -0800 [thread overview]
Message-ID: <7vslrirnv1.fsf@assigned-by-dhcp.cox.net> (raw)
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
reply other threads:[~2006-01-21 8:23 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vslrirnv1.fsf@assigned-by-dhcp.cox.net \
--to=junkio@cox.net \
--cc=git@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox