All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 7/7 (v5)] graft awareness
@ 2010-04-05 19:58 Nick Edelen
  0 siblings, 0 replies; only message in thread
From: Nick Edelen @ 2010-04-05 19:58 UTC (permalink / raw)
  To: Junio C Hamano, Nicolas Pitre, Johannes Schindelin, Sam Vilain,
	Michael J Gruber

Adds support for graft commits in rev-cache (w/ test), and slightly alters
graft mechanism.  Before, parse_commit() checked the graft list on every
commit.  Now register_commit_graft() preemptively loads graft commits into
memory, and sets a new 'graft' flag in the object.  This allows awareness of
the commits' medical history without searching a (normally private) array upon
each commit.

Signed-off-by: Nick Edelen <sirnot@gmail.com>

---
 builtin/rev-cache.c       |   14 ++++++++++++--
 commit.c                  |   34 +++++++++++++++++++++++++++++++---
 object.h                  |    3 ++-
 rev-cache.c               |   32 ++++++++++++++++++++++++++++++++
 t/t6019-rev-cache-list.sh |    7 +++++++
 5 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/builtin/rev-cache.c b/builtin/rev-cache.c
index 59fc833..404e48c 100644
--- a/builtin/rev-cache.c
+++ b/builtin/rev-cache.c
@@ -102,8 +102,18 @@ static int test_rev_list(int argc, const char *argv[])
 			flags ^= UNINTERESTING;
 		else if (!strcmp(argv[i], "--objects"))
 			revs.tree_objects = revs.blob_objects = 1;
-		else
-			handle_revision_arg(argv[i], &revs, flags, 1);
+		else {
+			struct commit_graft graft;
+
+			if (argv[i][0] == ':') {
+				handle_revision_arg(argv[i] + 1, &revs, flags, 1);
+
+				hashcpy(graft.sha1, revs.pending.objects[revs.pending.nr - 1].item->sha1);
+				graft.nr_parent = -1;
+				register_commit_graft(&graft, 0);
+			} else
+				handle_revision_arg(argv[i], &revs, flags, 1);
+		}
 	}
 
 	setup_revisions(0, 0, &revs, 0);
diff --git a/commit.c b/commit.c
index 263dd74..23f3bb9 100644
--- a/commit.c
+++ b/commit.c
@@ -100,6 +100,7 @@ static int commit_graft_pos(const unsigned char *sha1)
 
 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(graft->sha1);
 
 	if (0 <= pos) {
@@ -124,6 +125,17 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 			(commit_graft_nr - pos - 1) *
 			sizeof(*commit_graft));
 	commit_graft[pos] = graft;
+
+	commit = lookup_commit(graft->sha1);
+	commit->object.graft = 1;
+	if (commit->object.parsed) {
+		/* we don't want to call this from a parse_commit(), but
+		 * we should ensure commit's parents are "correct"
+		 */
+		commit->object.parsed = 0;
+		parse_commit(commit);
+	}
+
 	return 0;
 }
 
@@ -220,6 +232,7 @@ int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
 
 int unregister_shallow(const unsigned char *sha1)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(sha1);
 	if (pos < 0)
 		return -1;
@@ -228,6 +241,12 @@ int unregister_shallow(const unsigned char *sha1)
 				sizeof(struct commit_graft *)
 				* (commit_graft_nr - pos - 1));
 	commit_graft_nr--;
+
+	commit = lookup_commit(sha1);
+	commit->object.graft = 0;
+	commit->object.parsed = 0;
+	parse_commit(commit);
+
 	return 0;
 }
 
@@ -241,7 +260,6 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 
 	if (item->object.parsed)
 		return 0;
-	item->object.parsed = 1;
 	tail += size;
 	if (tail <= bufptr + 46 || memcmp(bufptr, "tree ", 5) || bufptr[45] != '\n')
 		return error("bogus commit object %s", sha1_to_hex(item->object.sha1));
@@ -254,7 +272,13 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 	while (pop_commit(pptr))
 		; /* clear anything from cache */
 
-	graft = lookup_commit_graft(item->object.sha1);
+	/* make sure .graft flag is initialized */
+	prepare_commit_graft();
+	if (item->object.graft)
+		graft = lookup_commit_graft(item->object.sha1);
+	else
+		graft = 0;
+
 	while (bufptr + 48 < tail && !memcmp(bufptr, "parent ", 7)) {
 		struct commit *new_parent;
 
@@ -282,8 +306,12 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 				continue;
 			pptr = &commit_list_insert(new_parent, pptr)->next;
 		}
-	}
+		item->object.graft = 1;
+	} else
+		item->object.graft = 0;
+
 	item->date = parse_commit_date(bufptr, tail);
+	item->object.parsed = 1;
 
 	return 0;
 }
diff --git a/object.h b/object.h
index 82877c8..8123824 100644
--- a/object.h
+++ b/object.h
@@ -22,7 +22,7 @@ struct object_array {
 };
 
 #define TYPE_BITS   3
-#define FLAG_BITS  27
+#define FLAG_BITS  26
 
 /*
  * The object type is stored in 3 bits.
@@ -30,6 +30,7 @@ struct object_array {
 struct object {
 	unsigned parsed : 1;
 	unsigned used : 1;
+	unsigned graft : 1;
 	unsigned type : TYPE_BITS;
 	unsigned flags : FLAG_BITS;
 	unsigned char sha1[20];
diff --git a/rev-cache.c b/rev-cache.c
index 4f1ea34..dfb3212 100644
--- a/rev-cache.c
+++ b/rev-cache.c
@@ -754,9 +754,41 @@ static int traverse_cache_slice_1(struct rc_slice_header *head, unsigned char *m
 			}
 		} else if (!ipath_nr && co->date <= date)
 			slop--;
+		else if (!ipath_nr && !upath_nr)
+			break;
 		else
 			slop = SLOP;
 
+		/* before opening further topo-relations, check if the parenting has had medical attention */
+		if (obj->graft) {
+			struct commit_list *list;
+
+			parse_commit(co);
+			obj->flags &= ~FACE_VALUE;
+			last_objects[path] = 0;
+
+			/* we're only interested in its indirect influence */
+			for (list = co->parents; list; list = list->next) {
+				struct rc_index_entry *iep;
+				struct object *po = &list->item->object;
+
+				iep = search_index(po->sha1);
+				if (!iep || hashcmp(idx_caches + 20 * iep->cache_index, head->sha1)) {
+					if (!(obj->flags & UNINTERESTING) && !(po->flags & UNINTERESTING))
+						ioutside = 1;
+				}
+			}
+
+			/* an abrupt end */
+			myworkp = &commit_list_insert(co, myworkp)->next;
+			if (uninteresting)
+				upath_nr--;
+			else
+				ipath_nr--;
+			paths[path] = 0;
+			continue;
+		}
+
 		/* open parents */
 		if (entry->merge_nr) {
 			int j, off = index + OBJECT_ENTRY_SIZE;
diff --git a/t/t6019-rev-cache-list.sh b/t/t6019-rev-cache-list.sh
index b7eff3f..5664de7 100644
--- a/t/t6019-rev-cache-list.sh
+++ b/t/t6019-rev-cache-list.sh
@@ -92,6 +92,7 @@ git rev-list --topo-order HEAD --not HEAD~2 >proper_commit_list_limited2
 git rev-list --topo-order HEAD >proper_commit_list
 git rev-list --objects HEAD >proper_object_list
 git rev-list HEAD --max-age=$min_date --min-age=$max_date >proper_list_date_limited
+git rev-cache test HEAD :HEAD~2 >proper_shallow_list 2>/dev/null
 
 cache_sha1=`git rev-cache add HEAD 2>output.err`
 
@@ -252,5 +253,11 @@ test_expect_success 'test --ignore-size function in fuse' '
 	test -e .git/rev-cache/$cache_sha1
 '
 
+#test graft handling
+test_expect_success 'check graft handling' '
+	git rev-cache test HEAD :HEAD~2 >list
+	test_cmp list proper_shallow_list
+'
+
 test_done
 
-- 
tg: (68204ac..) t/rc/graft (depends on: t/rc/names)

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

only message in thread, other threads:[~2010-04-05 19:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-05 19:58 [PATCH 7/7 (v5)] graft awareness Nick Edelen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.