diff options
author | Derrick Stolee <dstolee@microsoft.com> | 2018-04-10 08:56:04 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-04-11 10:43:02 +0900 |
commit | 4f2542b49e1525ebde595a5254743579a28a7382 (patch) | |
tree | ecba6a331d4f8fabeec0f71207da6913401a5628 | |
parent | commit-graph: add core.commitGraph setting (diff) | |
download | tgif-4f2542b49e1525ebde595a5254743579a28a7382.tar.xz |
commit-graph: close under reachability
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@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | commit-graph.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/commit-graph.c b/commit-graph.c index b1bd3a892d..ea29c5c2d8 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -367,6 +367,50 @@ static int add_packed_commits(const struct object_id *oid, return 0; } +static void add_missing_parents(struct packed_oid_list *oids, struct commit *commit) +{ + struct commit_list *parent; + for (parent = commit->parents; parent; parent = parent->next) { + if (!(parent->item->object.flags & UNINTERESTING)) { + ALLOC_GROW(oids->list, oids->nr + 1, oids->alloc); + oidcpy(&oids->list[oids->nr], &(parent->item->object.oid)); + oids->nr++; + parent->item->object.flags |= UNINTERESTING; + } + } +} + +static void close_reachable(struct packed_oid_list *oids) +{ + int i; + struct commit *commit; + + for (i = 0; i < oids->nr; i++) { + commit = lookup_commit(&oids->list[i]); + if (commit) + commit->object.flags |= UNINTERESTING; + } + + /* + * As this loop runs, oids->nr may grow, but not more + * than the number of missing commits in the reachable + * closure. + */ + for (i = 0; i < oids->nr; i++) { + commit = lookup_commit(&oids->list[i]); + + if (commit && !parse_commit(commit)) + add_missing_parents(oids, commit); + } + + for (i = 0; i < oids->nr; i++) { + commit = lookup_commit(&oids->list[i]); + + if (commit) + commit->object.flags &= ~UNINTERESTING; + } +} + void write_commit_graph(const char *obj_dir) { struct packed_oid_list oids; @@ -390,6 +434,7 @@ void write_commit_graph(const char *obj_dir) ALLOC_ARRAY(oids.list, oids.alloc); for_each_packed_object(add_packed_commits, &oids, 0); + close_reachable(&oids); QSORT(oids.list, oids.nr, commit_compare); |