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

[PATCH 1/3] commit-graph: let commit graph respect commit graft

From
ZheNing Hu via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 1, 2022, 09:41 UTC
Message-ID
<19fd72c34dcd1332df638d76b0b028e9d9da3d41.1662025272.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1343.git.1662025272.gitgitgadget@gmail.com>
From: ZheNing Hu <adlternative@gmail.com>

In repo_parse_commit_internal(), if we want to use commit graph, it will call parse_commit_in_graph() to parse commit's content from commit graph, otherwise call repo_read_object_file() to parse commit's content from commit object.

repo_read_object_file() will respect commit graft, which can correctly amend commit's parents. But parse_commit_in_graph() not. Inconsistencies here may result in incorrect processing of shallow clone.

So let parse_commit_in_graph() respect commit graft as repo_read_object_file() does, which can solve this problem.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 commit-graph.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/commit-graph.c b/commit-graph.c
index f2a36032f84..89bb6f87079 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -820,6 +820,7 @@ static int fill_commit_in_graph(struct repository *r,
 	struct commit_list **pptr;
 	const unsigned char *commit_data;
 	uint32_t lex_index;
+	struct commit_graft *graft;
 
 	while (pos < g->num_commits_in_base)
 		g = g->base_graph;
@@ -833,31 +834,54 @@ static int fill_commit_in_graph(struct repository *r,
 
 	set_commit_tree(item, NULL);
 
+	graft = lookup_commit_graft(r, &item->object.oid);
+	if (graft)
+		r->parsed_objects->substituted_parent = 1;
+
 	pptr = &item->parents;
 
 	edge_value = get_be32(commit_data + g->hash_len);
 	if (edge_value == GRAPH_PARENT_NONE)
 		return 1;
-	pptr = insert_parent_or_die(r, g, edge_value, pptr);
+	if (!(graft && (graft->nr_parent < 0 || grafts_replace_parents)))
+		pptr = insert_parent_or_die(r, g, edge_value, pptr);
 
 	edge_value = get_be32(commit_data + g->hash_len + 4);
 	if (edge_value == GRAPH_PARENT_NONE)
 		return 1;
 	if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) {
-		pptr = insert_parent_or_die(r, g, edge_value, pptr);
-		return 1;
+		if (!(graft && (graft->nr_parent < 0 || grafts_replace_parents))) {
+			pptr = insert_parent_or_die(r, g, edge_value, pptr);
+			return 1;
+		}
 	}
 
 	parent_data_ptr = (uint32_t*)(g->chunk_extra_edges +
 			  4 * (uint64_t)(edge_value & GRAPH_EDGE_LAST_MASK));
 	do {
 		edge_value = get_be32(parent_data_ptr);
-		pptr = insert_parent_or_die(r, g,
-					    edge_value & GRAPH_EDGE_LAST_MASK,
-					    pptr);
+		if (!(graft && (graft->nr_parent < 0 || grafts_replace_parents))) {
+			pptr = insert_parent_or_die(r, g,
+						    edge_value & GRAPH_EDGE_LAST_MASK,
+						    pptr);
+		}
 		parent_data_ptr++;
 	} while (!(edge_value & GRAPH_LAST_EDGE));
 
+	if (graft) {
+		int i;
+		struct commit *new_parent;
+		for (i = 0; i < graft->nr_parent; i++) {
+			new_parent = lookup_commit(r,
+						   &graft->parent[i]);
+			if (!new_parent)
+				die(_("bad graft parent %s in commit %s"),
+				       oid_to_hex(&graft->parent[i]),
+				       oid_to_hex(&item->object.oid));
+			pptr = &commit_list_insert(new_parent, pptr)->next;
+		}
+	}
+
 	return 1;
 }
 
-- 
gitgitgadget
Previous: ZheNing Hu via GitGitGadgetNext: Derrick Stolee
Message 2 of 12 in “list-object-filter: introduce depth filter”
  1. 0/3 list-object-filter: introduce depth filterZheNing Hu via GitGitGadget, Sep 1, 2022
  2. 1/3 commit-graph: let commit graph respect commit graftZheNing Hu via GitGitGadget, Sep 1, 2022
  3. Derrick StoleeSep 1, 2022
  4. ZheNing HuSep 4, 2022
  5. 2/3 list-object-filter: pass traversal_context in filter_init_fnZheNing Hu via GitGitGadget, Sep 1, 2022
  6. 3/3 list-object-filter: introduce depth filterZheNing Hu via GitGitGadget, Sep 1, 2022
  7. Derrick StoleeSep 1, 2022
  8. Johannes SchindelinSep 2, 2022
  9. ZheNing HuSep 4, 2022
  10. Johannes SchindelinSep 7, 2022
  11. ZheNing HuSep 11, 2022
  12. ZheNing HuSep 4, 2022

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.