Teach write_commit_graph() to walk all parents from the commits discovered in packfiles. This prevents gaps given by loose objects or previously-missed packfiles. Also automatically add commits from the existing graph file, if it exists. Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- commit-graph.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/commit-graph.c b/commit-graph.c index aff67c458e..d711a2cd81 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -633,6 +633,28 @@ static int if_packed_commit_add_to_list(const struct object_id *oid, return 0; } +static void close_reachable(struct packed_oid_list *oids) +{ + int i; + struct rev_info revs; + struct commit *commit; + init_revisions(&revs, NULL); + for (i = 0; i < oids->nr; i++) { + commit = lookup_commit(oids->list[i]); + if (commit && !parse_commit(commit)) + revs.commits = commit_list_insert(commit, &revs.commits); + } + + if (prepare_revision_walk(&revs)) + die(_("revision walk setup failed")); + + while ((commit = get_revision(&revs)) != NULL) { + ALLOC_GROW(oids->list, oids->nr + 1, oids->alloc); + oids->list[oids->nr] = &(commit->object.oid); + (oids->nr)++; + } +} + struct object_id *write_commit_graph(const char *pack_dir) { struct packed_oid_list oids; @@ -650,12 +672,27 @@ struct object_id *write_commit_graph(const char *pack_dir) char *fname; struct commit_list *parent; + prepare_commit_graph(); + oids.nr = 0; oids.alloc = 1024; + + if (commit_graph && oids.alloc < commit_graph->num_commits) + oids.alloc = commit_graph->num_commits; + ALLOC_ARRAY(oids.list, oids.alloc); + if (commit_graph) { + for (i = 0; i < commit_graph->num_commits; i++) { + oids.list[i] = malloc(sizeof(struct object_id)); + get_nth_commit_oid(commit_graph, i, oids.list[i]); + } + oids.nr = commit_graph->num_commits; + } + for_each_packed_object(if_packed_commit_add_to_list, &oids, 0); + close_reachable(&oids); QSORT(oids.list, oids.nr, commit_compare); count_distinct = 1; -- 2.15.1.45.g9b7079f