3 test_description='split commit graph'
6 GIT_TEST_COMMIT_GRAPH=0
8 test_expect_success 'setup repo' '
10 git config core.commitGraph true &&
11 git config gc.writeCommitGraph false &&
12 infodir=".git/objects/info" &&
13 graphdir="$infodir/commit-graphs" &&
31 header: 43475048 1 1 3 $NUM_BASE
33 chunks: oid_fanout oid_lookup commit_metadata
35 test-tool read-graph >output &&
36 test_cmp expect output
39 test_expect_success POSIXPERM 'tweak umask for modebit tests' '
43 test_expect_success 'create commits and write commit-graph' '
44 for i in $(test_seq 3)
47 git branch commits/$i || return 1
49 git commit-graph write --reachable &&
50 test_path_is_file $infodir/commit-graph &&
54 graph_git_two_modes() {
55 git -c core.commitGraph=true $1 >output
56 git -c core.commitGraph=false $1 >expect
57 test_cmp expect output
60 graph_git_behavior() {
64 test_expect_success "check normal git operations: $MSG" '
65 graph_git_two_modes "log --oneline $BRANCH" &&
66 graph_git_two_modes "log --topo-order $BRANCH" &&
67 graph_git_two_modes "log --graph $COMPARE..$BRANCH" &&
68 graph_git_two_modes "branch -vv" &&
69 graph_git_two_modes "merge-base -a $BRANCH $COMPARE"
73 graph_git_behavior 'graph exists' commits/3 commits/1
75 verify_chain_files_exist() {
76 for hash in $(cat $1/commit-graph-chain)
78 test_path_is_file $1/graph-$hash.graph || return 1
82 test_expect_success 'add more commits, and write a new base graph' '
83 git reset --hard commits/1 &&
84 for i in $(test_seq 4 5)
87 git branch commits/$i || return 1
89 git reset --hard commits/2 &&
90 for i in $(test_seq 6 10)
93 git branch commits/$i || return 1
95 git reset --hard commits/2 &&
96 git merge commits/4 &&
98 git reset --hard commits/4 &&
99 git merge commits/6 &&
100 git branch merge/2 &&
101 git commit-graph write --reachable &&
105 test_expect_success 'fork and fail to base a chain on a commit-graph file' '
106 test_when_finished rm -rf fork &&
110 rm .git/objects/info/commit-graph &&
111 echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
112 test_commit new-commit &&
113 git commit-graph write --reachable --split &&
114 test_path_is_file $graphdir/commit-graph-chain &&
115 test_line_count = 1 $graphdir/commit-graph-chain &&
116 verify_chain_files_exist $graphdir
120 test_expect_success 'add three more commits, write a tip graph' '
121 git reset --hard commits/3 &&
123 git merge commits/5 &&
125 git branch merge/3 &&
126 git commit-graph write --reachable --split &&
127 test_path_is_missing $infodir/commit-graph &&
128 test_path_is_file $graphdir/commit-graph-chain &&
129 ls $graphdir/graph-*.graph >graph-files &&
130 test_line_count = 2 graph-files &&
131 verify_chain_files_exist $graphdir
134 graph_git_behavior 'split commit-graph: merge 3 vs 2' merge/3 merge/2
136 test_expect_success 'add one commit, write a tip graph' '
138 git branch commits/11 &&
139 git commit-graph write --reachable --split &&
140 test_path_is_missing $infodir/commit-graph &&
141 test_path_is_file $graphdir/commit-graph-chain &&
142 ls $graphdir/graph-*.graph >graph-files &&
143 test_line_count = 3 graph-files &&
144 verify_chain_files_exist $graphdir
147 graph_git_behavior 'three-layer commit-graph: commit 11 vs 6' commits/11 commits/6
149 test_expect_success 'add one commit, write a merged graph' '
151 git branch commits/12 &&
152 git commit-graph write --reachable --split &&
153 test_path_is_file $graphdir/commit-graph-chain &&
154 test_line_count = 2 $graphdir/commit-graph-chain &&
155 ls $graphdir/graph-*.graph >graph-files &&
156 test_line_count = 2 graph-files &&
157 verify_chain_files_exist $graphdir
160 graph_git_behavior 'merged commit-graph: commit 12 vs 6' commits/12 commits/6
162 test_expect_success 'create fork and chain across alternate' '
166 git config core.commitGraph true &&
168 echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
170 git branch commits/13 &&
171 git commit-graph write --reachable --split &&
172 test_path_is_file $graphdir/commit-graph-chain &&
173 test_line_count = 3 $graphdir/commit-graph-chain &&
174 ls $graphdir/graph-*.graph >graph-files &&
175 test_line_count = 1 graph-files &&
176 git -c core.commitGraph=true rev-list HEAD >expect &&
177 git -c core.commitGraph=false rev-list HEAD >actual &&
178 test_cmp expect actual &&
180 git commit-graph write --reachable --split --object-dir=.git/objects/ &&
181 test_line_count = 3 $graphdir/commit-graph-chain &&
182 ls $graphdir/graph-*.graph >graph-files &&
183 test_line_count = 1 graph-files
187 graph_git_behavior 'alternate: commit 13 vs 6' commits/13 commits/6
189 test_expect_success 'test merge stragety constants' '
190 git clone . merge-2 &&
193 git config core.commitGraph true &&
194 test_line_count = 2 $graphdir/commit-graph-chain &&
196 git commit-graph write --reachable --split --size-multiple=2 &&
197 test_line_count = 3 $graphdir/commit-graph-chain
200 git clone . merge-10 &&
203 git config core.commitGraph true &&
204 test_line_count = 2 $graphdir/commit-graph-chain &&
206 git commit-graph write --reachable --split --size-multiple=10 &&
207 test_line_count = 1 $graphdir/commit-graph-chain &&
208 ls $graphdir/graph-*.graph >graph-files &&
209 test_line_count = 1 graph-files
211 git clone . merge-10-expire &&
213 cd merge-10-expire &&
214 git config core.commitGraph true &&
215 test_line_count = 2 $graphdir/commit-graph-chain &&
217 git commit-graph write --reachable --split --size-multiple=10 --expire-time=1980-01-01 &&
218 test_line_count = 1 $graphdir/commit-graph-chain &&
219 ls $graphdir/graph-*.graph >graph-files &&
220 test_line_count = 3 graph-files
222 git clone --no-hardlinks . max-commits &&
225 git config core.commitGraph true &&
226 test_line_count = 2 $graphdir/commit-graph-chain &&
229 git commit-graph write --reachable --split --max-commits=1 &&
230 test_line_count = 1 $graphdir/commit-graph-chain &&
231 ls $graphdir/graph-*.graph >graph-files &&
232 test_line_count = 1 graph-files
236 test_expect_success 'remove commit-graph-chain file after flattening' '
237 git clone . flatten &&
240 test_line_count = 2 $graphdir/commit-graph-chain &&
241 git commit-graph write --reachable &&
242 test_path_is_missing $graphdir/commit-graph-chain &&
243 ls $graphdir >graph-files &&
244 test_line_count = 0 graph-files
253 printf "$data" | dd of="$file" bs=1 seek="$pos" conv=notrunc
256 test_expect_success 'verify hashes along chain, even in shallow' '
257 git clone --no-hardlinks . verify &&
260 git commit-graph verify &&
261 base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
262 corrupt_file "$base_file" $(test_oid shallow) "\01" &&
263 test_must_fail git commit-graph verify --shallow 2>test_err &&
264 grep -v "^+" test_err >err &&
265 test_i18ngrep "incorrect checksum" err
269 test_expect_success 'verify --shallow does not check base contents' '
270 git clone --no-hardlinks . verify-shallow &&
273 git commit-graph verify &&
274 base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
275 corrupt_file "$base_file" 1000 "\01" &&
276 git commit-graph verify --shallow &&
277 test_must_fail git commit-graph verify 2>test_err &&
278 grep -v "^+" test_err >err &&
279 test_i18ngrep "incorrect checksum" err
283 test_expect_success 'warn on base graph chunk incorrect' '
284 git clone --no-hardlinks . base-chunk &&
287 git commit-graph verify &&
288 base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
289 corrupt_file "$base_file" $(test_oid base) "\01" &&
290 git commit-graph verify --shallow 2>test_err &&
291 grep -v "^+" test_err >err &&
292 test_i18ngrep "commit-graph chain does not match" err
296 test_expect_success 'verify after commit-graph-chain corruption' '
297 git clone --no-hardlinks . verify-chain &&
300 corrupt_file "$graphdir/commit-graph-chain" 60 "G" &&
301 git commit-graph verify 2>test_err &&
302 grep -v "^+" test_err >err &&
303 test_i18ngrep "invalid commit-graph chain" err &&
304 corrupt_file "$graphdir/commit-graph-chain" 60 "A" &&
305 git commit-graph verify 2>test_err &&
306 grep -v "^+" test_err >err &&
307 test_i18ngrep "unable to find all commit-graph files" err
311 test_expect_success 'verify across alternates' '
312 git clone --no-hardlinks . verify-alt &&
316 altdir="$(pwd)/../.git/objects" &&
317 echo "$altdir" >.git/objects/info/alternates &&
318 git commit-graph verify --object-dir="$altdir/" &&
320 git commit-graph write --reachable --split &&
321 tip_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
322 corrupt_file "$tip_file" 100 "\01" &&
323 test_must_fail git commit-graph verify --shallow 2>test_err &&
324 grep -v "^+" test_err >err &&
325 test_i18ngrep "commit-graph has incorrect fanout value" err
329 test_expect_success 'add octopus merge' '
330 git reset --hard commits/10 &&
331 git merge commits/3 commits/4 &&
332 git branch merge/octopus &&
333 git commit-graph write --reachable --split &&
334 git commit-graph verify --progress 2>err &&
335 test_line_count = 3 err &&
336 test_i18ngrep ! warning err &&
337 test_line_count = 3 $graphdir/commit-graph-chain
340 graph_git_behavior 'graph exists' merge/octopus commits/12
342 test_expect_success 'split across alternate where alternate is not split' '
343 git commit-graph write --reachable &&
344 test_path_is_file .git/objects/info/commit-graph &&
345 cp .git/objects/info/commit-graph . &&
346 git clone --no-hardlinks . alt-split &&
349 rm -f .git/objects/info/commit-graph &&
350 echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
352 git commit-graph write --reachable --split &&
353 test_line_count = 1 $graphdir/commit-graph-chain
355 test_cmp commit-graph .git/objects/info/commit-graph
358 while read mode modebits
360 test_expect_success POSIXPERM "split commit-graph respects core.sharedrepository $mode" '
361 rm -rf $graphdir $infodir/commit-graph &&
362 git reset --hard commits/1 &&
363 test_config core.sharedrepository "$mode" &&
364 git commit-graph write --split --reachable &&
365 ls $graphdir/graph-*.graph >graph-files &&
366 test_line_count = 1 graph-files &&
367 echo "$modebits" >expect &&
368 test_modebits $graphdir/graph-*.graph >actual &&
369 test_cmp expect actual