1#!/bin/sh
2
3test_description='split commit graph'
4. ./test-lib.sh
5
6GIT_TEST_COMMIT_GRAPH=0
7GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0
8
9test_expect_success 'setup repo' '
10	git init &&
11	git config core.commitGraph true &&
12	git config gc.writeCommitGraph false &&
13	infodir=".git/objects/info" &&
14	graphdir="$infodir/commit-graphs" &&
15	test_oid_cache <<-EOM
16	shallow sha1:2132
17	shallow sha256:2436
18
19	base sha1:1408
20	base sha256:1528
21
22	oid_version sha1:1
23	oid_version sha256:2
24	EOM
25'
26
27graph_read_expect() {
28	NUM_BASE=0
29	if test ! -z $2
30	then
31		NUM_BASE=$2
32	fi
33	cat >expect <<- EOF
34	header: 43475048 1 $(test_oid oid_version) 4 $NUM_BASE
35	num_commits: $1
36	chunks: oid_fanout oid_lookup commit_metadata generation_data
37	EOF
38	test-tool read-graph >output &&
39	test_cmp expect output
40}
41
42test_expect_success POSIXPERM 'tweak umask for modebit tests' '
43	umask 022
44'
45
46test_expect_success 'create commits and write commit-graph' '
47	for i in $(test_seq 3)
48	do
49		test_commit $i &&
50		git branch commits/$i || return 1
51	done &&
52	git commit-graph write --reachable &&
53	test_path_is_file $infodir/commit-graph &&
54	graph_read_expect 3
55'
56
57graph_git_two_modes() {
58	git ${2:+ -C "$2"} -c core.commitGraph=true $1 >output &&
59	git ${2:+ -C "$2"} -c core.commitGraph=false $1 >expect &&
60	test_cmp expect output
61}
62
63graph_git_behavior() {
64	MSG=$1
65	BRANCH=$2
66	COMPARE=$3
67	DIR=$4
68	test_expect_success "check normal git operations: $MSG" '
69		graph_git_two_modes "log --oneline $BRANCH" "$DIR" &&
70		graph_git_two_modes "log --topo-order $BRANCH" "$DIR" &&
71		graph_git_two_modes "log --graph $COMPARE..$BRANCH" "$DIR" &&
72		graph_git_two_modes "branch -vv" "$DIR" &&
73		graph_git_two_modes "merge-base -a $BRANCH $COMPARE" "$DIR"
74	'
75}
76
77graph_git_behavior 'graph exists' commits/3 commits/1
78
79verify_chain_files_exist() {
80	for hash in $(cat $1/commit-graph-chain)
81	do
82		test_path_is_file $1/graph-$hash.graph || return 1
83	done
84}
85
86test_expect_success 'add more commits, and write a new base graph' '
87	git reset --hard commits/1 &&
88	for i in $(test_seq 4 5)
89	do
90		test_commit $i &&
91		git branch commits/$i || return 1
92	done &&
93	git reset --hard commits/2 &&
94	for i in $(test_seq 6 10)
95	do
96		test_commit $i &&
97		git branch commits/$i || return 1
98	done &&
99	git reset --hard commits/2 &&
100	git merge commits/4 &&
101	git branch merge/1 &&
102	git reset --hard commits/4 &&
103	git merge commits/6 &&
104	git branch merge/2 &&
105	git commit-graph write --reachable &&
106	graph_read_expect 12
107'
108
109test_expect_success 'fork and fail to base a chain on a commit-graph file' '
110	test_when_finished rm -rf fork &&
111	git clone . fork &&
112	(
113		cd fork &&
114		rm .git/objects/info/commit-graph &&
115		echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
116		test_commit new-commit &&
117		git commit-graph write --reachable --split &&
118		test_path_is_file $graphdir/commit-graph-chain &&
119		test_line_count = 1 $graphdir/commit-graph-chain &&
120		verify_chain_files_exist $graphdir
121	)
122'
123
124test_expect_success 'add three more commits, write a tip graph' '
125	git reset --hard commits/3 &&
126	git merge merge/1 &&
127	git merge commits/5 &&
128	git merge merge/2 &&
129	git branch merge/3 &&
130	git commit-graph write --reachable --split &&
131	test_path_is_missing $infodir/commit-graph &&
132	test_path_is_file $graphdir/commit-graph-chain &&
133	ls $graphdir/graph-*.graph >graph-files &&
134	test_line_count = 2 graph-files &&
135	verify_chain_files_exist $graphdir
136'
137
138graph_git_behavior 'split commit-graph: merge 3 vs 2' merge/3 merge/2
139
140test_expect_success 'add one commit, write a tip graph' '
141	test_commit 11 &&
142	git branch commits/11 &&
143	git commit-graph write --reachable --split &&
144	test_path_is_missing $infodir/commit-graph &&
145	test_path_is_file $graphdir/commit-graph-chain &&
146	ls $graphdir/graph-*.graph >graph-files &&
147	test_line_count = 3 graph-files &&
148	verify_chain_files_exist $graphdir
149'
150
151graph_git_behavior 'three-layer commit-graph: commit 11 vs 6' commits/11 commits/6
152
153test_expect_success 'add one commit, write a merged graph' '
154	test_commit 12 &&
155	git branch commits/12 &&
156	git commit-graph write --reachable --split &&
157	test_path_is_file $graphdir/commit-graph-chain &&
158	test_line_count = 2 $graphdir/commit-graph-chain &&
159	ls $graphdir/graph-*.graph >graph-files &&
160	test_line_count = 2 graph-files &&
161	verify_chain_files_exist $graphdir
162'
163
164graph_git_behavior 'merged commit-graph: commit 12 vs 6' commits/12 commits/6
165
166test_expect_success 'create fork and chain across alternate' '
167	git clone . fork &&
168	(
169		cd fork &&
170		git config core.commitGraph true &&
171		rm -rf $graphdir &&
172		echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
173		test_commit 13 &&
174		git branch commits/13 &&
175		git commit-graph write --reachable --split &&
176		test_path_is_file $graphdir/commit-graph-chain &&
177		test_line_count = 3 $graphdir/commit-graph-chain &&
178		ls $graphdir/graph-*.graph >graph-files &&
179		test_line_count = 1 graph-files &&
180		git -c core.commitGraph=true  rev-list HEAD >expect &&
181		git -c core.commitGraph=false rev-list HEAD >actual &&
182		test_cmp expect actual &&
183		test_commit 14 &&
184		git commit-graph write --reachable --split --object-dir=.git/objects/ &&
185		test_line_count = 3 $graphdir/commit-graph-chain &&
186		ls $graphdir/graph-*.graph >graph-files &&
187		test_line_count = 1 graph-files
188	)
189'
190
191if test -d fork
192then
193	graph_git_behavior 'alternate: commit 13 vs 6' commits/13 origin/commits/6 "fork"
194fi
195
196test_expect_success 'test merge stragety constants' '
197	git clone . merge-2 &&
198	(
199		cd merge-2 &&
200		git config core.commitGraph true &&
201		test_line_count = 2 $graphdir/commit-graph-chain &&
202		test_commit 14 &&
203		git commit-graph write --reachable --split --size-multiple=2 &&
204		test_line_count = 3 $graphdir/commit-graph-chain
205
206	) &&
207	git clone . merge-10 &&
208	(
209		cd merge-10 &&
210		git config core.commitGraph true &&
211		test_line_count = 2 $graphdir/commit-graph-chain &&
212		test_commit 14 &&
213		git commit-graph write --reachable --split --size-multiple=10 &&
214		test_line_count = 1 $graphdir/commit-graph-chain &&
215		ls $graphdir/graph-*.graph >graph-files &&
216		test_line_count = 1 graph-files
217	) &&
218	git clone . merge-10-expire &&
219	(
220		cd merge-10-expire &&
221		git config core.commitGraph true &&
222		test_line_count = 2 $graphdir/commit-graph-chain &&
223		test_commit 15 &&
224		touch $graphdir/to-delete.graph $graphdir/to-keep.graph &&
225		test-tool chmtime =1546362000 $graphdir/to-delete.graph &&
226		test-tool chmtime =1546362001 $graphdir/to-keep.graph &&
227		git commit-graph write --reachable --split --size-multiple=10 \
228			--expire-time="2019-01-01 12:00 -05:00" &&
229		test_line_count = 1 $graphdir/commit-graph-chain &&
230		test_path_is_missing $graphdir/to-delete.graph &&
231		test_path_is_file $graphdir/to-keep.graph &&
232		ls $graphdir/graph-*.graph >graph-files &&
233		test_line_count = 3 graph-files
234	) &&
235	git clone --no-hardlinks . max-commits &&
236	(
237		cd max-commits &&
238		git config core.commitGraph true &&
239		test_line_count = 2 $graphdir/commit-graph-chain &&
240		test_commit 16 &&
241		test_commit 17 &&
242		git commit-graph write --reachable --split --max-commits=1 &&
243		test_line_count = 1 $graphdir/commit-graph-chain &&
244		ls $graphdir/graph-*.graph >graph-files &&
245		test_line_count = 1 graph-files
246	)
247'
248
249test_expect_success 'remove commit-graph-chain file after flattening' '
250	git clone . flatten &&
251	(
252		cd flatten &&
253		test_line_count = 2 $graphdir/commit-graph-chain &&
254		git commit-graph write --reachable &&
255		test_path_is_missing $graphdir/commit-graph-chain &&
256		ls $graphdir >graph-files &&
257		test_line_count = 0 graph-files
258	)
259'
260
261corrupt_file() {
262	file=$1
263	pos=$2
264	data="${3:-\0}"
265	chmod a+w "$file" &&
266	printf "$data" | dd of="$file" bs=1 seek="$pos" conv=notrunc
267}
268
269test_expect_success 'verify hashes along chain, even in shallow' '
270	git clone --no-hardlinks . verify &&
271	(
272		cd verify &&
273		git commit-graph verify &&
274		base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
275		corrupt_file "$base_file" $(test_oid shallow) "\01" &&
276		test_must_fail git commit-graph verify --shallow 2>test_err &&
277		grep -v "^+" test_err >err &&
278		test_i18ngrep "incorrect checksum" err
279	)
280'
281
282test_expect_success 'verify --shallow does not check base contents' '
283	git clone --no-hardlinks . verify-shallow &&
284	(
285		cd verify-shallow &&
286		git commit-graph verify &&
287		base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
288		corrupt_file "$base_file" 1000 "\01" &&
289		git commit-graph verify --shallow &&
290		test_must_fail git commit-graph verify 2>test_err &&
291		grep -v "^+" test_err >err &&
292		test_i18ngrep "incorrect checksum" err
293	)
294'
295
296test_expect_success 'warn on base graph chunk incorrect' '
297	git clone --no-hardlinks . base-chunk &&
298	(
299		cd base-chunk &&
300		git commit-graph verify &&
301		base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
302		corrupt_file "$base_file" $(test_oid base) "\01" &&
303		git commit-graph verify --shallow 2>test_err &&
304		grep -v "^+" test_err >err &&
305		test_i18ngrep "commit-graph chain does not match" err
306	)
307'
308
309test_expect_success 'verify after commit-graph-chain corruption' '
310	git clone --no-hardlinks . verify-chain &&
311	(
312		cd verify-chain &&
313		corrupt_file "$graphdir/commit-graph-chain" 60 "G" &&
314		git commit-graph verify 2>test_err &&
315		grep -v "^+" test_err >err &&
316		test_i18ngrep "invalid commit-graph chain" err &&
317		corrupt_file "$graphdir/commit-graph-chain" 60 "A" &&
318		git commit-graph verify 2>test_err &&
319		grep -v "^+" test_err >err &&
320		test_i18ngrep "unable to find all commit-graph files" err
321	)
322'
323
324test_expect_success 'verify across alternates' '
325	git clone --no-hardlinks . verify-alt &&
326	(
327		cd verify-alt &&
328		rm -rf $graphdir &&
329		altdir="$(pwd)/../.git/objects" &&
330		echo "$altdir" >.git/objects/info/alternates &&
331		git commit-graph verify --object-dir="$altdir/" &&
332		test_commit extra &&
333		git commit-graph write --reachable --split &&
334		tip_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
335		corrupt_file "$tip_file" 100 "\01" &&
336		test_must_fail git commit-graph verify --shallow 2>test_err &&
337		grep -v "^+" test_err >err &&
338		test_i18ngrep "commit-graph has incorrect fanout value" err
339	)
340'
341
342test_expect_success 'add octopus merge' '
343	git reset --hard commits/10 &&
344	git merge commits/3 commits/4 &&
345	git branch merge/octopus &&
346	git commit-graph write --reachable --split &&
347	git commit-graph verify --progress 2>err &&
348	test_line_count = 3 err &&
349	test_i18ngrep ! warning err &&
350	test_line_count = 3 $graphdir/commit-graph-chain
351'
352
353graph_git_behavior 'graph exists' merge/octopus commits/12
354
355test_expect_success 'split across alternate where alternate is not split' '
356	git commit-graph write --reachable &&
357	test_path_is_file .git/objects/info/commit-graph &&
358	cp .git/objects/info/commit-graph . &&
359	git clone --no-hardlinks . alt-split &&
360	(
361		cd alt-split &&
362		rm -f .git/objects/info/commit-graph &&
363		echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
364		test_commit 18 &&
365		git commit-graph write --reachable --split &&
366		test_line_count = 1 $graphdir/commit-graph-chain
367	) &&
368	test_cmp commit-graph .git/objects/info/commit-graph
369'
370
371test_expect_success '--split=no-merge always writes an incremental' '
372	test_when_finished rm -rf a b &&
373	rm -rf $graphdir $infodir/commit-graph &&
374	git reset --hard commits/2 &&
375	git rev-list HEAD~1 >a &&
376	git rev-list HEAD >b &&
377	git commit-graph write --split --stdin-commits <a &&
378	git commit-graph write --split=no-merge --stdin-commits <b &&
379	test_line_count = 2 $graphdir/commit-graph-chain
380'
381
382test_expect_success '--split=replace replaces the chain' '
383	rm -rf $graphdir $infodir/commit-graph &&
384	git reset --hard commits/3 &&
385	git rev-list -1 HEAD~2 >a &&
386	git rev-list -1 HEAD~1 >b &&
387	git rev-list -1 HEAD >c &&
388	git commit-graph write --split=no-merge --stdin-commits <a &&
389	git commit-graph write --split=no-merge --stdin-commits <b &&
390	git commit-graph write --split=no-merge --stdin-commits <c &&
391	test_line_count = 3 $graphdir/commit-graph-chain &&
392	git commit-graph write --stdin-commits --split=replace <b &&
393	test_path_is_missing $infodir/commit-graph &&
394	test_path_is_file $graphdir/commit-graph-chain &&
395	ls $graphdir/graph-*.graph >graph-files &&
396	test_line_count = 1 graph-files &&
397	verify_chain_files_exist $graphdir &&
398	graph_read_expect 2
399'
400
401test_expect_success ULIMIT_FILE_DESCRIPTORS 'handles file descriptor exhaustion' '
402	git init ulimit &&
403	(
404		cd ulimit &&
405		for i in $(test_seq 64)
406		do
407			test_commit $i &&
408			run_with_limited_open_files test_might_fail git commit-graph write \
409				--split=no-merge --reachable || return 1
410		done
411	)
412'
413
414while read mode modebits
415do
416	test_expect_success POSIXPERM "split commit-graph respects core.sharedrepository $mode" '
417		rm -rf $graphdir $infodir/commit-graph &&
418		git reset --hard commits/1 &&
419		test_config core.sharedrepository "$mode" &&
420		git commit-graph write --split --reachable &&
421		ls $graphdir/graph-*.graph >graph-files &&
422		test_line_count = 1 graph-files &&
423		echo "$modebits" >expect &&
424		test_modebits $graphdir/graph-*.graph >actual &&
425		test_cmp expect actual &&
426		test_modebits $graphdir/commit-graph-chain >actual &&
427		test_cmp expect actual
428	'
429done <<\EOF
4300666 -r--r--r--
4310600 -r--------
432EOF
433
434test_expect_success '--split=replace with partial Bloom data' '
435	rm -rf $graphdir $infodir/commit-graph &&
436	git reset --hard commits/3 &&
437	git rev-list -1 HEAD~2 >a &&
438	git rev-list -1 HEAD~1 >b &&
439	git commit-graph write --split=no-merge --stdin-commits --changed-paths <a &&
440	git commit-graph write --split=no-merge --stdin-commits <b &&
441	git commit-graph write --split=replace --stdin-commits --changed-paths <c &&
442	ls $graphdir/graph-*.graph >graph-files &&
443	test_line_count = 1 graph-files &&
444	verify_chain_files_exist $graphdir
445'
446
447test_expect_success 'prevent regression for duplicate commits across layers' '
448	git init dup &&
449	git -C dup commit --allow-empty -m one &&
450	git -C dup -c core.commitGraph=false commit-graph write --split=no-merge --reachable 2>err &&
451	test_i18ngrep "attempting to write a commit-graph" err &&
452	git -C dup commit-graph write --split=no-merge --reachable &&
453	git -C dup commit --allow-empty -m two &&
454	git -C dup commit-graph write --split=no-merge --reachable &&
455	git -C dup commit --allow-empty -m three &&
456	git -C dup commit-graph write --split --reachable &&
457	git -C dup commit-graph verify
458'
459
460NUM_FIRST_LAYER_COMMITS=64
461NUM_SECOND_LAYER_COMMITS=16
462NUM_THIRD_LAYER_COMMITS=7
463NUM_FOURTH_LAYER_COMMITS=8
464NUM_FIFTH_LAYER_COMMITS=16
465SECOND_LAYER_SEQUENCE_START=$(($NUM_FIRST_LAYER_COMMITS + 1))
466SECOND_LAYER_SEQUENCE_END=$(($SECOND_LAYER_SEQUENCE_START + $NUM_SECOND_LAYER_COMMITS - 1))
467THIRD_LAYER_SEQUENCE_START=$(($SECOND_LAYER_SEQUENCE_END + 1))
468THIRD_LAYER_SEQUENCE_END=$(($THIRD_LAYER_SEQUENCE_START + $NUM_THIRD_LAYER_COMMITS - 1))
469FOURTH_LAYER_SEQUENCE_START=$(($THIRD_LAYER_SEQUENCE_END + 1))
470FOURTH_LAYER_SEQUENCE_END=$(($FOURTH_LAYER_SEQUENCE_START + $NUM_FOURTH_LAYER_COMMITS - 1))
471FIFTH_LAYER_SEQUENCE_START=$(($FOURTH_LAYER_SEQUENCE_END + 1))
472FIFTH_LAYER_SEQUENCE_END=$(($FIFTH_LAYER_SEQUENCE_START + $NUM_FIFTH_LAYER_COMMITS - 1))
473
474# Current split graph chain:
475#
476#     16 commits (No GDAT)
477# ------------------------
478#     64 commits (GDAT)
479#
480test_expect_success 'setup repo for mixed generation commit-graph-chain' '
481	graphdir=".git/objects/info/commit-graphs" &&
482	test_oid_cache <<-EOF &&
483	oid_version sha1:1
484	oid_version sha256:2
485	EOF
486	git init mixed &&
487	(
488		cd mixed &&
489		git config core.commitGraph true &&
490		git config gc.writeCommitGraph false &&
491		for i in $(test_seq $NUM_FIRST_LAYER_COMMITS)
492		do
493			test_commit $i &&
494			git branch commits/$i || return 1
495		done &&
496		git -c commitGraph.generationVersion=2 commit-graph write --reachable --split &&
497		graph_read_expect $NUM_FIRST_LAYER_COMMITS &&
498		test_line_count = 1 $graphdir/commit-graph-chain &&
499		for i in $(test_seq $SECOND_LAYER_SEQUENCE_START $SECOND_LAYER_SEQUENCE_END)
500		do
501			test_commit $i &&
502			git branch commits/$i || return 1
503		done &&
504		git -c commitGraph.generationVersion=1 commit-graph write --reachable --split=no-merge &&
505		test_line_count = 2 $graphdir/commit-graph-chain &&
506		test-tool read-graph >output &&
507		cat >expect <<-EOF &&
508		header: 43475048 1 $(test_oid oid_version) 4 1
509		num_commits: $NUM_SECOND_LAYER_COMMITS
510		chunks: oid_fanout oid_lookup commit_metadata
511		EOF
512		test_cmp expect output &&
513		git commit-graph verify &&
514		cat $graphdir/commit-graph-chain
515	)
516'
517
518# The new layer will be added without generation data chunk as it was not
519# present on the layer underneath it.
520#
521#      7 commits (No GDAT)
522# ------------------------
523#     16 commits (No GDAT)
524# ------------------------
525#     64 commits (GDAT)
526#
527test_expect_success 'do not write generation data chunk if not present on existing tip' '
528	git clone mixed mixed-no-gdat &&
529	(
530		cd mixed-no-gdat &&
531		for i in $(test_seq $THIRD_LAYER_SEQUENCE_START $THIRD_LAYER_SEQUENCE_END)
532		do
533			test_commit $i &&
534			git branch commits/$i || return 1
535		done &&
536		git commit-graph write --reachable --split=no-merge &&
537		test_line_count = 3 $graphdir/commit-graph-chain &&
538		test-tool read-graph >output &&
539		cat >expect <<-EOF &&
540		header: 43475048 1 $(test_oid oid_version) 4 2
541		num_commits: $NUM_THIRD_LAYER_COMMITS
542		chunks: oid_fanout oid_lookup commit_metadata
543		EOF
544		test_cmp expect output &&
545		git commit-graph verify
546	)
547'
548
549# Number of commits in each layer of the split-commit graph before merge:
550#
551#      8 commits (No GDAT)
552# ------------------------
553#      7 commits (No GDAT)
554# ------------------------
555#     16 commits (No GDAT)
556# ------------------------
557#     64 commits (GDAT)
558#
559# The top two layers are merged and do not have generation data chunk as layer below them does
560# not have generation data chunk.
561#
562#     15 commits (No GDAT)
563# ------------------------
564#     16 commits (No GDAT)
565# ------------------------
566#     64 commits (GDAT)
567#
568test_expect_success 'do not write generation data chunk if the topmost remaining layer does not have generation data chunk' '
569	git clone mixed-no-gdat mixed-merge-no-gdat &&
570	(
571		cd mixed-merge-no-gdat &&
572		for i in $(test_seq $FOURTH_LAYER_SEQUENCE_START $FOURTH_LAYER_SEQUENCE_END)
573		do
574			test_commit $i &&
575			git branch commits/$i || return 1
576		done &&
577		git commit-graph write --reachable --split --size-multiple 1 &&
578		test_line_count = 3 $graphdir/commit-graph-chain &&
579		test-tool read-graph >output &&
580		cat >expect <<-EOF &&
581		header: 43475048 1 $(test_oid oid_version) 4 2
582		num_commits: $(($NUM_THIRD_LAYER_COMMITS + $NUM_FOURTH_LAYER_COMMITS))
583		chunks: oid_fanout oid_lookup commit_metadata
584		EOF
585		test_cmp expect output &&
586		git commit-graph verify
587	)
588'
589
590# Number of commits in each layer of the split-commit graph before merge:
591#
592#     16 commits (No GDAT)
593# ------------------------
594#     15 commits (No GDAT)
595# ------------------------
596#     16 commits (No GDAT)
597# ------------------------
598#     64 commits (GDAT)
599#
600# The top three layers are merged and has generation data chunk as the topmost remaining layer
601# has generation data chunk.
602#
603#     47 commits (GDAT)
604# ------------------------
605#     64 commits (GDAT)
606#
607test_expect_success 'write generation data chunk if topmost remaining layer has generation data chunk' '
608	git clone mixed-merge-no-gdat mixed-merge-gdat &&
609	(
610		cd mixed-merge-gdat &&
611		for i in $(test_seq $FIFTH_LAYER_SEQUENCE_START $FIFTH_LAYER_SEQUENCE_END)
612		do
613			test_commit $i &&
614			git branch commits/$i || return 1
615		done &&
616		git commit-graph write --reachable --split --size-multiple 1 &&
617		test_line_count = 2 $graphdir/commit-graph-chain &&
618		test-tool read-graph >output &&
619		cat >expect <<-EOF &&
620		header: 43475048 1 $(test_oid oid_version) 5 1
621		num_commits: $(($NUM_SECOND_LAYER_COMMITS + $NUM_THIRD_LAYER_COMMITS + $NUM_FOURTH_LAYER_COMMITS + $NUM_FIFTH_LAYER_COMMITS))
622		chunks: oid_fanout oid_lookup commit_metadata generation_data
623		EOF
624		test_cmp expect output
625	)
626'
627
628test_expect_success 'write generation data chunk when commit-graph chain is replaced' '
629	git clone mixed mixed-replace &&
630	(
631		cd mixed-replace &&
632		git commit-graph write --reachable --split=replace &&
633		test_path_is_file $graphdir/commit-graph-chain &&
634		test_line_count = 1 $graphdir/commit-graph-chain &&
635		verify_chain_files_exist $graphdir &&
636		graph_read_expect $(($NUM_FIRST_LAYER_COMMITS + $NUM_SECOND_LAYER_COMMITS)) &&
637		git commit-graph verify
638	)
639'
640
641test_done
642