diff options
| author | Junio C Hamano <gitster@pobox.com> | 2026-05-31 10:00:38 +0900 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-05-31 10:00:38 +0900 |
| commit | f6c8fe189b698845caa3c553bcffa226642948d5 (patch) | |
| tree | 3476c4b14d343e169ccbac5c7c126e47e017bd3f /commit.c | |
| parent | 4d11b9c21863c1a860fdf61a9066f0d94c0d692a (diff) | |
| parent | 3d8e4004c604b206d70240a087816907cce70a08 (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.c | 33 |
1 files changed, 32 insertions, 1 deletions
@@ -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) |
