@matheusbsbs / matheus-bagliano / commits / 3d11275505
Fork 0

commit-graph: examine commits by generation number

When running 'git commit-graph write --changed-paths', we sort the commits by pack-order to save time when computing the changed-paths bloom filters. This does not help when finding the commits via the '--reachable' flag. If not using pack-order, then sort by generation number before examining the diff. Commits with similar generation are more likely to have many trees in common, making the diff faster. On the Linux kernel repository, this change reduced the computation time for 'git commit-graph write --reachable --changed-paths' from 3m00s to 1m37s. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Garima Singh <garima.singh@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Garima Singh committed Mar 30, 2020 at 00:31 UTC 3d11275505694ce4e5256516de1c5dd90e749303
1 file changed +30 -3
commit-graph.c
+30 -3
@@ -70,6 +70,25 @@ static int commit_pos_cmp(const void *va, const void *vb)
70 commit_pos_at(&commit_pos, b);
71 }
72
73 +static int commit_gen_cmp(const void *va, const void *vb)
74 +{
75 + const struct commit *a = *(const struct commit **)va;
76 + const struct commit *b = *(const struct commit **)vb;
77 +
78 + /* lower generation commits first */
79 + if (a->generation < b->generation)
80 + return -1;
81 + else if (a->generation > b->generation)
82 + return 1;
83 +
84 + /* use date as a heuristic when generations are equal */
85 + if (a->date < b->date)
86 + return -1;
87 + else if (a->date > b->date)
88 + return 1;
89 + return 0;
90 +}
91 +
92 char *get_commit_graph_filename(struct object_directory *obj_dir)
93 {
94 return xstrfmt("%s/info/commit-graph", obj_dir->path);
@@ -815,7 +834,8 @@ struct write_commit_graph_context {
834 report_progress:1,
835 split:1,
836 check_oids:1,
818 - changed_paths:1;
837 + changed_paths:1,
838 + order_by_pack:1;
839
840 const struct split_commit_graph_opts *split_opts;
841 size_t total_bloom_filter_data_size;
@@ -1178,7 +1198,11 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
1198
1199 ALLOC_ARRAY(sorted_commits, ctx->commits.nr);
1200 COPY_ARRAY(sorted_commits, ctx->commits.list, ctx->commits.nr);
1181 - QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
1201 +
1202 + if (ctx->order_by_pack)
1203 + QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
1204 + else
1205 + QSORT(sorted_commits, ctx->commits.nr, commit_gen_cmp);
1206
1207 for (i = 0; i < ctx->commits.nr; i++) {
1208 struct commit *c = sorted_commits[i];
@@ -1884,6 +1908,7 @@ int write_commit_graph(struct object_directory *odb,
1908 }
1909
1910 if (pack_indexes) {
1911 + ctx->order_by_pack = 1;
1912 if ((res = fill_oids_from_packs(ctx, pack_indexes)))
1913 goto cleanup;
1914 }
@@ -1893,8 +1918,10 @@ int write_commit_graph(struct object_directory *odb,
1918 goto cleanup;
1919 }
1920
1896 - if (!pack_indexes && !commit_hex)
1921 + if (!pack_indexes && !commit_hex) {
1922 + ctx->order_by_pack = 1;
1923 fill_oids_from_all_packs(ctx);
1924 + }
1925
1926 close_reachable(ctx);
1927