]>
Commit | Line | Data |
---|---|---|
f237c8b6 DS |
1 | #!/bin/sh |
2 | ||
3 | test_description='commit graph' | |
4 | . ./test-lib.sh | |
52e2e8d4 | 5 | . "$TEST_DIRECTORY"/lib-chunk.sh |
f237c8b6 | 6 | |
d5b873c8 GS |
7 | GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 |
8 | ||
6d209a01 | 9 | test_expect_success 'usage' ' |
367c5f36 | 10 | test_expect_code 129 git commit-graph write blah 2>err && |
6d209a01 ÆAB |
11 | test_expect_code 129 git commit-graph write verify |
12 | ' | |
13 | ||
367c5f36 ÆAB |
14 | test_expect_success 'usage shown without sub-command' ' |
15 | test_expect_code 129 git commit-graph 2>err && | |
1c3b0517 | 16 | grep usage: err |
367c5f36 ÆAB |
17 | ' |
18 | ||
19 | test_expect_success 'usage shown with an error on unknown sub-command' ' | |
20 | cat >expect <<-\EOF && | |
1c3b0517 | 21 | error: unknown subcommand: `unknown'\'' |
367c5f36 ÆAB |
22 | EOF |
23 | test_expect_code 129 git commit-graph unknown 2>stderr && | |
24 | grep error stderr >actual && | |
25 | test_cmp expect actual | |
26 | ' | |
27 | ||
51550d03 TB |
28 | objdir=".git/objects" |
29 | ||
f237c8b6 | 30 | test_expect_success 'setup full repo' ' |
51550d03 | 31 | git init full |
f237c8b6 DS |
32 | ' |
33 | ||
1f9becae TB |
34 | test_expect_success POSIXPERM 'tweak umask for modebit tests' ' |
35 | umask 022 | |
36 | ' | |
37 | ||
283e68c7 | 38 | test_expect_success 'verify graph with no graph file' ' |
51550d03 | 39 | git -C full commit-graph verify |
283e68c7 DS |
40 | ' |
41 | ||
f237c8b6 | 42 | test_expect_success 'write graph with no packs' ' |
51550d03 TB |
43 | git -C full commit-graph write --object-dir $objdir && |
44 | test_path_is_missing full/$objdir/info/commit-graph | |
f237c8b6 DS |
45 | ' |
46 | ||
7c5c9b9c | 47 | test_expect_success 'exit with correct error on bad input to --stdin-packs' ' |
e103f727 | 48 | echo doesnotexist >in && |
51550d03 TB |
49 | test_expect_code 1 git -C full commit-graph write --stdin-packs \ |
50 | <in 2>stderr && | |
6789275d | 51 | test_grep "error adding pack" stderr |
e103f727 DS |
52 | ' |
53 | ||
f237c8b6 | 54 | test_expect_success 'create commits and repack' ' |
f237c8b6 DS |
55 | for i in $(test_seq 3) |
56 | do | |
51550d03 TB |
57 | test_commit -C full $i && |
58 | git -C full branch commits/$i || return 1 | |
f237c8b6 | 59 | done && |
51550d03 | 60 | git -C full repack |
f237c8b6 DS |
61 | ' |
62 | ||
17925e06 | 63 | . "$TEST_DIRECTORY"/lib-commit-graph.sh |
177722b3 DS |
64 | |
65 | graph_git_behavior 'no graph' full commits/3 commits/1 | |
66 | ||
1f1304d4 | 67 | test_expect_success 'exit with correct error on bad input to --stdin-commits' ' |
2f00c355 | 68 | # invalid, non-hex OID |
51550d03 TB |
69 | echo HEAD | test_expect_code 1 git -C full commit-graph write \ |
70 | --stdin-commits 2>stderr && | |
6789275d | 71 | test_grep "unexpected non-hex object ID: HEAD" stderr && |
2f00c355 | 72 | # non-existent OID |
51550d03 TB |
73 | echo $ZERO_OID | test_expect_code 1 git -C full commit-graph write \ |
74 | --stdin-commits 2>stderr && | |
6789275d | 75 | test_grep "invalid object" stderr && |
2f00c355 | 76 | # valid commit and tree OID |
51550d03 TB |
77 | git -C full rev-parse HEAD HEAD^{tree} >in && |
78 | git -C full commit-graph write --stdin-commits <in && | |
79 | graph_read_expect -C full 3 generation_data | |
1f1304d4 TB |
80 | ' |
81 | ||
f237c8b6 | 82 | test_expect_success 'write graph' ' |
51550d03 TB |
83 | git -C full commit-graph write && |
84 | test_path_is_file full/$objdir/info/commit-graph && | |
85 | graph_read_expect -C full 3 generation_data | |
f237c8b6 DS |
86 | ' |
87 | ||
1f9becae | 88 | test_expect_success POSIXPERM 'write graph has correct permissions' ' |
51550d03 | 89 | test_path_is_file full/$objdir/info/commit-graph && |
1f9becae | 90 | echo "-r--r--r--" >expect && |
51550d03 | 91 | test_modebits full/$objdir/info/commit-graph >actual && |
1f9becae TB |
92 | test_cmp expect actual |
93 | ' | |
94 | ||
177722b3 DS |
95 | graph_git_behavior 'graph exists' full commits/3 commits/1 |
96 | ||
f237c8b6 | 97 | test_expect_success 'Add more commits' ' |
51550d03 | 98 | git -C full reset --hard commits/1 && |
f237c8b6 DS |
99 | for i in $(test_seq 4 5) |
100 | do | |
51550d03 TB |
101 | test_commit -C full $i && |
102 | git -C full branch commits/$i || return 1 | |
f237c8b6 | 103 | done && |
51550d03 | 104 | git -C full reset --hard commits/2 && |
f237c8b6 DS |
105 | for i in $(test_seq 6 7) |
106 | do | |
51550d03 TB |
107 | test_commit -C full $i && |
108 | git -C full branch commits/$i || return 1 | |
f237c8b6 | 109 | done && |
51550d03 TB |
110 | git -C full reset --hard commits/2 && |
111 | git -C full merge commits/4 && | |
112 | git -C full branch merge/1 && | |
113 | git -C full reset --hard commits/4 && | |
114 | git -C full merge commits/6 && | |
115 | git -C full branch merge/2 && | |
116 | git -C full reset --hard commits/3 && | |
117 | git -C full merge commits/5 commits/7 && | |
118 | git -C full branch merge/3 && | |
119 | git -C full repack | |
f237c8b6 DS |
120 | ' |
121 | ||
73716122 | 122 | test_expect_success 'commit-graph write progress off for redirected stderr' ' |
51550d03 | 123 | git -C full commit-graph write 2>err && |
6334c5ff | 124 | test_must_be_empty err |
73716122 GS |
125 | ' |
126 | ||
127 | test_expect_success 'commit-graph write force progress on for stderr' ' | |
51550d03 | 128 | GIT_PROGRESS_DELAY=0 git -C full commit-graph write --progress 2>err && |
73716122 GS |
129 | test_file_not_empty err |
130 | ' | |
131 | ||
132 | test_expect_success 'commit-graph write with the --no-progress option' ' | |
51550d03 | 133 | git -C full commit-graph write --no-progress 2>err && |
6334c5ff | 134 | test_must_be_empty err |
73716122 GS |
135 | ' |
136 | ||
94fbd914 | 137 | test_expect_success 'commit-graph write --stdin-commits progress off for redirected stderr' ' |
51550d03 TB |
138 | git -C full rev-parse commits/5 >in && |
139 | git -C full commit-graph write --stdin-commits <in 2>err && | |
94fbd914 TB |
140 | test_must_be_empty err |
141 | ' | |
142 | ||
143 | test_expect_success 'commit-graph write --stdin-commits force progress on for stderr' ' | |
51550d03 TB |
144 | git -C full rev-parse commits/5 >in && |
145 | GIT_PROGRESS_DELAY=0 git -C full commit-graph write --stdin-commits \ | |
146 | --progress <in 2>err && | |
6789275d | 147 | test_grep "Collecting commits from input" err |
94fbd914 TB |
148 | ' |
149 | ||
150 | test_expect_success 'commit-graph write --stdin-commits with the --no-progress option' ' | |
51550d03 TB |
151 | git -C full rev-parse commits/5 >in && |
152 | git -C full commit-graph write --stdin-commits --no-progress <in 2>err && | |
94fbd914 | 153 | test_must_be_empty err |
73716122 GS |
154 | ' |
155 | ||
156 | test_expect_success 'commit-graph verify progress off for redirected stderr' ' | |
51550d03 | 157 | git -C full commit-graph verify 2>err && |
6334c5ff | 158 | test_must_be_empty err |
73716122 GS |
159 | ' |
160 | ||
161 | test_expect_success 'commit-graph verify force progress on for stderr' ' | |
51550d03 | 162 | GIT_PROGRESS_DELAY=0 git -C full commit-graph verify --progress 2>err && |
73716122 GS |
163 | test_file_not_empty err |
164 | ' | |
165 | ||
166 | test_expect_success 'commit-graph verify with the --no-progress option' ' | |
51550d03 | 167 | git -C full commit-graph verify --no-progress 2>err && |
6334c5ff | 168 | test_must_be_empty err |
73716122 GS |
169 | ' |
170 | ||
f237c8b6 DS |
171 | # Current graph structure: |
172 | # | |
173 | # __M3___ | |
174 | # / | \ | |
175 | # 3 M1 5 M2 7 | |
176 | # |/ \|/ \| | |
177 | # 2 4 6 | |
178 | # |___/____/ | |
179 | # 1 | |
180 | ||
f237c8b6 | 181 | test_expect_success 'write graph with merges' ' |
51550d03 TB |
182 | git -C full commit-graph write && |
183 | test_path_is_file full/$objdir/info/commit-graph && | |
184 | graph_read_expect -C full 10 "generation_data extra_edges" | |
f237c8b6 DS |
185 | ' |
186 | ||
177722b3 DS |
187 | graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2 |
188 | graph_git_behavior 'merge 1 vs 3' full merge/1 merge/3 | |
189 | graph_git_behavior 'merge 2 vs 3' full merge/2 merge/3 | |
190 | ||
f237c8b6 | 191 | test_expect_success 'Add one more commit' ' |
51550d03 TB |
192 | test_commit -C full 8 && |
193 | git -C full branch commits/8 && | |
194 | ls full/$objdir/pack | grep idx >existing-idx && | |
195 | git -C full repack && | |
196 | ls full/$objdir/pack| grep idx | grep -v -f existing-idx >new-idx | |
f237c8b6 DS |
197 | ' |
198 | ||
199 | # Current graph structure: | |
200 | # | |
201 | # 8 | |
202 | # | | |
203 | # __M3___ | |
204 | # / | \ | |
205 | # 3 M1 5 M2 7 | |
206 | # |/ \|/ \| | |
207 | # 2 4 6 | |
208 | # |___/____/ | |
209 | # 1 | |
210 | ||
177722b3 DS |
211 | graph_git_behavior 'mixed mode, commit 8 vs merge 1' full commits/8 merge/1 |
212 | graph_git_behavior 'mixed mode, commit 8 vs merge 2' full commits/8 merge/2 | |
213 | ||
f237c8b6 | 214 | test_expect_success 'write graph with new commit' ' |
51550d03 TB |
215 | git -C full commit-graph write && |
216 | test_path_is_file full/$objdir/info/commit-graph && | |
217 | graph_read_expect -C full 11 "generation_data extra_edges" | |
f237c8b6 DS |
218 | ' |
219 | ||
177722b3 DS |
220 | graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1 |
221 | graph_git_behavior 'full graph, commit 8 vs merge 2' full commits/8 merge/2 | |
222 | ||
f237c8b6 | 223 | test_expect_success 'write graph with nothing new' ' |
51550d03 TB |
224 | git -C full commit-graph write && |
225 | test_path_is_file full/$objdir/info/commit-graph && | |
226 | graph_read_expect -C full 11 "generation_data extra_edges" | |
f237c8b6 DS |
227 | ' |
228 | ||
177722b3 DS |
229 | graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1 |
230 | graph_git_behavior 'cleared graph, commit 8 vs merge 2' full commits/8 merge/2 | |
231 | ||
049d51a2 | 232 | test_expect_success 'build graph from latest pack with closure' ' |
51550d03 TB |
233 | git -C full commit-graph write --stdin-packs <new-idx && |
234 | test_path_is_file full/$objdir/info/commit-graph && | |
235 | graph_read_expect -C full 9 "generation_data extra_edges" | |
049d51a2 DS |
236 | ' |
237 | ||
238 | graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1 | |
239 | graph_git_behavior 'graph from pack, commit 8 vs merge 2' full commits/8 merge/2 | |
240 | ||
3d5df01b | 241 | test_expect_success 'build graph from commits with closure' ' |
51550d03 TB |
242 | git -C full tag -a -m "merge" tag/merge merge/2 && |
243 | git -C full rev-parse tag/merge >commits-in && | |
244 | git -C full rev-parse merge/1 >>commits-in && | |
245 | git -C full commit-graph write --stdin-commits <commits-in && | |
246 | test_path_is_file full/$objdir/info/commit-graph && | |
247 | graph_read_expect -C full 6 "generation_data" | |
3d5df01b DS |
248 | ' |
249 | ||
250 | graph_git_behavior 'graph from commits, commit 8 vs merge 1' full commits/8 merge/1 | |
251 | graph_git_behavior 'graph from commits, commit 8 vs merge 2' full commits/8 merge/2 | |
252 | ||
7547b95b | 253 | test_expect_success 'build graph from commits with append' ' |
51550d03 TB |
254 | git -C full rev-parse merge/3 >in && |
255 | git -C full commit-graph write --stdin-commits --append <in && | |
256 | test_path_is_file full/$objdir/info/commit-graph && | |
257 | graph_read_expect -C full 10 "generation_data extra_edges" | |
7547b95b DS |
258 | ' |
259 | ||
260 | graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 | |
261 | graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 | |
262 | ||
59fb8770 | 263 | test_expect_success 'build graph using --reachable' ' |
51550d03 TB |
264 | git -C full commit-graph write --reachable && |
265 | test_path_is_file full/$objdir/info/commit-graph && | |
266 | graph_read_expect -C full 11 "generation_data extra_edges" | |
59fb8770 DS |
267 | ' |
268 | ||
269 | graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 | |
270 | graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 | |
271 | ||
f237c8b6 | 272 | test_expect_success 'setup bare repo' ' |
51550d03 | 273 | git clone --bare --no-local full bare |
f237c8b6 DS |
274 | ' |
275 | ||
177722b3 DS |
276 | graph_git_behavior 'bare repo, commit 8 vs merge 1' bare commits/8 merge/1 |
277 | graph_git_behavior 'bare repo, commit 8 vs merge 2' bare commits/8 merge/2 | |
278 | ||
f237c8b6 | 279 | test_expect_success 'write graph in bare repo' ' |
51550d03 TB |
280 | git -C bare commit-graph write && |
281 | test_path_is_file bare/objects/info/commit-graph && | |
282 | graph_read_expect -C bare 11 "generation_data extra_edges" | |
f237c8b6 DS |
283 | ' |
284 | ||
177722b3 DS |
285 | graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1 |
286 | graph_git_behavior 'bare repo with graph, commit 8 vs merge 2' bare commits/8 merge/2 | |
287 | ||
7adf5266 | 288 | test_expect_success 'perform fast-forward merge in full repo' ' |
51550d03 TB |
289 | git -C full checkout -b merge-5-to-8 commits/5 && |
290 | git -C full merge commits/8 && | |
291 | git -C full show-ref -s merge-5-to-8 >output && | |
292 | git -C full show-ref -s commits/8 >expect && | |
7adf5266 DS |
293 | test_cmp expect output |
294 | ' | |
295 | ||
d5d5d7b6 | 296 | test_expect_success 'check that gc computes commit-graph' ' |
51550d03 TB |
297 | test_commit -C full --no-tag blank && |
298 | git -C full commit-graph write --reachable && | |
299 | cp full/$objdir/info/commit-graph commit-graph-before-gc && | |
300 | git -C full reset --hard HEAD~1 && | |
301 | test_config -C full gc.writeCommitGraph true && | |
302 | git -C full gc && | |
303 | cp full/$objdir/info/commit-graph commit-graph-after-gc && | |
eb7cc5bc | 304 | ! test_cmp_bin commit-graph-before-gc commit-graph-after-gc && |
51550d03 TB |
305 | git -C full commit-graph write --reachable && |
306 | test_cmp_bin commit-graph-after-gc full/$objdir/info/commit-graph | |
d5d5d7b6 DS |
307 | ' |
308 | ||
d6538246 | 309 | test_expect_success 'replace-objects invalidates commit-graph' ' |
d6538246 DS |
310 | test_when_finished rm -rf replace && |
311 | git clone full replace && | |
312 | ( | |
313 | cd replace && | |
314 | git commit-graph write --reachable && | |
315 | test_path_is_file .git/objects/info/commit-graph && | |
316 | git replace HEAD~1 HEAD~2 && | |
095d112f | 317 | graph_git_two_modes "commit-graph verify" && |
d6538246 DS |
318 | git -c core.commitGraph=false log >expect && |
319 | git -c core.commitGraph=true log >actual && | |
320 | test_cmp expect actual && | |
321 | git commit-graph write --reachable && | |
322 | git -c core.commitGraph=false --no-replace-objects log >expect && | |
323 | git -c core.commitGraph=true --no-replace-objects log >actual && | |
324 | test_cmp expect actual && | |
325 | rm -rf .git/objects/info/commit-graph && | |
326 | git commit-graph write --reachable && | |
327 | test_path_is_file .git/objects/info/commit-graph | |
328 | ) | |
329 | ' | |
330 | ||
20fd6d57 | 331 | test_expect_success 'commit grafts invalidate commit-graph' ' |
20fd6d57 | 332 | test_when_finished rm -rf graft && |
93e02b6e | 333 | git clone --template= full graft && |
20fd6d57 DS |
334 | ( |
335 | cd graft && | |
336 | git commit-graph write --reachable && | |
337 | test_path_is_file .git/objects/info/commit-graph && | |
338 | H1=$(git rev-parse --verify HEAD~1) && | |
339 | H3=$(git rev-parse --verify HEAD~3) && | |
93e02b6e | 340 | mkdir .git/info && |
20fd6d57 DS |
341 | echo "$H1 $H3" >.git/info/grafts && |
342 | git -c core.commitGraph=false log >expect && | |
343 | git -c core.commitGraph=true log >actual && | |
344 | test_cmp expect actual && | |
345 | git commit-graph write --reachable && | |
346 | git -c core.commitGraph=false --no-replace-objects log >expect && | |
347 | git -c core.commitGraph=true --no-replace-objects log >actual && | |
348 | test_cmp expect actual && | |
349 | rm -rf .git/objects/info/commit-graph && | |
350 | git commit-graph write --reachable && | |
351 | test_path_is_missing .git/objects/info/commit-graph | |
352 | ) | |
353 | ' | |
354 | ||
355 | test_expect_success 'replace-objects invalidates commit-graph' ' | |
20fd6d57 DS |
356 | test_when_finished rm -rf shallow && |
357 | git clone --depth 2 "file://$TRASH_DIRECTORY/full" shallow && | |
358 | ( | |
359 | cd shallow && | |
360 | git commit-graph write --reachable && | |
361 | test_path_is_missing .git/objects/info/commit-graph && | |
362 | git fetch origin --unshallow && | |
363 | git commit-graph write --reachable && | |
364 | test_path_is_file .git/objects/info/commit-graph | |
365 | ) | |
366 | ' | |
367 | ||
665d70ad DS |
368 | test_expect_success 'warn on improper hash version' ' |
369 | git init --object-format=sha1 sha1 && | |
370 | ( | |
371 | cd sha1 && | |
372 | test_commit 1 && | |
373 | git commit-graph write --reachable && | |
374 | mv .git/objects/info/commit-graph ../cg-sha1 | |
375 | ) && | |
376 | git init --object-format=sha256 sha256 && | |
377 | ( | |
378 | cd sha256 && | |
379 | test_commit 1 && | |
380 | git commit-graph write --reachable && | |
381 | mv .git/objects/info/commit-graph ../cg-sha256 | |
382 | ) && | |
383 | ( | |
384 | cd sha1 && | |
385 | mv ../cg-sha256 .git/objects/info/commit-graph && | |
386 | git log -1 2>err && | |
6789275d | 387 | test_grep "commit-graph hash version 2 does not match version 1" err |
665d70ad DS |
388 | ) && |
389 | ( | |
390 | cd sha256 && | |
391 | mv ../cg-sha1 .git/objects/info/commit-graph && | |
392 | git log -1 2>err && | |
6789275d | 393 | test_grep "commit-graph hash version 1 does not match version 2" err |
665d70ad DS |
394 | ) |
395 | ' | |
396 | ||
75979d94 | 397 | test_expect_success TIME_IS_64BIT,TIME_T_IS_64BIT 'lower layers have overflow chunk' ' |
90cb1c47 | 398 | UNIX_EPOCH_ZERO="@0 +0000" && |
75979d94 | 399 | FUTURE_DATE="@4147483646 +0000" && |
51550d03 TB |
400 | rm -f full/.git/objects/info/commit-graph && |
401 | test_commit -C full --date "$FUTURE_DATE" future-1 && | |
402 | test_commit -C full --date "$UNIX_EPOCH_ZERO" old-1 && | |
403 | git -C full commit-graph write --reachable && | |
404 | test_commit -C full --date "$FUTURE_DATE" future-2 && | |
405 | test_commit -C full --date "$UNIX_EPOCH_ZERO" old-2 && | |
406 | git -C full commit-graph write --reachable --split=no-merge && | |
407 | test_commit -C full extra && | |
408 | git -C full commit-graph write --reachable --split=no-merge && | |
409 | git -C full commit-graph write --reachable && | |
410 | graph_read_expect -C full 16 \ | |
411 | "generation_data generation_data_overflow extra_edges" && | |
412 | mv full/.git/objects/info/commit-graph commit-graph-upgraded && | |
413 | git -C full commit-graph write --reachable && | |
414 | graph_read_expect -C full 16 \ | |
415 | "generation_data generation_data_overflow extra_edges" && | |
416 | test_cmp full/.git/objects/info/commit-graph commit-graph-upgraded | |
90cb1c47 DS |
417 | ' |
418 | ||
d9b9f8a6 DS |
419 | # the verify tests below expect the commit-graph to contain |
420 | # exactly the commits reachable from the commits/8 branch. | |
421 | # If the file changes the set of commits in the list, then the | |
422 | # offsets into the binary file will result in different edits | |
423 | # and the tests will likely break. | |
424 | ||
283e68c7 | 425 | test_expect_success 'git commit-graph verify' ' |
51550d03 TB |
426 | git -C full rev-parse commits/8 >in && |
427 | git -C full -c commitGraph.generationVersion=1 commit-graph write \ | |
428 | --stdin-commits <in && | |
429 | git -C full commit-graph verify >output && | |
430 | graph_read_expect -C full 9 extra_edges 1 | |
283e68c7 DS |
431 | ' |
432 | ||
96af91d4 | 433 | NUM_COMMITS=9 |
437787ae | 434 | NUM_OCTOPUS_EDGES=2 |
ae0c89d4 | 435 | HASH_LEN="$(test_oid rawsz)" |
d9b9f8a6 DS |
436 | GRAPH_BYTE_VERSION=4 |
437 | GRAPH_BYTE_HASH=5 | |
2bd0365f DS |
438 | GRAPH_BYTE_CHUNK_COUNT=6 |
439 | GRAPH_CHUNK_LOOKUP_OFFSET=8 | |
440 | GRAPH_CHUNK_LOOKUP_WIDTH=12 | |
441 | GRAPH_CHUNK_LOOKUP_ROWS=5 | |
442 | GRAPH_BYTE_OID_FANOUT_ID=$GRAPH_CHUNK_LOOKUP_OFFSET | |
443 | GRAPH_BYTE_OID_LOOKUP_ID=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ | |
444 | 1 * $GRAPH_CHUNK_LOOKUP_WIDTH)) | |
445 | GRAPH_BYTE_COMMIT_DATA_ID=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ | |
446 | 2 * $GRAPH_CHUNK_LOOKUP_WIDTH)) | |
9bda8467 DS |
447 | GRAPH_FANOUT_OFFSET=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ |
448 | $GRAPH_CHUNK_LOOKUP_WIDTH * $GRAPH_CHUNK_LOOKUP_ROWS)) | |
449 | GRAPH_BYTE_FANOUT1=$(($GRAPH_FANOUT_OFFSET + 4 * 4)) | |
450 | GRAPH_BYTE_FANOUT2=$(($GRAPH_FANOUT_OFFSET + 4 * 255)) | |
451 | GRAPH_OID_LOOKUP_OFFSET=$(($GRAPH_FANOUT_OFFSET + 4 * 256)) | |
452 | GRAPH_BYTE_OID_LOOKUP_ORDER=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 8)) | |
96af91d4 | 453 | GRAPH_BYTE_OID_LOOKUP_MISSING=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 4 + 10)) |
ce7629a3 | 454 | GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16)) |
2e3c0737 DS |
455 | GRAPH_COMMIT_DATA_OFFSET=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * $NUM_COMMITS)) |
456 | GRAPH_BYTE_COMMIT_TREE=$GRAPH_COMMIT_DATA_OFFSET | |
53614b13 DS |
457 | GRAPH_BYTE_COMMIT_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN)) |
458 | GRAPH_BYTE_COMMIT_EXTRA_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 4)) | |
459 | GRAPH_BYTE_COMMIT_WRONG_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 3)) | |
1373e547 | 460 | GRAPH_BYTE_COMMIT_GENERATION=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 11)) |
ce7629a3 | 461 | GRAPH_BYTE_COMMIT_GENERATION_LAST=$(($GRAPH_BYTE_COMMIT_GENERATION + $(($NUM_COMMITS - 1)) * $GRAPH_COMMIT_DATA_WIDTH)) |
88968ebf | 462 | GRAPH_BYTE_COMMIT_DATE=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 12)) |
437787ae DS |
463 | GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \ |
464 | $GRAPH_COMMIT_DATA_WIDTH * $NUM_COMMITS)) | |
465 | GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4)) | |
41df0e30 | 466 | GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES)) |
d9b9f8a6 | 467 | |
f6761faa | 468 | corrupt_graph_setup() { |
51550d03 TB |
469 | test_when_finished mv commit-graph-backup full/$objdir/info/commit-graph && |
470 | cp full/$objdir/info/commit-graph commit-graph-backup && | |
471 | chmod u+w full/$objdir/info/commit-graph | |
f6761faa ÆAB |
472 | } |
473 | ||
474 | corrupt_graph_verify() { | |
475 | grepstr=$1 | |
51550d03 | 476 | test_must_fail git -C full commit-graph verify 2>test_err && |
f6761faa | 477 | grep -v "^+" test_err >err && |
6789275d | 478 | test_grep "$grepstr" err && |
43d35618 ÆAB |
479 | if test "$2" != "no-copy" |
480 | then | |
51550d03 | 481 | cp full/$objdir/info/commit-graph commit-graph-pre-write-test |
43d35618 | 482 | fi && |
51550d03 TB |
483 | git -C full status --short && |
484 | GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git -C full commit-graph write && | |
485 | chmod u+w full/$objdir/info/commit-graph && | |
486 | git -C full commit-graph verify | |
f6761faa ÆAB |
487 | } |
488 | ||
d2b86fba | 489 | # usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>] |
d9b9f8a6 | 490 | # Manipulates the commit-graph file at the position |
d2b86fba JS |
491 | # by inserting the data, optionally zeroing the file |
492 | # starting at <zero_pos>, then runs 'git commit-graph verify' | |
d9b9f8a6 DS |
493 | # and places the output in the file 'err'. Test 'err' for |
494 | # the given string. | |
495 | corrupt_graph_and_verify() { | |
496 | pos=$1 | |
497 | data="${2:-\0}" | |
498 | grepstr=$3 | |
f6761faa | 499 | corrupt_graph_setup && |
51550d03 | 500 | orig_size=$(wc -c <full/$objdir/info/commit-graph) && |
d2b86fba | 501 | zero_pos=${4:-${orig_size}} && |
51550d03 TB |
502 | printf "$data" | dd of="full/$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && |
503 | dd of="full/$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null && | |
504 | test-tool genzeros $(($orig_size - $zero_pos)) >>"full/$objdir/info/commit-graph" && | |
f6761faa ÆAB |
505 | corrupt_graph_verify "$grepstr" |
506 | ||
d9b9f8a6 DS |
507 | } |
508 | ||
7b8ce9c6 ÆAB |
509 | test_expect_success POSIXPERM,SANITY 'detect permission problem' ' |
510 | corrupt_graph_setup && | |
51550d03 | 511 | chmod 000 full/$objdir/info/commit-graph && |
43d35618 | 512 | corrupt_graph_verify "Could not open" "no-copy" |
7b8ce9c6 ÆAB |
513 | ' |
514 | ||
945944ca ÆAB |
515 | test_expect_success 'detect too small' ' |
516 | corrupt_graph_setup && | |
51550d03 | 517 | echo "a small graph" >full/$objdir/info/commit-graph && |
945944ca ÆAB |
518 | corrupt_graph_verify "too small" |
519 | ' | |
520 | ||
d9b9f8a6 DS |
521 | test_expect_success 'detect bad signature' ' |
522 | corrupt_graph_and_verify 0 "\0" \ | |
523 | "graph signature" | |
524 | ' | |
525 | ||
526 | test_expect_success 'detect bad version' ' | |
527 | corrupt_graph_and_verify $GRAPH_BYTE_VERSION "\02" \ | |
528 | "graph version" | |
529 | ' | |
530 | ||
531 | test_expect_success 'detect bad hash version' ' | |
1d86c8f0 | 532 | corrupt_graph_and_verify $GRAPH_BYTE_HASH "\03" \ |
d9b9f8a6 DS |
533 | "hash version" |
534 | ' | |
535 | ||
2bd0365f | 536 | test_expect_success 'detect low chunk count' ' |
cb9daf16 | 537 | corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\01" \ |
2692c2f6 | 538 | "final chunk has non-zero id" |
2bd0365f DS |
539 | ' |
540 | ||
541 | test_expect_success 'detect missing OID fanout chunk' ' | |
542 | corrupt_graph_and_verify $GRAPH_BYTE_OID_FANOUT_ID "\0" \ | |
93d29247 | 543 | "commit-graph required OID fanout chunk missing or corrupted" |
2bd0365f DS |
544 | ' |
545 | ||
546 | test_expect_success 'detect missing OID lookup chunk' ' | |
547 | corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_ID "\0" \ | |
93d29247 | 548 | "commit-graph required OID lookup chunk missing or corrupted" |
2bd0365f DS |
549 | ' |
550 | ||
551 | test_expect_success 'detect missing commit data chunk' ' | |
552 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATA_ID "\0" \ | |
93d29247 | 553 | "commit-graph required commit data chunk missing or corrupted" |
2bd0365f DS |
554 | ' |
555 | ||
9bda8467 DS |
556 | test_expect_success 'detect incorrect fanout' ' |
557 | corrupt_graph_and_verify $GRAPH_BYTE_FANOUT1 "\01" \ | |
558 | "fanout value" | |
559 | ' | |
560 | ||
561 | test_expect_success 'detect incorrect fanout final value' ' | |
562 | corrupt_graph_and_verify $GRAPH_BYTE_FANOUT2 "\01" \ | |
d3b6f6c6 | 563 | "OID lookup chunk is the wrong size" |
9bda8467 DS |
564 | ' |
565 | ||
566 | test_expect_success 'detect incorrect OID order' ' | |
567 | corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_ORDER "\01" \ | |
568 | "incorrect OID order" | |
569 | ' | |
570 | ||
96af91d4 DS |
571 | test_expect_success 'detect OID not in object database' ' |
572 | corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_MISSING "\01" \ | |
573 | "from object database" | |
574 | ' | |
575 | ||
2e3c0737 DS |
576 | test_expect_success 'detect incorrect tree OID' ' |
577 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_TREE "\01" \ | |
578 | "root tree OID for commit" | |
579 | ' | |
580 | ||
53614b13 DS |
581 | test_expect_success 'detect incorrect parent int-id' ' |
582 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_PARENT "\01" \ | |
583 | "invalid parent" | |
584 | ' | |
585 | ||
586 | test_expect_success 'detect extra parent int-id' ' | |
587 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_EXTRA_PARENT "\00" \ | |
588 | "is too long" | |
589 | ' | |
590 | ||
591 | test_expect_success 'detect wrong parent' ' | |
592 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_WRONG_PARENT "\01" \ | |
593 | "commit-graph parent for" | |
594 | ' | |
595 | ||
1373e547 DS |
596 | test_expect_success 'detect incorrect generation number' ' |
597 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\070" \ | |
598 | "generation for commit" | |
599 | ' | |
600 | ||
88968ebf DS |
601 | test_expect_success 'detect incorrect commit date' ' |
602 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATE "\01" \ | |
603 | "commit date" | |
604 | ' | |
605 | ||
437787ae DS |
606 | test_expect_success 'detect incorrect parent for octopus merge' ' |
607 | corrupt_graph_and_verify $GRAPH_BYTE_OCTOPUS "\01" \ | |
608 | "invalid parent" | |
609 | ' | |
610 | ||
41df0e30 DS |
611 | test_expect_success 'detect invalid checksum hash' ' |
612 | corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ | |
613 | "incorrect checksum" | |
614 | ' | |
615 | ||
d2b86fba JS |
616 | test_expect_success 'detect incorrect chunk count' ' |
617 | corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\377" \ | |
2ad4f1a7 SG |
618 | "commit-graph file is too small to hold [0-9]* chunks" \ |
619 | $GRAPH_CHUNK_LOOKUP_OFFSET | |
d2b86fba JS |
620 | ' |
621 | ||
ce7629a3 TB |
622 | test_expect_success 'detect mixed generation numbers (non-zero to zero)' ' |
623 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION_LAST "\0\0\0\0" \ | |
db6044d7 | 624 | "both zero and non-zero generations" |
ce7629a3 TB |
625 | ' |
626 | ||
627 | test_expect_success 'detect mixed generation numbers (zero to non-zero)' ' | |
628 | corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\0\0\0\0" \ | |
db6044d7 | 629 | "both zero and non-zero generations" |
ce7629a3 TB |
630 | ' |
631 | ||
f30e4d85 | 632 | test_expect_success 'git fsck (checks commit-graph when config set to true)' ' |
51550d03 | 633 | git -C full fsck && |
e0fd51e1 DS |
634 | corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ |
635 | "incorrect checksum" && | |
51550d03 TB |
636 | cp commit-graph-pre-write-test full/$objdir/info/commit-graph && |
637 | test_must_fail git -C full -c core.commitGraph=true fsck | |
f30e4d85 GC |
638 | ' |
639 | ||
640 | test_expect_success 'git fsck (ignores commit-graph when config set to false)' ' | |
51550d03 | 641 | git -C full fsck && |
f30e4d85 GC |
642 | corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ |
643 | "incorrect checksum" && | |
51550d03 TB |
644 | cp commit-graph-pre-write-test full/$objdir/info/commit-graph && |
645 | git -C full -c core.commitGraph=false fsck | |
f30e4d85 GC |
646 | ' |
647 | ||
648 | test_expect_success 'git fsck (checks commit-graph when config unset)' ' | |
51550d03 | 649 | test_when_finished "git -C full config core.commitGraph true" && |
f30e4d85 | 650 | |
51550d03 | 651 | git -C full fsck && |
f30e4d85 GC |
652 | corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ |
653 | "incorrect checksum" && | |
51550d03 TB |
654 | test_unconfig -C full core.commitGraph && |
655 | cp commit-graph-pre-write-test full/$objdir/info/commit-graph && | |
656 | test_must_fail git -C full fsck | |
e0fd51e1 DS |
657 | ' |
658 | ||
eda206f6 TB |
659 | test_expect_success 'git fsck shows commit-graph output with --progress' ' |
660 | git -C "$TRASH_DIRECTORY/full" fsck --progress 2>err && | |
661 | grep "Verifying commits in commit graph" err | |
662 | ' | |
663 | ||
664 | test_expect_success 'git fsck suppresses commit-graph output with --no-progress' ' | |
665 | git -C "$TRASH_DIRECTORY/full" fsck --no-progress 2>err && | |
666 | ! grep "Verifying commits in commit graph" err | |
667 | ' | |
668 | ||
dade47c0 JT |
669 | test_expect_success 'setup non-the_repository tests' ' |
670 | rm -rf repo && | |
671 | git init repo && | |
672 | test_commit -C repo one && | |
673 | test_commit -C repo two && | |
674 | git -C repo config core.commitGraph true && | |
675 | git -C repo rev-parse two | \ | |
676 | git -C repo commit-graph write --stdin-commits | |
677 | ' | |
678 | ||
679 | test_expect_success 'parse_commit_in_graph works for non-the_repository' ' | |
680 | test-tool repository parse_commit_in_graph \ | |
681 | repo/.git repo "$(git -C repo rev-parse two)" >actual && | |
3c458630 SG |
682 | { |
683 | git -C repo log --pretty=format:"%ct " -1 && | |
684 | git -C repo rev-parse one | |
685 | } >expect && | |
dade47c0 JT |
686 | test_cmp expect actual && |
687 | ||
688 | test-tool repository parse_commit_in_graph \ | |
689 | repo/.git repo "$(git -C repo rev-parse one)" >actual && | |
3c458630 | 690 | git -C repo log --pretty="%ct" -1 one >expect && |
dade47c0 JT |
691 | test_cmp expect actual |
692 | ' | |
693 | ||
694 | test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' | |
695 | test-tool repository get_commit_tree_in_graph \ | |
696 | repo/.git repo "$(git -C repo rev-parse two)" >actual && | |
3c458630 | 697 | git -C repo rev-parse two^{tree} >expect && |
dade47c0 JT |
698 | test_cmp expect actual && |
699 | ||
700 | test-tool repository get_commit_tree_in_graph \ | |
701 | repo/.git repo "$(git -C repo rev-parse one)" >actual && | |
3c458630 | 702 | git -C repo rev-parse one^{tree} >expect && |
dade47c0 JT |
703 | test_cmp expect actual |
704 | ' | |
705 | ||
16749b8d | 706 | test_expect_success 'corrupt commit-graph write (broken parent)' ' |
23424ea7 TB |
707 | rm -rf repo && |
708 | git init repo && | |
709 | ( | |
710 | cd repo && | |
711 | empty="$(git mktree </dev/null)" && | |
712 | cat >broken <<-EOF && | |
713 | tree $empty | |
48c10cc0 | 714 | parent $ZERO_OID |
23424ea7 TB |
715 | author whatever <whatever@example.com> 1234 -0000 |
716 | committer whatever <whatever@example.com> 1234 -0000 | |
717 | ||
718 | broken commit | |
719 | EOF | |
720 | broken="$(git hash-object -w -t commit --literally broken)" && | |
721 | git commit-tree -p "$broken" -m "good commit" "$empty" >good && | |
722 | test_must_fail git commit-graph write --stdin-commits \ | |
723 | <good 2>test_err && | |
6789275d | 724 | test_grep "unable to parse commit" test_err |
23424ea7 TB |
725 | ) |
726 | ' | |
727 | ||
806278de | 728 | test_expect_success 'corrupt commit-graph write (missing tree)' ' |
23424ea7 TB |
729 | rm -rf repo && |
730 | git init repo && | |
731 | ( | |
732 | cd repo && | |
733 | tree="$(git mktree </dev/null)" && | |
734 | cat >broken <<-EOF && | |
48c10cc0 | 735 | parent $ZERO_OID |
23424ea7 TB |
736 | author whatever <whatever@example.com> 1234 -0000 |
737 | committer whatever <whatever@example.com> 1234 -0000 | |
738 | ||
739 | broken commit | |
740 | EOF | |
741 | broken="$(git hash-object -w -t commit --literally broken)" && | |
742 | git commit-tree -p "$broken" -m "good" "$tree" >good && | |
743 | test_must_fail git commit-graph write --stdin-commits \ | |
744 | <good 2>test_err && | |
6789275d | 745 | test_grep "unable to parse commit" test_err |
23424ea7 TB |
746 | ) |
747 | ' | |
748 | ||
e8b63005 AK |
749 | # We test the overflow-related code with the following repo history: |
750 | # | |
751 | # 4:F - 5:N - 6:U | |
752 | # / \ | |
753 | # 1:U - 2:N - 3:U M:N | |
754 | # \ / | |
755 | # 7:N - 8:F - 9:N | |
756 | # | |
757 | # Here the commits denoted by U have committer date of zero seconds | |
758 | # since Unix epoch, the commits denoted by N have committer date | |
759 | # starting from 1112354055 seconds since Unix epoch (default committer | |
760 | # date for the test suite), and the commits denoted by F have committer | |
761 | # date of (2 ^ 31 - 2) seconds since Unix epoch. | |
762 | # | |
763 | # The largest offset observed is 2 ^ 31, just large enough to overflow. | |
764 | # | |
765 | ||
766 | test_expect_success 'set up and verify repo with generation data overflow chunk' ' | |
e8b63005 AK |
767 | UNIX_EPOCH_ZERO="@0 +0000" && |
768 | FUTURE_DATE="@2147483646 +0000" && | |
51550d03 TB |
769 | |
770 | git init repo && | |
771 | ( | |
772 | cd repo && | |
773 | ||
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 | ) | |
e8b63005 AK |
794 | ' |
795 | ||
796 | graph_git_behavior 'generation data overflow chunk repo' repo left right | |
797 | ||
9550f6c1 | 798 | test_expect_success 'overflow during generation version upgrade' ' |
2dd804cd TB |
799 | git init overflow-v2-upgrade && |
800 | ( | |
801 | cd overflow-v2-upgrade && | |
802 | ||
803 | # This commit will have a date at two seconds past the Epoch, | |
804 | # and a (v1) generation number of 1, since it is a root commit. | |
805 | # | |
806 | # The offset will then be computed as 1-2, which will underflow | |
807 | # to 2^31, which is greater than the v2 offset small limit of | |
808 | # 2^31-1. | |
809 | # | |
810 | # This is sufficient to need a large offset table for the v2 | |
811 | # generation numbers. | |
812 | test_commit --date "@2 +0000" base && | |
813 | git repack -d && | |
814 | ||
815 | # Test that upgrading from generation v1 to v2 correctly | |
816 | # produces the overflow table. | |
817 | git -c commitGraph.generationVersion=1 commit-graph write && | |
818 | git -c commitGraph.generationVersion=2 commit-graph write \ | |
819 | --changed-paths && | |
820 | ||
821 | git rev-list --all | |
822 | ) | |
823 | ' | |
824 | ||
52e2e8d4 JK |
825 | corrupt_chunk () { |
826 | graph=full/.git/objects/info/commit-graph && | |
827 | test_when_finished "rm -rf $graph" && | |
828 | git -C full commit-graph write --reachable && | |
829 | corrupt_chunk_file $graph "$@" | |
830 | } | |
831 | ||
832 | check_corrupt_chunk () { | |
833 | corrupt_chunk "$@" && | |
834 | git -C full -c core.commitGraph=false log >expect.out && | |
835 | git -C full -c core.commitGraph=true log >out 2>err && | |
836 | test_cmp expect.out out | |
837 | } | |
838 | ||
839 | test_expect_success 'reader notices too-small oid fanout chunk' ' | |
840 | # make it big enough that the graph file is plausible, | |
841 | # otherwise we hit an earlier check | |
842 | check_corrupt_chunk OIDF clear $(printf "000000%02x" $(test_seq 250)) && | |
843 | cat >expect.err <<-\EOF && | |
844 | error: commit-graph oid fanout chunk is wrong size | |
93d29247 | 845 | error: commit-graph required OID fanout chunk missing or corrupted |
52e2e8d4 JK |
846 | EOF |
847 | test_cmp expect.err err | |
848 | ' | |
849 | ||
4169d896 JK |
850 | test_expect_success 'reader notices fanout/lookup table mismatch' ' |
851 | check_corrupt_chunk OIDF 1020 "FFFFFFFF" && | |
852 | cat >expect.err <<-\EOF && | |
d3b6f6c6 JK |
853 | error: commit-graph OID lookup chunk is the wrong size |
854 | error: commit-graph required OID lookup chunk missing or corrupted | |
4169d896 JK |
855 | EOF |
856 | test_cmp expect.err err | |
857 | ' | |
858 | ||
859 | test_expect_success 'reader notices out-of-bounds fanout' ' | |
860 | # Rather than try to corrupt a specific hash, we will just | |
861 | # wreck them all. But we cannot just set them all to 0xFFFFFFFF or | |
862 | # similar, as they are used for hi/lo starts in a binary search (so if | |
863 | # they are identical, that indicates that the search should abort | |
864 | # immediately). Instead, we will give them high values that differ by | |
865 | # 2^24, ensuring that any that are used would cause an out-of-bounds | |
866 | # read. | |
867 | check_corrupt_chunk OIDF 0 $(printf "%02x000000" $(test_seq 0 254)) && | |
868 | cat >expect.err <<-\EOF && | |
869 | error: commit-graph fanout values out of order | |
06fb135f | 870 | error: commit-graph required OID fanout chunk missing or corrupted |
4169d896 JK |
871 | EOF |
872 | test_cmp expect.err err | |
873 | ' | |
874 | ||
b72df612 JK |
875 | test_expect_success 'reader notices too-small commit data chunk' ' |
876 | check_corrupt_chunk CDAT clear 00000000 && | |
877 | cat >expect.err <<-\EOF && | |
878 | error: commit-graph commit data chunk is wrong size | |
93d29247 | 879 | error: commit-graph required commit data chunk missing or corrupted |
b72df612 JK |
880 | EOF |
881 | test_cmp expect.err err | |
882 | ' | |
883 | ||
9622610e JK |
884 | test_expect_success 'reader notices out-of-bounds extra edge' ' |
885 | check_corrupt_chunk EDGE clear && | |
886 | cat >expect.err <<-\EOF && | |
887 | error: commit-graph extra-edges pointer out of bounds | |
888 | EOF | |
889 | test_cmp expect.err err | |
890 | ' | |
891 | ||
4a3c3466 JK |
892 | test_expect_success 'reader notices too-small generations chunk' ' |
893 | check_corrupt_chunk GDA2 clear 00000000 && | |
894 | cat >expect.err <<-\EOF && | |
895 | error: commit-graph generations chunk is wrong size | |
896 | EOF | |
897 | test_cmp expect.err err | |
898 | ' | |
899 | ||
e04838ea PS |
900 | test_expect_success 'stale commit cannot be parsed when given directly' ' |
901 | test_when_finished "rm -rf repo" && | |
902 | git init repo && | |
903 | ( | |
904 | cd repo && | |
905 | test_commit A && | |
906 | test_commit B && | |
907 | git commit-graph write --reachable && | |
908 | ||
909 | oid=$(git rev-parse B) && | |
910 | rm .git/objects/"$(test_oid_to_path "$oid")" && | |
911 | ||
912 | # Verify that it is possible to read the commit from the | |
913 | # commit graph when not being paranoid, ... | |
b1df3b38 | 914 | git rev-list B && |
e04838ea PS |
915 | # ... but parsing the commit when double checking that |
916 | # it actually exists in the object database should fail. | |
b1df3b38 | 917 | test_must_fail env GIT_COMMIT_GRAPH_PARANOIA=true git rev-list -1 B |
e04838ea PS |
918 | ) |
919 | ' | |
920 | ||
7a5d6044 PS |
921 | test_expect_success 'stale commit cannot be parsed when traversing graph' ' |
922 | test_when_finished "rm -rf repo" && | |
923 | git init repo && | |
924 | ( | |
925 | cd repo && | |
926 | ||
927 | test_commit A && | |
928 | test_commit B && | |
929 | test_commit C && | |
930 | git commit-graph write --reachable && | |
931 | ||
932 | # Corrupt the repository by deleting the intermediate commit | |
933 | # object. Commands should notice that this object is absent and | |
934 | # thus that the repository is corrupt even if the commit graph | |
935 | # exists. | |
936 | oid=$(git rev-parse B) && | |
937 | rm .git/objects/"$(test_oid_to_path "$oid")" && | |
938 | ||
939 | # Again, we should be able to parse the commit when not | |
940 | # being paranoid about commit graph staleness... | |
b1df3b38 | 941 | git rev-parse HEAD~2 && |
7a5d6044 | 942 | # ... but fail when we are paranoid. |
b1df3b38 | 943 | test_must_fail env GIT_COMMIT_GRAPH_PARANOIA=true git rev-parse HEAD~2 2>error && |
7a5d6044 PS |
944 | grep "error: commit $oid exists in commit-graph but not in the object database" error |
945 | ) | |
946 | ' | |
947 | ||
f237c8b6 | 948 | test_done |