summaryrefslogtreecommitdiff
path: root/t/t4216-log-bloom.sh
diff options
context:
space:
mode:
Diffstat (limited to 't/t4216-log-bloom.sh')
-rwxr-xr-xt/t4216-log-bloom.sh270
1 files changed, 260 insertions, 10 deletions
diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh
index c855bcd3e7..d11040ce41 100755
--- a/t/t4216-log-bloom.sh
+++ b/t/t4216-log-bloom.sh
@@ -30,12 +30,19 @@ test_expect_success 'setup test - repo, commits, commit graph, log outputs' '
rm file_to_be_deleted &&
git add . &&
git commit -m "file removed" &&
- git commit-graph write --reachable --changed-paths
+ git commit --allow-empty -m "empty" &&
+ git commit-graph write --reachable --changed-paths &&
+
+ test_oid_cache <<-EOF
+ oid_version sha1:1
+ oid_version sha256:2
+ EOF
'
+
graph_read_expect () {
NUM_CHUNKS=5
cat >expect <<- EOF
- header: 43475048 1 1 $NUM_CHUNKS 0
+ header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata bloom_indexes bloom_data
EOF
@@ -44,7 +51,7 @@ graph_read_expect () {
}
test_expect_success 'commit-graph write wrote out the bloom chunks' '
- graph_read_expect 15
+ graph_read_expect 16
'
# Turn off any inherited trace2 settings for this test.
@@ -53,14 +60,14 @@ sane_unset GIT_TRACE2_PERF_BRIEF
sane_unset GIT_TRACE2_CONFIG_PARAMS
setup () {
- rm "$TRASH_DIRECTORY/trace.perf"
+ rm -f "$TRASH_DIRECTORY/trace.perf" &&
git -c core.commitGraph=false log --pretty="format:%s" $1 >log_wo_bloom &&
GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.perf" git -c core.commitGraph=true log --pretty="format:%s" $1 >log_w_bloom
}
test_bloom_filters_used () {
log_args=$1
- bloom_trace_prefix="statistics:{\"filter_not_present\":0,\"zero_length_filter\":0,\"maybe\""
+ bloom_trace_prefix="statistics:{\"filter_not_present\":${2:-0},\"maybe\""
setup "$log_args" &&
grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" &&
test_cmp log_wo_bloom log_w_bloom &&
@@ -90,7 +97,9 @@ do
"--ancestry-path side..master"
do
test_expect_success "git log option: $option for path: $path" '
- test_bloom_filters_used "$option -- $path"
+ test_bloom_filters_used "$option -- $path" &&
+ test_config commitgraph.readChangedPaths false &&
+ test_bloom_filters_not_used "$option -- $path"
'
done
done
@@ -112,6 +121,10 @@ test_expect_success 'git log -- multiple path specs does not use Bloom filters'
test_bloom_filters_not_used "-- file4 A/file1"
'
+test_expect_success 'git log -- "." pathspec at root does not use Bloom filters' '
+ test_bloom_filters_not_used "-- ."
+'
+
test_expect_success 'git log with wildcard that resolves to a single path uses Bloom filters' '
test_bloom_filters_used "-- *4" &&
test_bloom_filters_used "-- *renamed"
@@ -126,12 +139,15 @@ test_expect_success 'setup - add commit-graph to the chain without Bloom filters
test_commit c14 A/anotherFile2 &&
test_commit c15 A/B/anotherFile2 &&
test_commit c16 A/B/C/anotherFile2 &&
- GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 git commit-graph write --reachable --split &&
+ git commit-graph write --reachable --split --no-changed-paths &&
test_line_count = 2 .git/objects/info/commit-graphs/commit-graph-chain
'
-test_expect_success 'Do not use Bloom filters if the latest graph does not have Bloom filters.' '
- test_bloom_filters_not_used "-- A/B"
+test_expect_success 'use Bloom filters even if the latest graph does not have Bloom filters' '
+ # Ensure that the number of empty filters is equal to the number of
+ # filters in the latest graph layer to prove that they are loaded (and
+ # ignored).
+ test_bloom_filters_used "-- A/B" 3
'
test_expect_success 'setup - add commit-graph to the chain with Bloom filters' '
@@ -142,7 +158,7 @@ test_expect_success 'setup - add commit-graph to the chain with Bloom filters' '
test_bloom_filters_used_when_some_filters_are_missing () {
log_args=$1
- bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"zero_length_filter\":0,\"maybe\":8,\"definitely_not\":6"
+ bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":9"
setup "$log_args" &&
grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" &&
test_cmp log_wo_bloom log_w_bloom
@@ -152,4 +168,238 @@ test_expect_success 'Use Bloom filters if they exist in the latest but not all c
test_bloom_filters_used_when_some_filters_are_missing "-- A/B"
'
+test_expect_success 'persist filter settings' '
+ test_when_finished rm -rf .git/objects/info/commit-graph* &&
+ rm -rf .git/objects/info/commit-graph* &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
+ GIT_TRACE2_EVENT_NESTING=5 \
+ GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=9 \
+ GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY=15 \
+ git commit-graph write --reachable --changed-paths &&
+ grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2-auto.txt" \
+ GIT_TRACE2_EVENT_NESTING=5 \
+ git commit-graph write --reachable --changed-paths &&
+ grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2-auto.txt
+'
+
+test_max_changed_paths () {
+ grep "\"max_changed_paths\":$1" $2
+}
+
+test_filter_not_computed () {
+ grep "\"key\":\"filter-not-computed\",\"value\":\"$1\"" $2
+}
+
+test_filter_computed () {
+ grep "\"key\":\"filter-computed\",\"value\":\"$1\"" $2
+}
+
+test_filter_trunc_empty () {
+ grep "\"key\":\"filter-trunc-empty\",\"value\":\"$1\"" $2
+}
+
+test_filter_trunc_large () {
+ grep "\"key\":\"filter-trunc-large\",\"value\":\"$1\"" $2
+}
+
+test_expect_success 'correctly report changes over limit' '
+ git init limits &&
+ (
+ cd limits &&
+ mkdir d &&
+ mkdir d/e &&
+
+ for i in $(test_seq 1 2)
+ do
+ printf $i >d/file$i.txt &&
+ printf $i >d/e/file$i.txt || return 1
+ done &&
+
+ mkdir mode &&
+ printf bash >mode/script.sh &&
+
+ mkdir foo &&
+ touch foo/bar &&
+ touch foo.txt &&
+
+ git add d foo foo.txt mode &&
+ git commit -m "files" &&
+
+ # Commit has 7 file and 4 directory adds
+ GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \
+ GIT_TRACE2_EVENT="$(pwd)/trace" \
+ git commit-graph write --reachable --changed-paths &&
+ test_max_changed_paths 10 trace &&
+ test_filter_computed 1 trace &&
+ test_filter_trunc_large 1 trace &&
+
+ for path in $(git ls-tree -r --name-only HEAD)
+ do
+ git -c commitGraph.readChangedPaths=false log \
+ -- $path >expect &&
+ git log -- $path >actual &&
+ test_cmp expect actual || return 1
+ done &&
+
+ # Make a variety of path changes
+ printf new1 >d/e/file1.txt &&
+ printf new2 >d/file2.txt &&
+ rm d/e/file2.txt &&
+ rm -r foo &&
+ printf text >foo &&
+ mkdir f &&
+ printf new1 >f/file1.txt &&
+
+ # including a mode-only change (counts as modified)
+ git update-index --chmod=+x mode/script.sh &&
+
+ git add foo d f &&
+ git commit -m "complicated" &&
+
+ # start from scratch and rebuild
+ rm -f .git/objects/info/commit-graph &&
+ GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=10 \
+ GIT_TRACE2_EVENT="$(pwd)/trace-edit" \
+ git commit-graph write --reachable --changed-paths &&
+ test_max_changed_paths 10 trace-edit &&
+ test_filter_computed 2 trace-edit &&
+ test_filter_trunc_large 2 trace-edit &&
+
+ for path in $(git ls-tree -r --name-only HEAD)
+ do
+ git -c commitGraph.readChangedPaths=false log \
+ -- $path >expect &&
+ git log -- $path >actual &&
+ test_cmp expect actual || return 1
+ done &&
+
+ # start from scratch and rebuild
+ rm -f .git/objects/info/commit-graph &&
+ GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS=11 \
+ GIT_TRACE2_EVENT="$(pwd)/trace-update" \
+ git commit-graph write --reachable --changed-paths &&
+ test_max_changed_paths 11 trace-update &&
+ test_filter_computed 2 trace-update &&
+ test_filter_trunc_large 0 trace-update &&
+
+ for path in $(git ls-tree -r --name-only HEAD)
+ do
+ git -c commitGraph.readChangedPaths=false log \
+ -- $path >expect &&
+ git log -- $path >actual &&
+ test_cmp expect actual || return 1
+ done
+ )
+'
+
+test_expect_success 'correctly report commits with no changed paths' '
+ git init empty &&
+ test_when_finished "rm -fr empty" &&
+ (
+ cd empty &&
+
+ git commit --allow-empty -m "initial commit" &&
+
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable --changed-paths &&
+ test_filter_computed 1 trace.event &&
+ test_filter_not_computed 0 trace.event &&
+ test_filter_trunc_empty 1 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ )
+'
+
+test_expect_success 'Bloom generation is limited by --max-new-filters' '
+ (
+ cd limits &&
+ test_commit c2 filter &&
+ test_commit c3 filter &&
+ test_commit c4 no-filter &&
+
+ rm -f trace.event &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable --split=replace \
+ --changed-paths --max-new-filters=2 &&
+
+ test_filter_computed 2 trace.event &&
+ test_filter_not_computed 3 trace.event &&
+ test_filter_trunc_empty 0 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ )
+'
+
+test_expect_success 'Bloom generation backfills previously-skipped filters' '
+ # Check specifying commitGraph.maxNewFilters over "git config" works.
+ test_config -C limits commitGraph.maxNewFilters 1 &&
+ (
+ cd limits &&
+
+ rm -f trace.event &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable --changed-paths \
+ --split=replace &&
+ test_filter_computed 1 trace.event &&
+ test_filter_not_computed 4 trace.event &&
+ test_filter_trunc_empty 0 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ )
+'
+
+test_expect_success '--max-new-filters overrides configuration' '
+ git init override &&
+ test_when_finished "rm -fr override" &&
+ test_config -C override commitGraph.maxNewFilters 2 &&
+ (
+ cd override &&
+ test_commit one &&
+ test_commit two &&
+
+ rm -f trace.event &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable --changed-paths \
+ --max-new-filters=1 &&
+ test_filter_computed 1 trace.event &&
+ test_filter_not_computed 1 trace.event &&
+ test_filter_trunc_empty 0 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ )
+'
+
+test_expect_success 'Bloom generation backfills empty commits' '
+ git init empty &&
+ test_when_finished "rm -fr empty" &&
+ (
+ cd empty &&
+ for i in $(test_seq 1 6)
+ do
+ git commit --allow-empty -m "$i"
+ done &&
+
+ # Generate Bloom filters for empty commits 1-6, two at a time.
+ for i in $(test_seq 1 3)
+ do
+ rm -f trace.event &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable \
+ --changed-paths --max-new-filters=2 &&
+ test_filter_computed 2 trace.event &&
+ test_filter_not_computed 4 trace.event &&
+ test_filter_trunc_empty 2 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ done &&
+
+ # Finally, make sure that once all commits have filters, that
+ # none are subsequently recomputed.
+ rm -f trace.event &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ git commit-graph write --reachable \
+ --changed-paths --max-new-filters=2 &&
+ test_filter_computed 0 trace.event &&
+ test_filter_not_computed 6 trace.event &&
+ test_filter_trunc_empty 0 trace.event &&
+ test_filter_trunc_large 0 trace.event
+ )
+'
+
test_done