git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism

From
NENick Edelen <sirnot@gmail.com>
Date
Sep 7, 2009, 14:11 UTC
Message-ID
<op.uzv4dyuotdk399@sirnot.private>

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>

--- THE PATCH THAT NEVER WAS! (sorry about the wack numbering; the change isn't very big and it seemed silly to escalate the version)

 builtin-rev-cache.c       |   14 ++++++++++++--
 commit.c                  |   25 +++++++++++++++++++++++--
 object.h                  |    3 ++-
 rev-cache.c               |   32 ++++++++++++++++++++++++++++++++
 t/t6017-rev-cache-list.sh |    6 ++++++
 5 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
index 4c1766d..b36bc39 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 b7485c4..8429f69 100644
--- a/commit.c
+++ b/commit.c
@@ -99,6 +99,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) {
@@ -123,6 +124,12 @@ 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;
+	commit->object.parsed = 0;
+	parse_commit(commit); /* in case commit was already parsed */
+
 	return 0;
 }
 
@@ -221,6 +228,7 @@ int write_shallow_commits(int fd, 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;
@@ -229,6 +237,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;
 }
 
@@ -255,7 +269,11 @@ 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);
+	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;
 
@@ -283,7 +301,10 @@ 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);
 
 	return 0;
diff --git a/object.h b/object.h
index 89dd0c4..f848e0f 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 3595f66..84305e9 100644
--- a/rev-cache.c
+++ b/rev-cache.c
@@ -663,9 +663,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 (entry->uninteresting)
+				upath_nr--;
+			else
+				ipath_nr--;
+			paths[path] = 0;
+			continue;
+		}
+
 		/* open parents */
 		if (entry->merge_nr) {
 			int j, off = index + sizeof(struct rc_object_entry_ondisk);
diff --git a/t/t6017-rev-cache-list.sh b/t/t6017-rev-cache-list.sh
index 3286560..6ada7ac 100755
--- a/t/t6017-rev-cache-list.sh
+++ b/t/t6017-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
 
 cache_sha1=`git-rev-cache add HEAD 2>output.err`
 
@@ -252,4 +253,9 @@ test_expect_success 'test --ignore-size function in fuse' '
 	test -e .git/rev-cache/$cache_sha1
 '
 
+test_expect_success 'check graft handling' '
+	git-rev-cache test HEAD :HEAD~2 >list
+	test_cmp list proper_shallow_list
+'
+
 test_done
-- 
tg: (3a6aad2..) t/revcache/graft (depends on: t/revcache/names)
Next: Nick Edelen
Message 1 of 8 in “support for commit grafts, slight change to general mechanism”
  1. 7/6 support for commit grafts, slight change to general mechanismNick Edelen, Sep 7, 2009
  2. Nick EdelenSep 27, 2009
  3. Shawn O. PearceSep 29, 2009
  4. Chris JohnsenSep 30, 2009
  5. Nick EdelenOct 19, 2009
  6. Thomas RastOct 21, 2009
  7. Thomas RastOct 21, 2009
  8. Nick EdelenOct 27, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.