Skip to content

Commit e8d1cd7

Browse files
committed
possible fix for commit-graph race issue
Alternative may be to fill in all trees when closing graph file. Gross cast?
1 parent 94f0577 commit e8d1cd7

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

commit-graph.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,9 @@ void close_commit_graph(struct object_database *o)
825825
if (!o->commit_graph)
826826
return;
827827

828+
/*
829+
* could fill blank maybe_tree here?
830+
*/
828831
clear_commit_graph_data_slab(&commit_graph_data_slab);
829832
deinit_bloom_filters();
830833
free_commit_graph(o->commit_graph);

commit.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,27 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
434434
c->maybe_tree = t;
435435
}
436436

437+
static void load_tree_from_commit_contents(struct repository *r, struct commit *commit)
438+
{
439+
enum object_type type;
440+
unsigned long size;
441+
char *buf;
442+
const char *p;
443+
struct object_id tree_oid;
444+
445+
buf = odb_read_object(r->objects, &commit->object.oid, &type, &size);
446+
if (!buf)
447+
return;
448+
449+
if (type == OBJ_COMMIT &&
450+
skip_prefix(buf, "tree ", &p) &&
451+
!parse_oid_hex(p, &tree_oid, &p) &&
452+
*p == '\n')
453+
set_commit_tree(commit, lookup_tree(r, &tree_oid));
454+
455+
free(buf);
456+
}
457+
437458
struct tree *repo_get_commit_tree(struct repository *r,
438459
const struct commit *commit)
439460
{
@@ -443,7 +464,16 @@ struct tree *repo_get_commit_tree(struct repository *r,
443464
if (commit_graph_position(commit) != COMMIT_NOT_FROM_GRAPH)
444465
return get_commit_tree_in_graph(r, commit);
445466

446-
return NULL;
467+
/*
468+
* This is either a corrupt commit, or one which we partially loaded
469+
* from a graph file but then subsequently threw away the graph data.
470+
*
471+
* Optimistically assume it's the latter and try to reload from
472+
* scratch. This gives a performance penalty if it really is a corrupt
473+
* commit, but presumably that happens rarely.
474+
*/
475+
load_tree_from_commit_contents(r, (struct commit *)commit);
476+
return commit->maybe_tree;
447477
}
448478

449479
struct object_id *get_commit_tree_oid(const struct commit *commit)

0 commit comments

Comments
 (0)