commit-graph: implement generation data chunk

As discovered by Ævar, we cannot increment graph version to distinguish between generation numbers v1 and v2 [1]. Thus, one of pre-requistes before implementing generation number v2 was to distinguish between graph versions in a backwards compatible manner. We are going to introduce a new chunk called Generation DATa chunk (or GDAT). GDAT will store corrected committer date offsets whereas CDAT will still store topological level. Old Git does not understand GDAT chunk and would ignore it, reading topological levels from CDAT. New Git can parse GDAT and take advantage of newer generation numbers, falling back to topological levels when GDAT chunk is missing (as it would happen with a commit-graph written by old Git). We introduce a test environment variable 'GIT_TEST_COMMIT_GRAPH_NO_GDAT' which forces commit-graph file to be written without generation data chunk to emulate a commit-graph file written by old Git. To minimize the space required to store corrrected commit date, Git stores corrected commit date offsets into the commit-graph file, instea of corrected commit dates. This saves us 4 bytes per commit, decreasing the GDAT chunk size by half, but it's possible for the offset to overflow the 4-bytes allocated for storage. As such overflows are and should be exceedingly rare, we use the following overflow management scheme: We introduce a new commit-graph chunk, Generation Data OVerflow ('GDOV') to store corrected commit dates for commits with offsets greater than GENERATION_NUMBER_V2_OFFSET_MAX. If the offset is greater than GENERATION_NUMBER_V2_OFFSET_MAX, we set the MSB of the offset and the other bits store the position of corrected commit date in GDOV chunk, similar to how Extra Edge List is maintained. We test the overflow-related code with the following repo history: F - N - U / \ U - N - U N \ / N - F - N Where the commits denoted by U have committer date of zero seconds since Unix epoch, the commits denoted by N have committer date of 1112354055 (default committer date for the test suite) seconds since Unix epoch and the commits denoted by F have committer date of (2 ^ 31 - 2) seconds since Unix epoch. The largest offset observed is 2 ^ 31, just large enough to overflow. [1]: https://lore.kernel.org/git/87a7gdspo4.fsf@evledraar.gmail.com/ Signed-off-by: Abhishek Kumar <abhishekkumar8222@gmail.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Abhishek Kumar committed Jan 16, 2021 at 18:11 UTC e8b63005c48696a26f976f5f9b0ccaf1983e439d
10 files changed +200 -32
commit-graph.c
+103 -11
@@ -38,11 +38,13 @@ void git_test_write_commit_graph_or_die(void)
38 #define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
39 #define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
40 #define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
41 +#define GRAPH_CHUNKID_GENERATION_DATA 0x47444154 /* "GDAT" */
42 +#define GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW 0x47444f56 /* "GDOV" */
43 #define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
44 #define GRAPH_CHUNKID_BLOOMINDEXES 0x42494458 /* "BIDX" */
45 #define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */
46 #define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */
45 -#define MAX_NUM_CHUNKS 7
47 +#define MAX_NUM_CHUNKS 9
48
49 #define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
50
@@ -61,6 +63,8 @@ void git_test_write_commit_graph_or_die(void)
63 #define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \
64 + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
65
66 +#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)
67 +
68 /* Remember to update object flag allocation in object.h */
69 #define REACHABLE (1u<<15)
70
@@ -394,6 +398,20 @@ struct commit_graph *parse_commit_graph(struct repository *r,
398 graph->chunk_commit_data = data + chunk_offset;
399 break;
400
401 + case GRAPH_CHUNKID_GENERATION_DATA:
402 + if (graph->chunk_generation_data)
403 + chunk_repeated = 1;
404 + else
405 + graph->chunk_generation_data = data + chunk_offset;
406 + break;
407 +
408 + case GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW:
409 + if (graph->chunk_generation_data_overflow)
410 + chunk_repeated = 1;
411 + else
412 + graph->chunk_generation_data_overflow = data + chunk_offset;
413 + break;
414 +
415 case GRAPH_CHUNKID_EXTRAEDGES:
416 if (graph->chunk_extra_edges)
417 chunk_repeated = 1;
@@ -754,8 +772,8 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
772 {
773 const unsigned char *commit_data;
774 struct commit_graph_data *graph_data;
757 - uint32_t lex_index;
758 - uint64_t date_high, date_low;
775 + uint32_t lex_index, offset_pos;
776 + uint64_t date_high, date_low, offset;
777
778 while (pos < g->num_commits_in_base)
779 g = g->base_graph;
@@ -773,7 +791,19 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
791 date_low = get_be32(commit_data + g->hash_len + 12);
792 item->date = (timestamp_t)((date_high << 32) | date_low);
793
776 - graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
794 + if (g->chunk_generation_data) {
795 + offset = (timestamp_t)get_be32(g->chunk_generation_data + sizeof(uint32_t) * lex_index);
796 +
797 + if (offset & CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW) {
798 + if (!g->chunk_generation_data_overflow)
799 + die(_("commit-graph requires overflow generation data but has none"));
800 +
801 + offset_pos = offset ^ CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW;
802 + graph_data->generation = get_be64(g->chunk_generation_data_overflow + 8 * offset_pos);
803 + } else
804 + graph_data->generation = item->date + offset;
805 + } else
806 + graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
807
808 if (g->topo_levels)
809 *topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2;
@@ -945,6 +975,7 @@ struct write_commit_graph_context {
975 struct oid_array oids;
976 struct packed_commit_list commits;
977 int num_extra_edges;
978 + int num_generation_data_overflows;
979 unsigned long approx_nr_objects;
980 struct progress *progress;
981 int progress_done;
@@ -963,7 +994,8 @@ struct write_commit_graph_context {
994 report_progress:1,
995 split:1,
996 changed_paths:1,
966 - order_by_pack:1;
997 + order_by_pack:1,
998 + write_generation_data:1;
999
1000 struct topo_level_slab *topo_levels;
1001 const struct commit_graph_opts *opts;
@@ -1123,6 +1155,45 @@ static int write_graph_chunk_data(struct hashfile *f,
1155 return 0;
1156 }
1157
1158 +static int write_graph_chunk_generation_data(struct hashfile *f,
1159 + struct write_commit_graph_context *ctx)
1160 +{
1161 + int i, num_generation_data_overflows = 0;
1162 +
1163 + for (i = 0; i < ctx->commits.nr; i++) {
1164 + struct commit *c = ctx->commits.list[i];
1165 + timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1166 + display_progress(ctx->progress, ++ctx->progress_cnt);
1167 +
1168 + if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1169 + offset = CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW | num_generation_data_overflows;
1170 + num_generation_data_overflows++;
1171 + }
1172 +
1173 + hashwrite_be32(f, offset);
1174 + }
1175 +
1176 + return 0;
1177 +}
1178 +
1179 +static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
1180 + struct write_commit_graph_context *ctx)
1181 +{
1182 + int i;
1183 + for (i = 0; i < ctx->commits.nr; i++) {
1184 + struct commit *c = ctx->commits.list[i];
1185 + timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1186 + display_progress(ctx->progress, ++ctx->progress_cnt);
1187 +
1188 + if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1189 + hashwrite_be32(f, offset >> 32);
1190 + hashwrite_be32(f, (uint32_t) offset);
1191 + }
1192 + }
1193 +
1194 + return 0;
1195 +}
1196 +
1197 static int write_graph_chunk_extra_edges(struct hashfile *f,
1198 struct write_commit_graph_context *ctx)
1199 {
@@ -1386,6 +1457,9 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1457 if (current->date && current->date > max_corrected_commit_date)
1458 max_corrected_commit_date = current->date - 1;
1459 commit_graph_data_at(current)->generation = max_corrected_commit_date + 1;
1460 +
1461 + if (commit_graph_data_at(current)->generation - current->date > GENERATION_NUMBER_V2_OFFSET_MAX)
1462 + ctx->num_generation_data_overflows++;
1463 }
1464 }
1465 }
@@ -1719,6 +1793,21 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1793 chunks[2].id = GRAPH_CHUNKID_DATA;
1794 chunks[2].size = (hashsz + 16) * ctx->commits.nr;
1795 chunks[2].write_fn = write_graph_chunk_data;
1796 +
1797 + if (git_env_bool(GIT_TEST_COMMIT_GRAPH_NO_GDAT, 0))
1798 + ctx->write_generation_data = 0;
1799 + if (ctx->write_generation_data) {
1800 + chunks[num_chunks].id = GRAPH_CHUNKID_GENERATION_DATA;
1801 + chunks[num_chunks].size = sizeof(uint32_t) * ctx->commits.nr;
1802 + chunks[num_chunks].write_fn = write_graph_chunk_generation_data;
1803 + num_chunks++;
1804 + }
1805 + if (ctx->num_generation_data_overflows) {
1806 + chunks[num_chunks].id = GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW;
1807 + chunks[num_chunks].size = sizeof(timestamp_t) * ctx->num_generation_data_overflows;
1808 + chunks[num_chunks].write_fn = write_graph_chunk_generation_data_overflow;
1809 + num_chunks++;
1810 + }
1811 if (ctx->num_extra_edges) {
1812 chunks[num_chunks].id = GRAPH_CHUNKID_EXTRAEDGES;
1813 chunks[num_chunks].size = 4 * ctx->num_extra_edges;
@@ -2139,6 +2228,8 @@ int write_commit_graph(struct object_directory *odb,
2228 ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
2229 ctx->opts = opts;
2230 ctx->total_bloom_filter_data_size = 0;
2231 + ctx->write_generation_data = 1;
2232 + ctx->num_generation_data_overflows = 0;
2233
2234 bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
2235 bloom_settings.bits_per_entry);
@@ -2445,16 +2536,17 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
2536 continue;
2537
2538 /*
2448 - * If one of our parents has generation GENERATION_NUMBER_V1_MAX, then
2449 - * our generation is also GENERATION_NUMBER_V1_MAX. Decrement to avoid
2450 - * extra logic in the following condition.
2539 + * If we are using topological level and one of our parents has
2540 + * generation GENERATION_NUMBER_V1_MAX, then our generation is
2541 + * also GENERATION_NUMBER_V1_MAX. Decrement to avoid extra logic
2542 + * in the following condition.
2543 */
2452 - if (max_generation == GENERATION_NUMBER_V1_MAX)
2544 + if (!g->chunk_generation_data && max_generation == GENERATION_NUMBER_V1_MAX)
2545 max_generation--;
2546
2547 generation = commit_graph_generation(graph_commit);
2456 - if (generation != max_generation + 1)
2457 - graph_report(_("commit-graph generation for commit %s is %"PRItime" != %"PRItime),
2548 + if (generation < max_generation + 1)
2549 + graph_report(_("commit-graph generation for commit %s is %"PRItime" < %"PRItime),
2550 oid_to_hex(&cur_oid),
2551 generation,
2552 max_generation + 1);
commit-graph.h
+3
@@ -6,6 +6,7 @@
6 #include "oidset.h"
7
8 #define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH"
9 +#define GIT_TEST_COMMIT_GRAPH_NO_GDAT "GIT_TEST_COMMIT_GRAPH_NO_GDAT"
10 #define GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE "GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE"
11 #define GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS "GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS"
12
@@ -68,6 +69,8 @@ struct commit_graph {
69 const uint32_t *chunk_oid_fanout;
70 const unsigned char *chunk_oid_lookup;
71 const unsigned char *chunk_commit_data;
72 + const unsigned char *chunk_generation_data;
73 + const unsigned char *chunk_generation_data_overflow;
74 const unsigned char *chunk_extra_edges;
75 const unsigned char *chunk_base_graphs;
76 const unsigned char *chunk_bloom_indexes;
commit.h
+1
@@ -14,6 +14,7 @@
14 #define GENERATION_NUMBER_INFINITY ((1ULL << 63) - 1)
15 #define GENERATION_NUMBER_V1_MAX 0x3FFFFFFF
16 #define GENERATION_NUMBER_ZERO 0
17 +#define GENERATION_NUMBER_V2_OFFSET_MAX ((1ULL << 31) - 1)
18
19 struct commit_list {
20 struct commit *item;
t/README
+3
@@ -393,6 +393,9 @@ GIT_TEST_COMMIT_GRAPH=<boolean>, when true, forces the commit-graph to
393 be written after every 'git commit' command, and overrides the
394 'core.commitGraph' setting to true.
395
396 +GIT_TEST_COMMIT_GRAPH_NO_GDAT=<boolean>, when true, forces the
397 +commit-graph to be written without generation data chunk.
398 +
399 GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=<boolean>, when true, forces
400 commit-graph write to compute and write changed path Bloom filters for
401 every 'git commit-graph write', as if the `--changed-paths` option was
t/helper/test-read-graph.c
+4
@@ -33,6 +33,10 @@ int cmd__read_graph(int argc, const char **argv)
33 printf(" oid_lookup");
34 if (graph->chunk_commit_data)
35 printf(" commit_metadata");
36 + if (graph->chunk_generation_data)
37 + printf(" generation_data");
38 + if (graph->chunk_generation_data_overflow)
39 + printf(" generation_data_overflow");
40 if (graph->chunk_extra_edges)
41 printf(" extra_edges");
42 if (graph->chunk_bloom_indexes)
t/t4216-log-bloom.sh
+2 -2
@@ -40,11 +40,11 @@ test_expect_success 'setup test - repo, commits, commit graph, log outputs' '
40 '
41
42 graph_read_expect () {
43 - NUM_CHUNKS=5
43 + NUM_CHUNKS=6
44 cat >expect <<- EOF
45 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
46 num_commits: $1
47 - chunks: oid_fanout oid_lookup commit_metadata bloom_indexes bloom_data
47 + chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
48 EOF
49 test-tool read-graph >actual &&
50 test_cmp expect actual
t/t5318-commit-graph.sh
+66 -13
@@ -76,7 +76,7 @@ graph_git_behavior 'no graph' full commits/3 commits/1
76 graph_read_expect() {
77 OPTIONAL=""
78 NUM_CHUNKS=3
79 - if test ! -z $2
79 + if test ! -z "$2"
80 then
81 OPTIONAL=" $2"
82 NUM_CHUNKS=$((3 + $(echo "$2" | wc -w)))
@@ -103,14 +103,14 @@ test_expect_success 'exit with correct error on bad input to --stdin-commits' '
103 # valid commit and tree OID
104 git rev-parse HEAD HEAD^{tree} >in &&
105 git commit-graph write --stdin-commits <in &&
106 - graph_read_expect 3
106 + graph_read_expect 3 generation_data
107 '
108
109 test_expect_success 'write graph' '
110 cd "$TRASH_DIRECTORY/full" &&
111 git commit-graph write &&
112 test_path_is_file $objdir/info/commit-graph &&
113 - graph_read_expect "3"
113 + graph_read_expect "3" generation_data
114 '
115
116 test_expect_success POSIXPERM 'write graph has correct permissions' '
@@ -219,7 +219,7 @@ test_expect_success 'write graph with merges' '
219 cd "$TRASH_DIRECTORY/full" &&
220 git commit-graph write &&
221 test_path_is_file $objdir/info/commit-graph &&
222 - graph_read_expect "10" "extra_edges"
222 + graph_read_expect "10" "generation_data extra_edges"
223 '
224
225 graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2
@@ -254,7 +254,7 @@ test_expect_success 'write graph with new commit' '
254 cd "$TRASH_DIRECTORY/full" &&
255 git commit-graph write &&
256 test_path_is_file $objdir/info/commit-graph &&
257 - graph_read_expect "11" "extra_edges"
257 + graph_read_expect "11" "generation_data extra_edges"
258 '
259
260 graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1
@@ -264,7 +264,7 @@ test_expect_success 'write graph with nothing new' '
264 cd "$TRASH_DIRECTORY/full" &&
265 git commit-graph write &&
266 test_path_is_file $objdir/info/commit-graph &&
267 - graph_read_expect "11" "extra_edges"
267 + graph_read_expect "11" "generation_data extra_edges"
268 '
269
270 graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1
@@ -274,7 +274,7 @@ test_expect_success 'build graph from latest pack with closure' '
274 cd "$TRASH_DIRECTORY/full" &&
275 cat new-idx | git commit-graph write --stdin-packs &&
276 test_path_is_file $objdir/info/commit-graph &&
277 - graph_read_expect "9" "extra_edges"
277 + graph_read_expect "9" "generation_data extra_edges"
278 '
279
280 graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1
@@ -287,7 +287,7 @@ test_expect_success 'build graph from commits with closure' '
287 git rev-parse merge/1 >>commits-in &&
288 cat commits-in | git commit-graph write --stdin-commits &&
289 test_path_is_file $objdir/info/commit-graph &&
290 - graph_read_expect "6"
290 + graph_read_expect "6" "generation_data"
291 '
292
293 graph_git_behavior 'graph from commits, commit 8 vs merge 1' full commits/8 merge/1
@@ -297,7 +297,7 @@ test_expect_success 'build graph from commits with append' '
297 cd "$TRASH_DIRECTORY/full" &&
298 git rev-parse merge/3 | git commit-graph write --stdin-commits --append &&
299 test_path_is_file $objdir/info/commit-graph &&
300 - graph_read_expect "10" "extra_edges"
300 + graph_read_expect "10" "generation_data extra_edges"
301 '
302
303 graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
@@ -307,7 +307,7 @@ test_expect_success 'build graph using --reachable' '
307 cd "$TRASH_DIRECTORY/full" &&
308 git commit-graph write --reachable &&
309 test_path_is_file $objdir/info/commit-graph &&
310 - graph_read_expect "11" "extra_edges"
310 + graph_read_expect "11" "generation_data extra_edges"
311 '
312
313 graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
@@ -328,7 +328,7 @@ test_expect_success 'write graph in bare repo' '
328 cd "$TRASH_DIRECTORY/bare" &&
329 git commit-graph write &&
330 test_path_is_file $baredir/info/commit-graph &&
331 - graph_read_expect "11" "extra_edges"
331 + graph_read_expect "11" "generation_data extra_edges"
332 '
333
334 graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1
@@ -454,8 +454,9 @@ test_expect_success 'warn on improper hash version' '
454
455 test_expect_success 'git commit-graph verify' '
456 cd "$TRASH_DIRECTORY/full" &&
457 - git rev-parse commits/8 | git commit-graph write --stdin-commits &&
458 - git commit-graph verify >output
457 + git rev-parse commits/8 | GIT_TEST_COMMIT_GRAPH_NO_GDAT=1 git commit-graph write --stdin-commits &&
458 + git commit-graph verify >output &&
459 + graph_read_expect 9 extra_edges
460 '
461
462 NUM_COMMITS=9
@@ -741,4 +742,56 @@ test_expect_success 'corrupt commit-graph write (missing tree)' '
742 )
743 '
744
745 +# We test the overflow-related code with the following repo history:
746 +#
747 +# 4:F - 5:N - 6:U
748 +# / \
749 +# 1:U - 2:N - 3:U M:N
750 +# \ /
751 +# 7:N - 8:F - 9:N
752 +#
753 +# Here the commits denoted by U have committer date of zero seconds
754 +# since Unix epoch, the commits denoted by N have committer date
755 +# starting from 1112354055 seconds since Unix epoch (default committer
756 +# date for the test suite), and the commits denoted by F have committer
757 +# date of (2 ^ 31 - 2) seconds since Unix epoch.
758 +#
759 +# The largest offset observed is 2 ^ 31, just large enough to overflow.
760 +#
761 +
762 +test_expect_success 'set up and verify repo with generation data overflow chunk' '
763 + objdir=".git/objects" &&
764 + UNIX_EPOCH_ZERO="@0 +0000" &&
765 + FUTURE_DATE="@2147483646 +0000" &&
766 + test_oid_cache <<-EOF &&
767 + oid_version sha1:1
768 + oid_version sha256:2
769 + EOF
770 + cd "$TRASH_DIRECTORY" &&
771 + mkdir repo &&
772 + cd repo &&
773 + git init &&
774 + test_commit --date "$UNIX_EPOCH_ZERO" 1 &&
775 + test_commit 2 &&
776 + test_commit --date "$UNIX_EPOCH_ZERO" 3 &&
777 + git commit-graph write --reachable &&
778 + graph_read_expect 3 generation_data &&
779 + test_commit --date "$FUTURE_DATE" 4 &&
780 + test_commit 5 &&
781 + test_commit --date "$UNIX_EPOCH_ZERO" 6 &&
782 + git branch left &&
783 + git reset --hard 3 &&
784 + test_commit 7 &&
785 + test_commit --date "$FUTURE_DATE" 8 &&
786 + test_commit 9 &&
787 + git branch right &&
788 + git reset --hard 3 &&
789 + test_merge M left right &&
790 + git commit-graph write --reachable &&
791 + graph_read_expect 10 "generation_data generation_data_overflow" &&
792 + git commit-graph verify
793 +'
794 +
795 +graph_git_behavior 'generation data overflow chunk repo' repo left right
796 +
797 test_done
t/t5324-split-commit-graph.sh
+6 -6
@@ -13,11 +13,11 @@ test_expect_success 'setup repo' '
13 infodir=".git/objects/info" &&
14 graphdir="$infodir/commit-graphs" &&
15 test_oid_cache <<-EOM
16 - shallow sha1:1760
17 - shallow sha256:2064
16 + shallow sha1:2132
17 + shallow sha256:2436
18
19 - base sha1:1376
20 - base sha256:1496
19 + base sha1:1408
20 + base sha256:1528
21
22 oid_version sha1:1
23 oid_version sha256:2
@@ -31,9 +31,9 @@ graph_read_expect() {
31 NUM_BASE=$2
32 fi
33 cat >expect <<- EOF
34 - header: 43475048 1 $(test_oid oid_version) 3 $NUM_BASE
34 + header: 43475048 1 $(test_oid oid_version) 4 $NUM_BASE
35 num_commits: $1
36 - chunks: oid_fanout oid_lookup commit_metadata
36 + chunks: oid_fanout oid_lookup commit_metadata generation_data
37 EOF
38 test-tool read-graph >output &&
39 test_cmp expect output
t/t6600-test-reach.sh
+6
@@ -55,6 +55,9 @@ test_expect_success 'setup' '
55 git show-ref -s commit-5-5 | git commit-graph write --stdin-commits &&
56 mv .git/objects/info/commit-graph commit-graph-half &&
57 chmod u+w commit-graph-half &&
58 + GIT_TEST_COMMIT_GRAPH_NO_GDAT=1 git commit-graph write --reachable &&
59 + mv .git/objects/info/commit-graph commit-graph-no-gdat &&
60 + chmod u+w commit-graph-no-gdat &&
61 git config core.commitGraph true
62 '
63
@@ -67,6 +70,9 @@ run_all_modes () {
70 test_cmp expect actual &&
71 cp commit-graph-half .git/objects/info/commit-graph &&
72 "$@" <input >actual &&
73 + test_cmp expect actual &&
74 + cp commit-graph-no-gdat .git/objects/info/commit-graph &&
75 + "$@" <input >actual &&
76 test_cmp expect actual
77 }
78
t/test-lib-functions.sh
+6
@@ -202,6 +202,12 @@ test_commit () {
202 --signoff)
203 signoff="$1"
204 ;;
205 + --date)
206 + notick=yes
207 + GIT_COMMITTER_DATE="$2"
208 + GIT_AUTHOR_DATE="$2"
209 + shift
210 + ;;
211 -C)
212 indir="$2"
213 shift