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>
Derrick Stolee committed
Apr 10, 2018 at 08:56 UTC
4f2542b49e1525ebde595a5254743579a28a7382
1 file changed
+45
commit-graph.c
+45
@@ -367,6 +367,50 @@ static int add_packed_commits(const struct object_id *oid,
367
return 0;
368
}
369
370
+static void add_missing_parents(struct packed_oid_list *oids, struct commit *commit)
371
+{
372
+ struct commit_list *parent;
373
+ for (parent = commit->parents; parent; parent = parent->next) {
374
+ if (!(parent->item->object.flags & UNINTERESTING)) {
375
+ ALLOC_GROW(oids->list, oids->nr + 1, oids->alloc);
376
+ oidcpy(&oids->list[oids->nr], &(parent->item->object.oid));
377
+ oids->nr++;
378
+ parent->item->object.flags |= UNINTERESTING;
379
+ }
380
+ }
381
+}
382
+
383
+static void close_reachable(struct packed_oid_list *oids)
384
+{
385
+ int i;
386
+ struct commit *commit;
387
+
388
+ for (i = 0; i < oids->nr; i++) {
389
+ commit = lookup_commit(&oids->list[i]);
390
+ if (commit)
391
+ commit->object.flags |= UNINTERESTING;
392
+ }
393
+
394
+ /*
395
+ * As this loop runs, oids->nr may grow, but not more
396
+ * than the number of missing commits in the reachable
397
+ * closure.
398
+ */
399
+ for (i = 0; i < oids->nr; i++) {
400
+ commit = lookup_commit(&oids->list[i]);
401
+
402
+ if (commit && !parse_commit(commit))
403
+ add_missing_parents(oids, commit);
404
+ }
405
+
406
+ for (i = 0; i < oids->nr; i++) {
407
+ commit = lookup_commit(&oids->list[i]);
408
+
409
+ if (commit)
410
+ commit->object.flags &= ~UNINTERESTING;
411
+ }
412
+}
413
+
414
void write_commit_graph(const char *obj_dir)
415
{
416
struct packed_oid_list oids;
@@ -390,6 +434,7 @@ void write_commit_graph(const char *obj_dir)
434
ALLOC_ARRAY(oids.list, oids.alloc);
435
436
for_each_packed_object(add_packed_commits, &oids, 0);
437
+ close_reachable(&oids);
438
439
QSORT(oids.list, oids.nr, commit_compare);
440