summaryrefslogtreecommitdiff
path: root/commit.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-05-31 10:00:38 +0900
committerJunio C Hamano <gitster@pobox.com>2026-05-31 10:00:38 +0900
commitf6c8fe189b698845caa3c553bcffa226642948d5 (patch)
tree3476c4b14d343e169ccbac5c7c126e47e017bd3f /commit.c
parent4d11b9c21863c1a860fdf61a9066f0d94c0d692a (diff)
parent3d8e4004c604b206d70240a087816907cce70a08 (diff)
Merge branch 'jk/commit-graph-lazy-load-fallback'
The logic to lazy-load trees from the commit-graph has been made more robust by falling back to reading the commit object when the commit-graph is no longer available. * jk/commit-graph-lazy-load-fallback: commit: fall back to full read when maybe_tree is NULL
Diffstat (limited to 'commit.c')
-rw-r--r--commit.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/commit.c b/commit.c
index e3e7352e69..fd8723502e 100644
--- a/commit.c
+++ b/commit.c
@@ -434,6 +434,27 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
c->maybe_tree = t;
}
+static void load_tree_from_commit_contents(struct repository *r, struct commit *commit)
+{
+ enum object_type type;
+ unsigned long size;
+ char *buf;
+ const char *p;
+ struct object_id tree_oid;
+
+ buf = odb_read_object(r->objects, &commit->object.oid, &type, &size);
+ if (!buf)
+ return;
+
+ if (type == OBJ_COMMIT &&
+ skip_prefix(buf, "tree ", &p) &&
+ !parse_oid_hex_algop(p, &tree_oid, &p, r->hash_algo) &&
+ *p == '\n')
+ set_commit_tree(commit, lookup_tree(r, &tree_oid));
+
+ free(buf);
+}
+
struct tree *repo_get_commit_tree(struct repository *r,
const struct commit *commit)
{
@@ -443,7 +464,17 @@ struct tree *repo_get_commit_tree(struct repository *r,
if (commit_graph_position(commit) != COMMIT_NOT_FROM_GRAPH)
return get_commit_tree_in_graph(r, commit);
- return NULL;
+ /*
+ * This is either a corrupt commit, or one which we partially loaded
+ * from a graph file but then subsequently threw away the graph data.
+ *
+ * Optimistically assume it's the latter and try to reload from
+ * scratch. This gives a performance penalty if it really is a corrupt
+ * commit, but presumably that happens rarely (and only once per
+ * process).
+ */
+ load_tree_from_commit_contents(r, (struct commit *)commit);
+ return commit->maybe_tree;
}
struct object_id *get_commit_tree_oid(const struct commit *commit)