Post 2.46-rc0 batch #1
[git/gitster.git] / t / t4216-log-bloom.sh
blob3f163dc396980f4dacce34b5209f50b870d5092f
1 #!/bin/sh
3 test_description='git log for a path with Bloom filters'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7 . ./test-lib.sh
8 . "$TEST_DIRECTORY"/lib-chunk.sh
10 GIT_TEST_COMMIT_GRAPH=0
11 GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0
13 test_expect_success 'setup test - repo, commits, commit graph, log outputs' '
14 git init &&
15 mkdir A A/B A/B/C &&
16 test_commit c1 A/file1 &&
17 test_commit c2 A/B/file2 &&
18 test_commit c3 A/B/C/file3 &&
19 test_commit c4 A/file1 &&
20 test_commit c5 A/B/file2 &&
21 test_commit c6 A/B/C/file3 &&
22 test_commit c7 A/file1 &&
23 test_commit c8 A/B/file2 &&
24 test_commit c9 A/B/C/file3 &&
25 test_commit c10 file_to_be_deleted &&
26 git checkout -b side HEAD~4 &&
27 test_commit side-1 file4 &&
28 git checkout main &&
29 git merge side &&
30 test_commit c11 file5 &&
31 mv file5 file5_renamed &&
32 git add file5_renamed &&
33 git commit -m "rename" &&
34 rm file_to_be_deleted &&
35 git add . &&
36 git commit -m "file removed" &&
37 git commit --allow-empty -m "empty" &&
38 git commit-graph write --reachable --changed-paths &&
40 test_oid_cache <<-EOF
41 oid_version sha1:1
42 oid_version sha256:2
43 EOF
46 graph_read_expect () {
47 NUM_CHUNKS=6
48 cat >expect <<- EOF
49 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
50 num_commits: $1
51 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
52 options: bloom(1,10,7) read_generation_data
53 EOF
54 test-tool read-graph >actual &&
55 test_cmp expect actual
58 test_expect_success 'commit-graph write wrote out the bloom chunks' '
59 graph_read_expect 16
62 # Turn off any inherited trace2 settings for this test.
63 sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT
64 sane_unset GIT_TRACE2_PERF_BRIEF
65 sane_unset GIT_TRACE2_CONFIG_PARAMS
67 setup () {
68 rm -f "$TRASH_DIRECTORY/trace.perf" &&
69 git -c core.commitGraph=false log --pretty="format:%s" $1 >log_wo_bloom &&
70 GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.perf" git -c core.commitGraph=true log --pretty="format:%s" $1 >log_w_bloom
73 test_bloom_filters_used () {
74 log_args=$1
75 bloom_trace_prefix="statistics:{\"filter_not_present\":${2:-0},\"maybe\""
76 setup "$log_args" &&
77 grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" &&
78 test_cmp log_wo_bloom log_w_bloom &&
79 test_path_is_file "$TRASH_DIRECTORY/trace.perf"
82 test_bloom_filters_not_used () {
83 log_args=$1
84 setup "$log_args" &&
86 if grep -q "statistics:{\"filter_not_present\":" "$TRASH_DIRECTORY/trace.perf"
87 then
88 # if the Bloom filter system is initialized, ensure that no
89 # filters were used
90 data="statistics:{"
91 # unusable filters (e.g., those computed with a
92 # different value of commitGraph.changedPathsVersion)
93 # are counted in the filter_not_present bucket, so any
94 # value is OK there.
95 data="$data\"filter_not_present\":[0-9][0-9]*,"
96 data="$data\"maybe\":0,"
97 data="$data\"definitely_not\":0,"
98 data="$data\"false_positive\":0}"
100 grep -q "$data" "$TRASH_DIRECTORY/trace.perf"
101 fi &&
102 test_cmp log_wo_bloom log_w_bloom
105 for path in A A/B A/B/C A/file1 A/B/file2 A/B/C/file3 file4 file5 file5_renamed file_to_be_deleted
107 for option in "" \
108 "--all" \
109 "--full-history" \
110 "--full-history --simplify-merges" \
111 "--simplify-merges" \
112 "--simplify-by-decoration" \
113 "--follow" \
114 "--first-parent" \
115 "--topo-order" \
116 "--date-order" \
117 "--author-date-order" \
118 "--ancestry-path side..main"
120 test_expect_success "git log option: $option for path: $path" '
121 test_bloom_filters_used "$option -- $path" &&
122 test_config commitgraph.readChangedPaths false &&
123 test_bloom_filters_not_used "$option -- $path"
125 done
126 done
128 test_expect_success 'git log -- folder works with and without the trailing slash' '
129 test_bloom_filters_used "-- A" &&
130 test_bloom_filters_used "-- A/"
133 test_expect_success 'git log for path that does not exist. ' '
134 test_bloom_filters_used "-- path_does_not_exist"
137 test_expect_success 'git log with --walk-reflogs does not use Bloom filters' '
138 test_bloom_filters_not_used "--walk-reflogs -- A"
141 test_expect_success 'git log -- multiple path specs does not use Bloom filters' '
142 test_bloom_filters_not_used "-- file4 A/file1"
145 test_expect_success 'git log -- "." pathspec at root does not use Bloom filters' '
146 test_bloom_filters_not_used "-- ."
149 test_expect_success 'git log with wildcard that resolves to a single path uses Bloom filters' '
150 test_bloom_filters_used "-- *4" &&
151 test_bloom_filters_used "-- *renamed"
154 test_expect_success 'git log with wildcard that resolves to a multiple paths does not uses Bloom filters' '
155 test_bloom_filters_not_used "-- *" &&
156 test_bloom_filters_not_used "-- file*"
159 test_expect_success 'setup - add commit-graph to the chain without Bloom filters' '
160 test_commit c14 A/anotherFile2 &&
161 test_commit c15 A/B/anotherFile2 &&
162 test_commit c16 A/B/C/anotherFile2 &&
163 git commit-graph write --reachable --split --no-changed-paths &&
164 test_line_count = 2 .git/objects/info/commit-graphs/commit-graph-chain
167 test_expect_success 'use Bloom filters even if the latest graph does not have Bloom filters' '
168 # Ensure that the number of empty filters is equal to the number of
169 # filters in the latest graph layer to prove that they are loaded (and
170 # ignored).
171 test_bloom_filters_used "-- A/B" 3
174 test_expect_success 'setup - add commit-graph to the chain with Bloom filters' '
175 test_commit c17 A/anotherFile3 &&
176 git commit-graph write --reachable --changed-paths --split &&
177 test_line_count = 3 .git/objects/info/commit-graphs/commit-graph-chain
180 test_bloom_filters_used_when_some_filters_are_missing () {
181 log_args=$1
182 bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":10"
183 setup "$log_args" &&
184 grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" &&
185 test_cmp log_wo_bloom log_w_bloom
188 test_expect_success 'Use Bloom filters if they exist in the latest but not all commit graphs in the chain.' '
189 test_bloom_filters_used_when_some_filters_are_missing "-- A/B"
192 test_expect_success 'persist filter settings' '
193 test_when_finished rm -rf .git/objects/info/commit-graph* &&
194 rm -rf .git/objects/info/commit-graph* &&
195 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
196 GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=9 \
197 GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY=15 \
198 git commit-graph write --reachable --changed-paths &&
199 grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2.txt &&
200 GIT_TRACE2_EVENT="$(pwd)/trace2-auto.txt" \
201 git commit-graph write --reachable --changed-paths &&
202 grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2-auto.txt
205 test_max_changed_paths () {
206 grep "\"max_changed_paths\":$1" $2
209 test_filter_not_computed () {
210 grep "\"key\":\"filter-not-computed\",\"value\":\"$1\"" $2
213 test_filter_computed () {
214 grep "\"key\":\"filter-computed\",\"value\":\"$1\"" $2
217 test_filter_trunc_empty () {
218 grep "\"key\":\"filter-trunc-empty\",\"value\":\"$1\"" $2
221 test_filter_trunc_large () {
222 grep "\"key\":\"filter-trunc-large\",\"value\":\"$1\"" $2
225 test_filter_upgraded () {
226 grep "\"key\":\"filter-upgraded\",\"value\":\"$1\"" $2
229 test_expect_success 'correctly report changes over limit' '
230 git init limits &&
232 cd limits &&
233 mkdir d &&
234 mkdir d/e &&
236 for i in $(test_seq 1 2)
238 printf $i >d/file$i.txt &&
239 printf $i >d/e/file$i.txt || return 1
240 done &&
242 mkdir mode &&
243 printf bash >mode/script.sh &&
245 mkdir foo &&
246 touch foo/bar &&
247 touch foo.txt &&
249 git add d foo foo.txt mode &&
250 git commit -m "files" &&
252 # Commit has 7 file and 4 directory adds
253 GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \
254 GIT_TRACE2_EVENT="$(pwd)/trace" \
255 git commit-graph write --reachable --changed-paths &&
256 test_max_changed_paths 10 trace &&
257 test_filter_computed 1 trace &&
258 test_filter_trunc_large 1 trace &&
260 for path in $(git ls-tree -r --name-only HEAD)
262 git -c commitGraph.readChangedPaths=false log \
263 -- $path >expect &&
264 git log -- $path >actual &&
265 test_cmp expect actual || return 1
266 done &&
268 # Make a variety of path changes
269 printf new1 >d/e/file1.txt &&
270 printf new2 >d/file2.txt &&
271 rm d/e/file2.txt &&
272 rm -r foo &&
273 printf text >foo &&
274 mkdir f &&
275 printf new1 >f/file1.txt &&
277 # including a mode-only change (counts as modified)
278 git update-index --chmod=+x mode/script.sh &&
280 git add foo d f &&
281 git commit -m "complicated" &&
283 # start from scratch and rebuild
284 rm -f .git/objects/info/commit-graph &&
285 GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \
286 GIT_TRACE2_EVENT="$(pwd)/trace-edit" \
287 git commit-graph write --reachable --changed-paths &&
288 test_max_changed_paths 10 trace-edit &&
289 test_filter_computed 2 trace-edit &&
290 test_filter_trunc_large 2 trace-edit &&
292 for path in $(git ls-tree -r --name-only HEAD)
294 git -c commitGraph.readChangedPaths=false log \
295 -- $path >expect &&
296 git log -- $path >actual &&
297 test_cmp expect actual || return 1
298 done &&
300 # start from scratch and rebuild
301 rm -f .git/objects/info/commit-graph &&
302 GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=11 \
303 GIT_TRACE2_EVENT="$(pwd)/trace-update" \
304 git commit-graph write --reachable --changed-paths &&
305 test_max_changed_paths 11 trace-update &&
306 test_filter_computed 2 trace-update &&
307 test_filter_trunc_large 0 trace-update &&
309 for path in $(git ls-tree -r --name-only HEAD)
311 git -c commitGraph.readChangedPaths=false log \
312 -- $path >expect &&
313 git log -- $path >actual &&
314 test_cmp expect actual || return 1
315 done
319 test_expect_success 'correctly report commits with no changed paths' '
320 git init empty &&
321 test_when_finished "rm -fr empty" &&
323 cd empty &&
325 git commit --allow-empty -m "initial commit" &&
327 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
328 git commit-graph write --reachable --changed-paths &&
329 test_filter_computed 1 trace.event &&
330 test_filter_not_computed 0 trace.event &&
331 test_filter_trunc_empty 1 trace.event &&
332 test_filter_trunc_large 0 trace.event
336 test_expect_success 'Bloom generation is limited by --max-new-filters' '
338 cd limits &&
339 test_commit c2 filter &&
340 test_commit c3 filter &&
341 test_commit c4 no-filter &&
343 rm -f trace.event &&
344 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
345 git commit-graph write --reachable --split=replace \
346 --changed-paths --max-new-filters=2 &&
348 test_filter_computed 2 trace.event &&
349 test_filter_not_computed 3 trace.event &&
350 test_filter_trunc_empty 0 trace.event &&
351 test_filter_trunc_large 0 trace.event
355 test_expect_success 'Bloom generation backfills previously-skipped filters' '
356 # Check specifying commitGraph.maxNewFilters over "git config" works.
357 test_config -C limits commitGraph.maxNewFilters 1 &&
359 cd limits &&
361 rm -f trace.event &&
362 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
363 git commit-graph write --reachable --changed-paths \
364 --split=replace &&
365 test_filter_computed 1 trace.event &&
366 test_filter_not_computed 4 trace.event &&
367 test_filter_trunc_empty 0 trace.event &&
368 test_filter_trunc_large 0 trace.event
372 test_expect_success '--max-new-filters overrides configuration' '
373 git init override &&
374 test_when_finished "rm -fr override" &&
375 test_config -C override commitGraph.maxNewFilters 2 &&
377 cd override &&
378 test_commit one &&
379 test_commit two &&
381 rm -f trace.event &&
382 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
383 git commit-graph write --reachable --changed-paths \
384 --max-new-filters=1 &&
385 test_filter_computed 1 trace.event &&
386 test_filter_not_computed 1 trace.event &&
387 test_filter_trunc_empty 0 trace.event &&
388 test_filter_trunc_large 0 trace.event
392 test_expect_success 'Bloom generation backfills empty commits' '
393 git init empty &&
394 test_when_finished "rm -fr empty" &&
396 cd empty &&
397 for i in $(test_seq 1 6)
399 git commit --allow-empty -m "$i" || return 1
400 done &&
402 # Generate Bloom filters for empty commits 1-6, two at a time.
403 for i in $(test_seq 1 3)
405 rm -f trace.event &&
406 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
407 git commit-graph write --reachable \
408 --changed-paths --max-new-filters=2 &&
409 test_filter_computed 2 trace.event &&
410 test_filter_not_computed 4 trace.event &&
411 test_filter_trunc_empty 2 trace.event &&
412 test_filter_trunc_large 0 trace.event || return 1
413 done &&
415 # Finally, make sure that once all commits have filters, that
416 # none are subsequently recomputed.
417 rm -f trace.event &&
418 GIT_TRACE2_EVENT="$(pwd)/trace.event" \
419 git commit-graph write --reachable \
420 --changed-paths --max-new-filters=2 &&
421 test_filter_computed 0 trace.event &&
422 test_filter_not_computed 6 trace.event &&
423 test_filter_trunc_empty 0 trace.event &&
424 test_filter_trunc_large 0 trace.event
428 graph=.git/objects/info/commit-graph
429 graphdir=.git/objects/info/commit-graphs
430 chain=$graphdir/commit-graph-chain
432 test_expect_success 'setup for mixed Bloom setting tests' '
433 repo=mixed-bloom-settings &&
435 git init $repo &&
436 for i in one two three
438 test_commit -C $repo $i file || return 1
439 done
442 test_expect_success 'ensure Bloom filters with incompatible settings are ignored' '
443 # Compute Bloom filters with "unusual" settings.
444 git -C $repo rev-parse one >in &&
445 GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=3 git -C $repo commit-graph write \
446 --stdin-commits --changed-paths --split <in &&
447 layer=$(head -n 1 $repo/$chain) &&
449 # A commit-graph layer without Bloom filters "hides" the layers
450 # below ...
451 git -C $repo rev-parse two >in &&
452 git -C $repo commit-graph write --stdin-commits --no-changed-paths \
453 --split=no-merge <in &&
455 # Another commit-graph layer that has Bloom filters, but with
456 # standard settings, and is thus incompatible with the base
457 # layer written above.
458 git -C $repo rev-parse HEAD >in &&
459 git -C $repo commit-graph write --stdin-commits --changed-paths \
460 --split=no-merge <in &&
462 test_line_count = 3 $repo/$chain &&
464 # Ensure that incompatible Bloom filters are ignored.
465 git -C $repo -c core.commitGraph=false log --oneline --no-decorate -- file \
466 >expect 2>err &&
467 git -C $repo log --oneline --no-decorate -- file >actual 2>err &&
468 test_cmp expect actual &&
469 grep "disabling Bloom filters for commit-graph layer .$layer." err
472 test_expect_success 'merge graph layers with incompatible Bloom settings' '
473 # Ensure that incompatible Bloom filters are ignored when
474 # merging existing layers.
475 >trace2.txt &&
476 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
477 git -C $repo commit-graph write --reachable --changed-paths 2>err &&
478 grep "disabling Bloom filters for commit-graph layer .$layer." err &&
479 grep "{\"hash_version\":1,\"num_hashes\":7,\"bits_per_entry\":10,\"max_changed_paths\":512" trace2.txt &&
481 test_path_is_file $repo/$graph &&
482 test_dir_is_empty $repo/$graphdir &&
484 git -C $repo -c core.commitGraph=false log --oneline --no-decorate -- \
485 file >expect &&
486 trace_out="$(pwd)/trace.perf" &&
487 GIT_TRACE2_PERF="$trace_out" \
488 git -C $repo log --oneline --no-decorate -- file >actual 2>err &&
490 test_cmp expect actual &&
491 grep "statistics:{\"filter_not_present\":0," trace.perf &&
492 test_must_be_empty err
495 # chosen to be the same under all Unicode normalization forms
496 CENT=$(printf "\302\242")
498 test_expect_success 'ensure Bloom filter with incompatible versions are ignored' '
499 rm "$repo/$graph" &&
501 git -C $repo log --oneline --no-decorate -- $CENT >expect &&
503 # Compute v1 Bloom filters for commits at the bottom.
504 git -C $repo rev-parse HEAD^ >in &&
505 git -C $repo commit-graph write --stdin-commits --changed-paths \
506 --split <in &&
508 # Compute v2 Bloomfilters for the rest of the commits at the top.
509 git -C $repo rev-parse HEAD >in &&
510 git -C $repo -c commitGraph.changedPathsVersion=2 commit-graph write \
511 --stdin-commits --changed-paths --split=no-merge <in &&
513 test_line_count = 2 $repo/$chain &&
515 git -C $repo log --oneline --no-decorate -- $CENT >actual 2>err &&
516 test_cmp expect actual &&
518 layer="$(head -n 1 $repo/$chain)" &&
519 cat >expect.err <<-EOF &&
520 warning: disabling Bloom filters for commit-graph layer $SQ$layer$SQ due to incompatible settings
522 test_cmp expect.err err &&
524 # Merge the two layers with incompatible bloom filter versions,
525 # ensuring that the v2 filters are used.
526 >trace2.txt &&
527 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
528 git -C $repo -c commitGraph.changedPathsVersion=2 commit-graph write --reachable --changed-paths 2>err &&
529 grep "disabling Bloom filters for commit-graph layer .$layer." err &&
530 grep "{\"hash_version\":2,\"num_hashes\":7,\"bits_per_entry\":10,\"max_changed_paths\":512" trace2.txt
533 get_first_changed_path_filter () {
534 test-tool read-graph bloom-filters >filters.dat &&
535 head -n 1 filters.dat
538 test_expect_success 'set up repo with high bit path, version 1 changed-path' '
539 git init highbit1 &&
540 test_commit -C highbit1 c1 "$CENT" &&
541 git -C highbit1 commit-graph write --reachable --changed-paths
544 test_expect_success 'setup check value of version 1 changed-path' '
546 cd highbit1 &&
547 echo "52a9" >expect &&
548 get_first_changed_path_filter >actual
552 # expect will not match actual if char is unsigned by default. Write the test
553 # in this way, so that a user running this test script can still see if the two
554 # files match. (It will appear as an ordinary success if they match, and a skip
555 # if not.)
556 if test_cmp highbit1/expect highbit1/actual
557 then
558 test_set_prereq SIGNED_CHAR_BY_DEFAULT
560 test_expect_success SIGNED_CHAR_BY_DEFAULT 'check value of version 1 changed-path' '
561 # Only the prereq matters for this test.
562 true
565 test_expect_success 'setup make another commit' '
566 # "git log" does not use Bloom filters for root commits - see how, in
567 # revision.c, rev_compare_tree() (the only code path that eventually calls
568 # get_bloom_filter()) is only called by try_to_simplify_commit() when the commit
569 # has one parent. Therefore, make another commit so that we perform the tests on
570 # a non-root commit.
571 test_commit -C highbit1 anotherc1 "another$CENT"
574 test_expect_success 'version 1 changed-path used when version 1 requested' '
576 cd highbit1 &&
577 test_bloom_filters_used "-- another$CENT"
581 test_expect_success 'version 1 changed-path not used when version 2 requested' '
583 cd highbit1 &&
584 git config --add commitGraph.changedPathsVersion 2 &&
585 test_bloom_filters_not_used "-- another$CENT"
589 test_expect_success 'version 1 changed-path used when autodetect requested' '
591 cd highbit1 &&
592 git config --add commitGraph.changedPathsVersion -1 &&
593 test_bloom_filters_used "-- another$CENT"
597 test_expect_success 'when writing another commit graph, preserve existing version 1 of changed-path' '
598 test_commit -C highbit1 c1double "$CENT$CENT" &&
599 git -C highbit1 commit-graph write --reachable --changed-paths &&
601 cd highbit1 &&
602 git config --add commitGraph.changedPathsVersion -1 &&
603 echo "options: bloom(1,10,7) read_generation_data" >expect &&
604 test-tool read-graph >full &&
605 grep options full >actual &&
606 test_cmp expect actual
610 test_expect_success 'set up repo with high bit path, version 2 changed-path' '
611 git init highbit2 &&
612 git -C highbit2 config --add commitGraph.changedPathsVersion 2 &&
613 test_commit -C highbit2 c2 "$CENT" &&
614 git -C highbit2 commit-graph write --reachable --changed-paths
617 test_expect_success 'check value of version 2 changed-path' '
619 cd highbit2 &&
620 echo "c01f" >expect &&
621 get_first_changed_path_filter >actual &&
622 test_cmp expect actual
626 test_expect_success 'setup make another commit' '
627 # "git log" does not use Bloom filters for root commits - see how, in
628 # revision.c, rev_compare_tree() (the only code path that eventually calls
629 # get_bloom_filter()) is only called by try_to_simplify_commit() when the commit
630 # has one parent. Therefore, make another commit so that we perform the tests on
631 # a non-root commit.
632 test_commit -C highbit2 anotherc2 "another$CENT"
635 test_expect_success 'version 2 changed-path used when version 2 requested' '
637 cd highbit2 &&
638 test_bloom_filters_used "-- another$CENT"
642 test_expect_success 'version 2 changed-path not used when version 1 requested' '
644 cd highbit2 &&
645 git config --add commitGraph.changedPathsVersion 1 &&
646 test_bloom_filters_not_used "-- another$CENT"
650 test_expect_success 'version 2 changed-path used when autodetect requested' '
652 cd highbit2 &&
653 git config --add commitGraph.changedPathsVersion -1 &&
654 test_bloom_filters_used "-- another$CENT"
658 test_expect_success 'when writing another commit graph, preserve existing version 2 of changed-path' '
659 test_commit -C highbit2 c2double "$CENT$CENT" &&
660 git -C highbit2 commit-graph write --reachable --changed-paths &&
662 cd highbit2 &&
663 git config --add commitGraph.changedPathsVersion -1 &&
664 echo "options: bloom(2,10,7) read_generation_data" >expect &&
665 test-tool read-graph >full &&
666 grep options full >actual &&
667 test_cmp expect actual
671 test_expect_success 'when writing commit graph, do not reuse changed-path of another version' '
672 git init doublewrite &&
673 test_commit -C doublewrite c "$CENT" &&
675 git -C doublewrite config --add commitGraph.changedPathsVersion 1 &&
676 >trace2.txt &&
677 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
678 git -C doublewrite commit-graph write --reachable --changed-paths &&
679 test_filter_computed 1 trace2.txt &&
680 test_filter_upgraded 0 trace2.txt &&
682 git -C doublewrite commit-graph write --reachable --changed-paths &&
683 for v in -2 3
685 git -C doublewrite config --add commitGraph.changedPathsVersion $v &&
686 git -C doublewrite commit-graph write --reachable --changed-paths 2>err &&
687 cat >expect <<-EOF &&
688 warning: attempting to write a commit-graph, but ${SQ}commitGraph.changedPathsVersion${SQ} ($v) is not supported
690 test_cmp expect err || return 1
691 done &&
693 git -C doublewrite config --add commitGraph.changedPathsVersion 2 &&
694 >trace2.txt &&
695 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
696 git -C doublewrite commit-graph write --reachable --changed-paths &&
697 test_filter_computed 1 trace2.txt &&
698 test_filter_upgraded 0 trace2.txt &&
701 cd doublewrite &&
702 echo "c01f" >expect &&
703 get_first_changed_path_filter >actual &&
704 test_cmp expect actual
708 test_expect_success 'when writing commit graph, reuse changed-path of another version where possible' '
709 git init upgrade &&
711 test_commit -C upgrade base no-high-bits &&
713 git -C upgrade config --add commitGraph.changedPathsVersion 1 &&
714 >trace2.txt &&
715 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
716 git -C upgrade commit-graph write --reachable --changed-paths &&
717 test_filter_computed 1 trace2.txt &&
718 test_filter_upgraded 0 trace2.txt &&
720 git -C upgrade config --add commitGraph.changedPathsVersion 2 &&
721 >trace2.txt &&
722 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
723 git -C upgrade commit-graph write --reachable --changed-paths &&
724 test_filter_computed 0 trace2.txt &&
725 test_filter_upgraded 1 trace2.txt
728 corrupt_graph () {
729 test_when_finished "rm -rf $graph" &&
730 git commit-graph write --reachable --changed-paths &&
731 corrupt_chunk_file $graph "$@"
734 check_corrupt_graph () {
735 corrupt_graph "$@" &&
736 git -c core.commitGraph=false log -- A/B/file2 >expect.out &&
737 git -c core.commitGraph=true log -- A/B/file2 >out 2>err &&
738 test_cmp expect.out out
741 test_expect_success 'Bloom reader notices too-small data chunk' '
742 check_corrupt_graph BDAT clear 00000000 &&
743 echo "warning: ignoring too-small changed-path chunk" \
744 "(4 < 12) in commit-graph file" >expect.err &&
745 test_cmp expect.err err
748 test_expect_success 'Bloom reader notices out-of-bounds filter offsets' '
749 check_corrupt_graph BIDX 12 FFFFFFFF &&
750 # use grep to avoid depending on exact chunk size
751 grep "warning: ignoring out-of-range offset (4294967295) for changed-path filter at pos 3 of .git/objects/info/commit-graph" err
754 test_expect_success 'Bloom reader notices too-small index chunk' '
755 # replace the index with a single entry, making most
756 # lookups out-of-bounds
757 check_corrupt_graph BIDX clear 00000000 &&
758 echo "warning: commit-graph changed-path index chunk" \
759 "is too small" >expect.err &&
760 test_cmp expect.err err
763 test_expect_success 'Bloom reader notices out-of-order index offsets' '
764 # we do not know any real offsets, but we can pick
765 # something plausible; we should not get to the point of
766 # actually reading from the bogus offsets anyway.
767 corrupt_graph BIDX 4 0000000c00000005 &&
768 echo "warning: ignoring decreasing changed-path index offsets" \
769 "(12 > 5) for positions 1 and 2 of .git/objects/info/commit-graph" >expect.err &&
770 git -c core.commitGraph=false log -- A/B/file2 >expect.out &&
771 git -c core.commitGraph=true log -- A/B/file2 >out 2>err &&
772 test_cmp expect.out out &&
773 test_cmp expect.err err
776 test_done