Git fork
at reftables-rust 465 lines 12 kB view raw
1#!/bin/sh 2 3test_description='pseudo-merge bitmaps' 4 5GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 6 7. ./test-lib.sh 8 9test_pseudo_merges () { 10 test-tool bitmap dump-pseudo-merges 11} 12 13test_pseudo_merge_commits () { 14 test-tool bitmap dump-pseudo-merge-commits "$1" 15} 16 17test_pseudo_merges_satisfied () { 18 test_trace2_data bitmap pseudo_merges_satisfied "$1" 19} 20 21test_pseudo_merges_cascades () { 22 test_trace2_data bitmap pseudo_merges_cascades "$1" 23} 24 25test_pseudo_merges_reused () { 26 test_trace2_data pack-bitmap-write building_bitmaps_pseudo_merge_reused "$1" 27} 28 29tag_everything () { 30 git rev-list --all --no-object-names >in && 31 sed 's|\(.*\)|create refs/tags/\1 \1|' in | 32 git update-ref --stdin 33} 34 35test_expect_success 'setup' ' 36 test_commit_bulk 512 && 37 tag_everything 38' 39 40test_expect_success 'bitmap traversal without pseudo-merges' ' 41 git repack -adb && 42 43 git rev-list --count --all --objects >expect && 44 45 : >trace2.txt && 46 GIT_TRACE2_EVENT=$PWD/trace2.txt \ 47 git rev-list --count --all --objects --use-bitmap-index >actual && 48 49 test_pseudo_merges_satisfied 0 <trace2.txt && 50 test_pseudo_merges_cascades 0 <trace2.txt && 51 test_pseudo_merges >merges && 52 test_must_be_empty merges && 53 test_cmp expect actual 54' 55 56test_expect_success 'pseudo-merges accurately represent their objects' ' 57 test_config bitmapPseudoMerge.test.pattern "refs/tags/" && 58 test_config bitmapPseudoMerge.test.maxMerges 8 && 59 test_config bitmapPseudoMerge.test.stableThreshold never && 60 61 git repack -adb && 62 63 test_pseudo_merges >merges && 64 test_line_count = 8 merges && 65 66 for i in $(test_seq 0 $(($(wc -l <merges)-1))) 67 do 68 test-tool bitmap dump-pseudo-merge-commits $i >commits && 69 70 git rev-list --objects --no-object-names --stdin <commits >expect.raw && 71 test-tool bitmap dump-pseudo-merge-objects $i >actual.raw && 72 73 sort -u <expect.raw >expect && 74 sort -u <actual.raw >actual && 75 76 test_cmp expect actual || return 1 77 done 78' 79 80test_expect_success 'bitmap traversal with pseudo-merges' ' 81 : >trace2.txt && 82 GIT_TRACE2_EVENT=$PWD/trace2.txt \ 83 git rev-list --count --all --objects --use-bitmap-index >actual && 84 git rev-list --count --all --objects >expect && 85 86 test_pseudo_merges_satisfied 8 <trace2.txt && 87 test_pseudo_merges_cascades 1 <trace2.txt && 88 test_cmp expect actual 89' 90 91test_expect_success 'stale bitmap traversal with pseudo-merges' ' 92 test_commit other && 93 94 : >trace2.txt && 95 GIT_TRACE2_EVENT=$PWD/trace2.txt \ 96 git rev-list --count --all --objects --use-bitmap-index >actual && 97 git rev-list --count --all --objects >expect && 98 99 test_pseudo_merges_satisfied 8 <trace2.txt && 100 test_pseudo_merges_cascades 1 <trace2.txt && 101 test_cmp expect actual 102' 103 104test_expect_success PERL_TEST_HELPERS 'bitmapPseudoMerge.sampleRate adjusts commit selection rate' ' 105 test_config bitmapPseudoMerge.test.pattern "refs/tags/" && 106 test_config bitmapPseudoMerge.test.maxMerges 1 && 107 test_config bitmapPseudoMerge.test.stableThreshold never && 108 109 commits_nr=$(git rev-list --all --count) && 110 111 for rate in 1.0 0.5 0.25 112 do 113 git -c bitmapPseudoMerge.test.sampleRate=$rate repack -adb && 114 115 test_pseudo_merges >merges && 116 test_line_count = 1 merges && 117 test_pseudo_merge_commits 0 >commits && 118 119 test-tool bitmap list-commits >bitmaps && 120 bitmaps_nr="$(wc -l <bitmaps)" && 121 122 perl -MPOSIX -e "print ceil(\$ARGV[0]*(\$ARGV[1]-\$ARGV[2]))" \ 123 "$rate" "$commits_nr" "$bitmaps_nr" >expect && 124 125 test $(cat expect) -eq $(wc -l <commits) || return 1 126 done 127' 128 129test_expect_success 'bitmapPseudoMerge.threshold excludes newer commits' ' 130 git init pseudo-merge-threshold && 131 ( 132 cd pseudo-merge-threshold && 133 134 new="1672549200" && # 2023-01-01 135 old="1641013200" && # 2022-01-01 136 137 GIT_COMMITTER_DATE="$new +0000" && 138 export GIT_COMMITTER_DATE && 139 test_commit_bulk --message="new" --notick 128 && 140 141 GIT_COMMITTER_DATE="$old +0000" && 142 export GIT_COMMITTER_DATE && 143 test_commit_bulk --message="old" --notick 128 && 144 145 tag_everything && 146 147 git \ 148 -c bitmapPseudoMerge.test.pattern="refs/tags/" \ 149 -c bitmapPseudoMerge.test.maxMerges=1 \ 150 -c bitmapPseudoMerge.test.threshold=$(($new - 1)) \ 151 -c bitmapPseudoMerge.test.stableThreshold=never \ 152 repack -adb && 153 154 test_pseudo_merges >merges && 155 test_line_count = 1 merges && 156 157 test_pseudo_merge_commits 0 >oids && 158 git cat-file --batch <oids >commits && 159 160 test $(wc -l <oids) = $(grep -c "^committer.*$old +0000$" commits) 161 ) 162' 163 164test_expect_success 'bitmapPseudoMerge.stableThreshold creates stable groups' ' 165 ( 166 cd pseudo-merge-threshold && 167 168 new="1672549200" && # 2023-01-01 169 mid="1654059600" && # 2022-06-01 170 old="1641013200" && # 2022-01-01 171 172 GIT_COMMITTER_DATE="$mid +0000" && 173 export GIT_COMMITTER_DATE && 174 test_commit_bulk --message="mid" --notick 128 && 175 176 git for-each-ref --format="delete %(refname)" refs/tags >in && 177 git update-ref --stdin <in && 178 179 tag_everything && 180 181 git \ 182 -c bitmapPseudoMerge.test.pattern="refs/tags/" \ 183 -c bitmapPseudoMerge.test.maxMerges=1 \ 184 -c bitmapPseudoMerge.test.threshold=$(($new - 1)) \ 185 -c bitmapPseudoMerge.test.stableThreshold=$(($mid - 1)) \ 186 -c bitmapPseudoMerge.test.stableSize=10 \ 187 repack -adb && 188 189 test_pseudo_merges >merges && 190 merges_nr="$(wc -l <merges)" && 191 192 for i in $(test_seq $(($merges_nr - 1))) 193 do 194 test_pseudo_merge_commits 0 >oids && 195 git cat-file --batch <oids >commits && 196 197 expect="$(grep -c "^committer.*$old +0000$" commits)" && 198 actual="$(wc -l <oids)" && 199 200 test $expect = $actual || return 1 201 done && 202 203 test_pseudo_merge_commits $(($merges_nr - 1)) >oids && 204 git cat-file --batch <oids >commits && 205 test $(wc -l <oids) = $(grep -c "^committer.*$mid +0000$" commits) 206 ) 207' 208 209test_expect_success 'out of order thresholds are rejected' ' 210 # Disable the test var to remove a stderr message. 211 test_must_fail env GIT_TEST_NAME_HASH_VERSION=1 git \ 212 -c bitmapPseudoMerge.test.pattern="refs/*" \ 213 -c bitmapPseudoMerge.test.threshold=1.month.ago \ 214 -c bitmapPseudoMerge.test.stableThreshold=1.week.ago \ 215 repack -adb 2>err && 216 217 cat >expect <<-EOF && 218 fatal: pseudo-merge group ${SQ}test${SQ} has unstable threshold before stable one 219 EOF 220 221 test_cmp expect err 222' 223 224test_expect_success 'pseudo-merge pattern with capture groups' ' 225 git init pseudo-merge-captures && 226 ( 227 cd pseudo-merge-captures && 228 229 test_commit_bulk 128 && 230 tag_everything && 231 232 for r in $(test_seq 8) 233 do 234 test_commit_bulk 16 && 235 236 git rev-list HEAD~16.. >in && 237 sed "s|\(.*\)|create refs/remotes/$r/tags/\1 \1|" in >refs && 238 git update-ref --stdin <refs || return 1 239 done && 240 241 git \ 242 -c bitmapPseudoMerge.tags.pattern="refs/remotes/([0-9]+)/tags/" \ 243 -c bitmapPseudoMerge.tags.maxMerges=1 \ 244 repack -adb && 245 246 git for-each-ref --format="%(objectname) %(refname)" >refs && 247 248 test_pseudo_merges >merges && 249 for m in $(test_seq 0 $(($(wc -l <merges) - 1))) 250 do 251 test_pseudo_merge_commits $m >oids && 252 grep -f oids refs | 253 sed -n "s|refs/remotes/\([0-9][0-9]*\)/|\1|p" && 254 sort -u || return 1 255 done >remotes && 256 257 test $(wc -l <remotes) -eq $(sort -u <remotes | wc -l) 258 ) 259' 260 261test_expect_success 'pseudo-merge overlap setup' ' 262 git init pseudo-merge-overlap && 263 ( 264 cd pseudo-merge-overlap && 265 266 test_commit_bulk 256 && 267 tag_everything && 268 269 git \ 270 -c bitmapPseudoMerge.all.pattern="refs/" \ 271 -c bitmapPseudoMerge.all.maxMerges=1 \ 272 -c bitmapPseudoMerge.all.stableThreshold=never \ 273 -c bitmapPseudoMerge.tags.pattern="refs/tags/" \ 274 -c bitmapPseudoMerge.tags.maxMerges=1 \ 275 -c bitmapPseudoMerge.tags.stableThreshold=never \ 276 repack -adb 277 ) 278' 279 280test_expect_success 'pseudo-merge overlap generates overlapping groups' ' 281 ( 282 cd pseudo-merge-overlap && 283 284 test_pseudo_merges >merges && 285 test_line_count = 2 merges && 286 287 test_pseudo_merge_commits 0 >commits-0.raw && 288 test_pseudo_merge_commits 1 >commits-1.raw && 289 290 sort commits-0.raw >commits-0 && 291 sort commits-1.raw >commits-1 && 292 293 comm -12 commits-0 commits-1 >overlap && 294 295 test_line_count -gt 0 overlap 296 ) 297' 298 299test_expect_success 'pseudo-merge overlap traversal' ' 300 ( 301 cd pseudo-merge-overlap && 302 303 : >trace2.txt && 304 GIT_TRACE2_EVENT=$PWD/trace2.txt \ 305 git rev-list --count --all --objects --use-bitmap-index >actual && 306 git rev-list --count --all --objects >expect && 307 308 test_pseudo_merges_satisfied 2 <trace2.txt && 309 test_pseudo_merges_cascades 1 <trace2.txt && 310 test_cmp expect actual 311 ) 312' 313 314test_expect_success 'pseudo-merge overlap stale traversal' ' 315 ( 316 cd pseudo-merge-overlap && 317 318 test_commit other && 319 320 : >trace2.txt && 321 GIT_TRACE2_EVENT=$PWD/trace2.txt \ 322 git rev-list --count --all --objects --use-bitmap-index >actual && 323 git rev-list --count --all --objects >expect && 324 325 test_pseudo_merges_satisfied 2 <trace2.txt && 326 test_pseudo_merges_cascades 1 <trace2.txt && 327 test_cmp expect actual 328 ) 329' 330 331test_expect_success 'pseudo-merge reuse' ' 332 git init pseudo-merge-reuse && 333 ( 334 cd pseudo-merge-reuse && 335 336 stable="1641013200" && # 2022-01-01 337 unstable="1672549200" && # 2023-01-01 338 339 GIT_COMMITTER_DATE="$stable +0000" && 340 export GIT_COMMITTER_DATE && 341 test_commit_bulk --notick 128 && 342 GIT_COMMITTER_DATE="$unstable +0000" && 343 export GIT_COMMITTER_DATE && 344 test_commit_bulk --notick 128 && 345 346 tag_everything && 347 348 git \ 349 -c bitmapPseudoMerge.test.pattern="refs/tags/" \ 350 -c bitmapPseudoMerge.test.maxMerges=1 \ 351 -c bitmapPseudoMerge.test.threshold=now \ 352 -c bitmapPseudoMerge.test.stableThreshold=$(($unstable - 1)) \ 353 -c bitmapPseudoMerge.test.stableSize=512 \ 354 repack -adb && 355 356 test_pseudo_merges >merges && 357 test_line_count = 2 merges && 358 359 test_pseudo_merge_commits 0 >stable-oids.before && 360 test_pseudo_merge_commits 1 >unstable-oids.before && 361 362 : >trace2.txt && 363 GIT_TRACE2_EVENT=$PWD/trace2.txt git \ 364 -c bitmapPseudoMerge.test.pattern="refs/tags/" \ 365 -c bitmapPseudoMerge.test.maxMerges=2 \ 366 -c bitmapPseudoMerge.test.threshold=now \ 367 -c bitmapPseudoMerge.test.stableThreshold=$(($unstable - 1)) \ 368 -c bitmapPseudoMerge.test.stableSize=512 \ 369 repack -adb && 370 371 test_pseudo_merges_reused 1 <trace2.txt && 372 373 test_pseudo_merges >merges && 374 test_line_count = 3 merges && 375 376 test_pseudo_merge_commits 0 >stable-oids.after && 377 for i in 1 2 378 do 379 test_pseudo_merge_commits $i || return 1 380 done >unstable-oids.after && 381 382 sort -u <stable-oids.before >expect && 383 sort -u <stable-oids.after >actual && 384 test_cmp expect actual && 385 386 sort -u <unstable-oids.before >expect && 387 sort -u <unstable-oids.after >actual && 388 test_cmp expect actual 389 ) 390' 391 392test_expect_success 'empty pseudo-merge group' ' 393 git init pseudo-merge-empty-group && 394 ( 395 cd pseudo-merge-empty-group && 396 397 # Ensure that a pseudo-merge group with no unstable 398 # commits does not generate an empty pseudo-merge 399 # bitmap. 400 git config bitmapPseudoMerge.empty.pattern refs/ && 401 402 test_commit base && 403 git repack -adb && 404 405 test-tool bitmap dump-pseudo-merges >merges && 406 test_line_count = 1 merges && 407 408 test 0 -eq "$(grep -c commits=0 <merges)" 409 ) 410' 411 412test_expect_success 'pseudo-merge closure' ' 413 git init pseudo-merge-closure && 414 ( 415 cd pseudo-merge-closure && 416 417 test_commit A && 418 git repack -d && 419 420 test_commit B && 421 422 # Note that the contents of A is packed, but B is not. A 423 # (and the objects reachable from it) are thus visible 424 # to the MIDX, but the same is not true for B and its 425 # objects. 426 # 427 # Ensure that we do not attempt to create a pseudo-merge 428 # for B, depsite it matching the below pseudo-merge 429 # group pattern, as doing so would result in a failure 430 # to write a non-closed bitmap. 431 git config bitmapPseudoMerge.test.pattern refs/ && 432 git config bitmapPseudoMerge.test.threshold now && 433 434 git multi-pack-index write --bitmap && 435 436 test-tool bitmap dump-pseudo-merges >pseudo-merges && 437 test_line_count = 1 pseudo-merges && 438 439 git rev-parse A >expect && 440 441 test-tool bitmap list-commits >actual && 442 test_cmp expect actual && 443 test-tool bitmap dump-pseudo-merge-commits 0 >actual && 444 test_cmp expect actual 445 ) 446' 447 448test_expect_success 'use pseudo-merge in boundary traversal' ' 449 git init pseudo-merge-boundary-traversal && 450 ( 451 cd pseudo-merge-boundary-traversal && 452 453 git config bitmapPseudoMerge.test.pattern refs/ && 454 git config pack.useBitmapBoundaryTraversal true && 455 456 test_commit A && 457 git repack -adb && 458 test_commit B && 459 460 nr=$(git rev-list --count --use-bitmap-index HEAD~1..HEAD) && 461 test 1 -eq "$nr" 462 ) 463' 464 465test_done