| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='pseudo-merge bitmaps' |
| 4 | |
| 5 | GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 |
| 6 | |
| 7 | . ./test-lib.sh |
| 8 | |
| 9 | test_pseudo_merges () { |
| 10 | test-tool bitmap dump-pseudo-merges |
| 11 | } |
| 12 | |
| 13 | test_pseudo_merge_commits () { |
| 14 | test-tool bitmap dump-pseudo-merge-commits "$1" |
| 15 | } |
| 16 | |
| 17 | test_pseudo_merges_satisfied () { |
| 18 | test_trace2_data bitmap pseudo_merges_satisfied "$1" |
| 19 | } |
| 20 | |
| 21 | test_pseudo_merges_cascades () { |
| 22 | test_trace2_data bitmap pseudo_merges_cascades "$1" |
| 23 | } |
| 24 | |
| 25 | test_pseudo_merges_reused () { |
| 26 | test_trace2_data pack-bitmap-write building_bitmaps_pseudo_merge_reused "$1" |
| 27 | } |
| 28 | |
| 29 | tag_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 | |
| 35 | test_expect_success 'setup' ' |
| 36 | test_commit_bulk 512 && |
| 37 | tag_everything |
| 38 | ' |
| 39 | |
| 40 | test_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 | : >trace2.txt && |
| 56 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 57 | git rev-list --objects --use-bitmap-index HEAD HEAD >/dev/null && |
| 58 | |
| 59 | # The first HEAD initializes base from its position-zero bitmap. The |
| 60 | # duplicate root should not count as another bitmap hit. |
| 61 | test_trace2_data bitmap bitmap/hits 1 <trace2.txt |
| 62 | ' |
| 63 | |
| 64 | test_expect_success 'pseudo-merges accurately represent their objects' ' |
| 65 | test_config bitmapPseudoMerge.test.pattern "refs/tags/" && |
| 66 | test_config bitmapPseudoMerge.test.maxMerges 8 && |
| 67 | test_config bitmapPseudoMerge.test.stableThreshold never && |
| 68 | |
| 69 | git repack -adb && |
| 70 | |
| 71 | test_pseudo_merges >merges && |
| 72 | test_line_count = 8 merges && |
| 73 | |
| 74 | for i in $(test_seq 0 $(($(wc -l <merges)-1))) |
| 75 | do |
| 76 | test-tool bitmap dump-pseudo-merge-commits $i >commits && |
| 77 | |
| 78 | git rev-list --objects --no-object-names --stdin <commits >expect.raw && |
| 79 | test-tool bitmap dump-pseudo-merge-objects $i >actual.raw && |
| 80 | |
| 81 | sort -u <expect.raw >expect && |
| 82 | sort -u <actual.raw >actual && |
| 83 | |
| 84 | test_cmp expect actual || return 1 |
| 85 | done |
| 86 | ' |
| 87 | |
| 88 | test_expect_success 'bitmap traversal with pseudo-merges' ' |
| 89 | : >trace2.txt && |
| 90 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 91 | git rev-list --count --all --objects --use-bitmap-index >actual && |
| 92 | git rev-list --count --all --objects >expect && |
| 93 | |
| 94 | test_pseudo_merges_satisfied 8 <trace2.txt && |
| 95 | test_pseudo_merges_cascades 1 <trace2.txt && |
| 96 | |
| 97 | # Position zero is named by HEAD, its branch, and its tag, but it |
| 98 | # should count as only one bitmap hit. |
| 99 | test_trace2_data bitmap bitmap/hits 1 <trace2.txt && |
| 100 | test_cmp expect actual |
| 101 | ' |
| 102 | |
| 103 | test_expect_success 'stale bitmap traversal with pseudo-merges' ' |
| 104 | test_commit other && |
| 105 | |
| 106 | : >trace2.txt && |
| 107 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 108 | git rev-list --count --all --objects --use-bitmap-index >actual && |
| 109 | git rev-list --count --all --objects >expect && |
| 110 | |
| 111 | test_pseudo_merges_satisfied 8 <trace2.txt && |
| 112 | test_pseudo_merges_cascades 1 <trace2.txt && |
| 113 | test_cmp expect actual |
| 114 | ' |
| 115 | |
| 116 | test_expect_success PERL_TEST_HELPERS 'bitmapPseudoMerge.sampleRate adjusts commit selection rate' ' |
| 117 | test_config bitmapPseudoMerge.test.pattern "refs/tags/" && |
| 118 | test_config bitmapPseudoMerge.test.maxMerges 1 && |
| 119 | test_config bitmapPseudoMerge.test.stableThreshold never && |
| 120 | |
| 121 | commits_nr=$(git rev-list --all --count) && |
| 122 | |
| 123 | for rate in 1.0 0.5 0.25 |
| 124 | do |
| 125 | git -c bitmapPseudoMerge.test.sampleRate=$rate repack -adb && |
| 126 | |
| 127 | test_pseudo_merges >merges && |
| 128 | test_line_count = 1 merges && |
| 129 | test_pseudo_merge_commits 0 >commits && |
| 130 | |
| 131 | test-tool bitmap list-commits >bitmaps && |
| 132 | bitmaps_nr="$(wc -l <bitmaps)" && |
| 133 | |
| 134 | perl -MPOSIX -e "print ceil(\$ARGV[0]*(\$ARGV[1]-\$ARGV[2]))" \ |
| 135 | "$rate" "$commits_nr" "$bitmaps_nr" >expect && |
| 136 | |
| 137 | test $(cat expect) -eq $(wc -l <commits) || return 1 |
| 138 | done |
| 139 | ' |
| 140 | |
| 141 | test_expect_success 'bitmapPseudoMerge.threshold excludes newer commits' ' |
| 142 | git init pseudo-merge-threshold && |
| 143 | ( |
| 144 | cd pseudo-merge-threshold && |
| 145 | |
| 146 | new="1672549200" && # 2023-01-01 |
| 147 | old="1641013200" && # 2022-01-01 |
| 148 | |
| 149 | GIT_COMMITTER_DATE="$new +0000" && |
| 150 | export GIT_COMMITTER_DATE && |
| 151 | test_commit_bulk --message="new" --notick 128 && |
| 152 | |
| 153 | GIT_COMMITTER_DATE="$old +0000" && |
| 154 | export GIT_COMMITTER_DATE && |
| 155 | test_commit_bulk --message="old" --notick 128 && |
| 156 | |
| 157 | tag_everything && |
| 158 | |
| 159 | git \ |
| 160 | -c bitmapPseudoMerge.test.pattern="refs/tags/" \ |
| 161 | -c bitmapPseudoMerge.test.maxMerges=1 \ |
| 162 | -c bitmapPseudoMerge.test.threshold=$(($new - 1)) \ |
| 163 | -c bitmapPseudoMerge.test.stableThreshold=never \ |
| 164 | repack -adb && |
| 165 | |
| 166 | test_pseudo_merges >merges && |
| 167 | test_line_count = 1 merges && |
| 168 | |
| 169 | test_pseudo_merge_commits 0 >oids && |
| 170 | git cat-file --batch <oids >commits && |
| 171 | |
| 172 | test $(wc -l <oids) = $(grep -c "^committer.*$old +0000$" commits) |
| 173 | ) |
| 174 | ' |
| 175 | |
| 176 | test_expect_success 'bitmapPseudoMerge.stableThreshold creates stable groups' ' |
| 177 | ( |
| 178 | cd pseudo-merge-threshold && |
| 179 | |
| 180 | new="1672549200" && # 2023-01-01 |
| 181 | mid="1654059600" && # 2022-06-01 |
| 182 | old="1641013200" && # 2022-01-01 |
| 183 | |
| 184 | GIT_COMMITTER_DATE="$mid +0000" && |
| 185 | export GIT_COMMITTER_DATE && |
| 186 | test_commit_bulk --message="mid" --notick 128 && |
| 187 | |
| 188 | git for-each-ref --format="delete %(refname)" refs/tags >in && |
| 189 | git update-ref --stdin <in && |
| 190 | |
| 191 | tag_everything && |
| 192 | |
| 193 | git \ |
| 194 | -c bitmapPseudoMerge.test.pattern="refs/tags/" \ |
| 195 | -c bitmapPseudoMerge.test.maxMerges=1 \ |
| 196 | -c bitmapPseudoMerge.test.threshold=$(($new - 1)) \ |
| 197 | -c bitmapPseudoMerge.test.stableThreshold=$(($mid - 1)) \ |
| 198 | -c bitmapPseudoMerge.test.stableSize=10 \ |
| 199 | repack -adb && |
| 200 | |
| 201 | test_pseudo_merges >merges && |
| 202 | merges_nr="$(wc -l <merges)" && |
| 203 | |
| 204 | for i in $(test_seq $(($merges_nr - 1))) |
| 205 | do |
| 206 | test_pseudo_merge_commits 0 >oids && |
| 207 | git cat-file --batch <oids >commits && |
| 208 | |
| 209 | expect="$(grep -c "^committer.*$old +0000$" commits)" && |
| 210 | actual="$(wc -l <oids)" && |
| 211 | |
| 212 | test $expect = $actual || return 1 |
| 213 | done && |
| 214 | |
| 215 | test_pseudo_merge_commits $(($merges_nr - 1)) >oids && |
| 216 | git cat-file --batch <oids >commits && |
| 217 | test $(wc -l <oids) = $(grep -c "^committer.*$mid +0000$" commits) |
| 218 | ) |
| 219 | ' |
| 220 | |
| 221 | test_expect_success 'out of order thresholds are rejected' ' |
| 222 | # Disable the test var to remove a stderr message. |
| 223 | test_must_fail env GIT_TEST_NAME_HASH_VERSION=1 git \ |
| 224 | -c bitmapPseudoMerge.test.pattern="refs/*" \ |
| 225 | -c bitmapPseudoMerge.test.threshold=1.month.ago \ |
| 226 | -c bitmapPseudoMerge.test.stableThreshold=1.week.ago \ |
| 227 | repack -adb 2>err && |
| 228 | |
| 229 | cat >expect <<-EOF && |
| 230 | fatal: pseudo-merge group ${SQ}test${SQ} has unstable threshold before stable one |
| 231 | EOF |
| 232 | |
| 233 | test_cmp expect err |
| 234 | ' |
| 235 | |
| 236 | test_expect_success 'pseudo-merge pattern with capture groups' ' |
| 237 | git init pseudo-merge-captures && |
| 238 | ( |
| 239 | cd pseudo-merge-captures && |
| 240 | |
| 241 | test_commit_bulk 128 && |
| 242 | tag_everything && |
| 243 | |
| 244 | for r in $(test_seq 8) |
| 245 | do |
| 246 | test_commit_bulk 16 && |
| 247 | |
| 248 | git rev-list HEAD~16.. >in && |
| 249 | sed "s|\(.*\)|create refs/remotes/$r/tags/\1 \1|" in >refs && |
| 250 | git update-ref --stdin <refs || return 1 |
| 251 | done && |
| 252 | |
| 253 | git \ |
| 254 | -c bitmapPseudoMerge.tags.pattern="refs/remotes/([0-9]+)/tags/" \ |
| 255 | -c bitmapPseudoMerge.tags.maxMerges=1 \ |
| 256 | repack -adb && |
| 257 | |
| 258 | git for-each-ref --format="%(objectname) %(refname)" >refs && |
| 259 | |
| 260 | test_pseudo_merges >merges && |
| 261 | for m in $(test_seq 0 $(($(wc -l <merges) - 1))) |
| 262 | do |
| 263 | test_pseudo_merge_commits $m >oids && |
| 264 | grep -f oids refs | |
| 265 | sed -n "s|refs/remotes/\([0-9][0-9]*\)/|\1|p" && |
| 266 | sort -u || return 1 |
| 267 | done >remotes && |
| 268 | |
| 269 | test $(wc -l <remotes) -eq $(sort -u <remotes | wc -l) |
| 270 | ) |
| 271 | ' |
| 272 | |
| 273 | test_expect_success 'pseudo-merge overlap setup' ' |
| 274 | git init pseudo-merge-overlap && |
| 275 | ( |
| 276 | cd pseudo-merge-overlap && |
| 277 | |
| 278 | test_commit_bulk 256 && |
| 279 | tag_everything && |
| 280 | |
| 281 | git \ |
| 282 | -c bitmapPseudoMerge.all.pattern="refs/" \ |
| 283 | -c bitmapPseudoMerge.all.maxMerges=1 \ |
| 284 | -c bitmapPseudoMerge.all.stableThreshold=never \ |
| 285 | -c bitmapPseudoMerge.tags.pattern="refs/tags/" \ |
| 286 | -c bitmapPseudoMerge.tags.maxMerges=1 \ |
| 287 | -c bitmapPseudoMerge.tags.stableThreshold=never \ |
| 288 | repack -adb |
| 289 | ) |
| 290 | ' |
| 291 | |
| 292 | test_expect_success 'pseudo-merge overlap generates overlapping groups' ' |
| 293 | ( |
| 294 | cd pseudo-merge-overlap && |
| 295 | |
| 296 | test_pseudo_merges >merges && |
| 297 | test_line_count = 2 merges && |
| 298 | |
| 299 | test_pseudo_merge_commits 0 >commits-0.raw && |
| 300 | test_pseudo_merge_commits 1 >commits-1.raw && |
| 301 | |
| 302 | sort commits-0.raw >commits-0 && |
| 303 | sort commits-1.raw >commits-1 && |
| 304 | |
| 305 | comm -12 commits-0 commits-1 >overlap && |
| 306 | |
| 307 | test_line_count -gt 0 overlap |
| 308 | ) |
| 309 | ' |
| 310 | |
| 311 | test_expect_success 'pseudo-merge overlap traversal' ' |
| 312 | ( |
| 313 | cd pseudo-merge-overlap && |
| 314 | |
| 315 | : >trace2.txt && |
| 316 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 317 | git rev-list --count --all --objects --use-bitmap-index >actual && |
| 318 | git rev-list --count --all --objects >expect && |
| 319 | |
| 320 | test_pseudo_merges_satisfied 2 <trace2.txt && |
| 321 | test_pseudo_merges_cascades 1 <trace2.txt && |
| 322 | test_cmp expect actual |
| 323 | ) |
| 324 | ' |
| 325 | |
| 326 | test_expect_success 'pseudo-merge overlap stale traversal' ' |
| 327 | ( |
| 328 | cd pseudo-merge-overlap && |
| 329 | |
| 330 | test_commit other && |
| 331 | |
| 332 | : >trace2.txt && |
| 333 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 334 | git rev-list --count --all --objects --use-bitmap-index >actual && |
| 335 | git rev-list --count --all --objects >expect && |
| 336 | |
| 337 | test_pseudo_merges_satisfied 2 <trace2.txt && |
| 338 | test_pseudo_merges_cascades 1 <trace2.txt && |
| 339 | test_cmp expect actual |
| 340 | ) |
| 341 | ' |
| 342 | |
| 343 | test_expect_success 'pseudo-merge reuse' ' |
| 344 | git init pseudo-merge-reuse && |
| 345 | ( |
| 346 | cd pseudo-merge-reuse && |
| 347 | |
| 348 | stable="1641013200" && # 2022-01-01 |
| 349 | unstable="1672549200" && # 2023-01-01 |
| 350 | |
| 351 | GIT_COMMITTER_DATE="$stable +0000" && |
| 352 | export GIT_COMMITTER_DATE && |
| 353 | test_commit_bulk --notick 128 && |
| 354 | GIT_COMMITTER_DATE="$unstable +0000" && |
| 355 | export GIT_COMMITTER_DATE && |
| 356 | test_commit_bulk --notick 128 && |
| 357 | |
| 358 | tag_everything && |
| 359 | |
| 360 | git \ |
| 361 | -c bitmapPseudoMerge.test.pattern="refs/tags/" \ |
| 362 | -c bitmapPseudoMerge.test.maxMerges=1 \ |
| 363 | -c bitmapPseudoMerge.test.threshold=now \ |
| 364 | -c bitmapPseudoMerge.test.stableThreshold=$(($unstable - 1)) \ |
| 365 | -c bitmapPseudoMerge.test.stableSize=512 \ |
| 366 | repack -adb && |
| 367 | |
| 368 | test_pseudo_merges >merges && |
| 369 | test_line_count = 2 merges && |
| 370 | |
| 371 | test_pseudo_merge_commits 0 >stable-oids.before && |
| 372 | test_pseudo_merge_commits 1 >unstable-oids.before && |
| 373 | |
| 374 | : >trace2.txt && |
| 375 | GIT_TRACE2_EVENT=$PWD/trace2.txt git \ |
| 376 | -c bitmapPseudoMerge.test.pattern="refs/tags/" \ |
| 377 | -c bitmapPseudoMerge.test.maxMerges=2 \ |
| 378 | -c bitmapPseudoMerge.test.threshold=now \ |
| 379 | -c bitmapPseudoMerge.test.stableThreshold=$(($unstable - 1)) \ |
| 380 | -c bitmapPseudoMerge.test.stableSize=512 \ |
| 381 | repack -adb && |
| 382 | |
| 383 | test_pseudo_merges_reused 1 <trace2.txt && |
| 384 | |
| 385 | test_pseudo_merges >merges && |
| 386 | test_line_count = 3 merges && |
| 387 | |
| 388 | test_pseudo_merge_commits 0 >stable-oids.after && |
| 389 | for i in 1 2 |
| 390 | do |
| 391 | test_pseudo_merge_commits $i || return 1 |
| 392 | done >unstable-oids.after && |
| 393 | |
| 394 | sort -u <stable-oids.before >expect && |
| 395 | sort -u <stable-oids.after >actual && |
| 396 | test_cmp expect actual && |
| 397 | |
| 398 | sort -u <unstable-oids.before >expect && |
| 399 | sort -u <unstable-oids.after >actual && |
| 400 | test_cmp expect actual |
| 401 | ) |
| 402 | ' |
| 403 | |
| 404 | test_expect_success 'empty pseudo-merge group' ' |
| 405 | git init pseudo-merge-empty-group && |
| 406 | ( |
| 407 | cd pseudo-merge-empty-group && |
| 408 | |
| 409 | # Ensure that a pseudo-merge group with no unstable |
| 410 | # commits does not generate an empty pseudo-merge |
| 411 | # bitmap. |
| 412 | git config bitmapPseudoMerge.empty.pattern refs/ && |
| 413 | |
| 414 | test_commit base && |
| 415 | git repack -adb && |
| 416 | |
| 417 | test-tool bitmap dump-pseudo-merges >merges && |
| 418 | test_line_count = 1 merges && |
| 419 | |
| 420 | test 0 -eq "$(grep -c commits=0 <merges)" |
| 421 | ) |
| 422 | ' |
| 423 | |
| 424 | test_expect_success 'pseudo-merge closure' ' |
| 425 | git init pseudo-merge-closure && |
| 426 | ( |
| 427 | cd pseudo-merge-closure && |
| 428 | |
| 429 | test_commit A && |
| 430 | git repack -d && |
| 431 | |
| 432 | test_commit B && |
| 433 | |
| 434 | # Note that the contents of A is packed, but B is not. A |
| 435 | # (and the objects reachable from it) are thus visible |
| 436 | # to the MIDX, but the same is not true for B and its |
| 437 | # objects. |
| 438 | # |
| 439 | # Ensure that we do not attempt to create a pseudo-merge |
| 440 | # for B, depsite it matching the below pseudo-merge |
| 441 | # group pattern, as doing so would result in a failure |
| 442 | # to write a non-closed bitmap. |
| 443 | git config bitmapPseudoMerge.test.pattern refs/ && |
| 444 | git config bitmapPseudoMerge.test.threshold now && |
| 445 | |
| 446 | git multi-pack-index write --bitmap && |
| 447 | |
| 448 | test-tool bitmap dump-pseudo-merges >pseudo-merges && |
| 449 | test_line_count = 1 pseudo-merges && |
| 450 | |
| 451 | git rev-parse A >expect && |
| 452 | |
| 453 | test-tool bitmap list-commits >actual && |
| 454 | test_cmp expect actual && |
| 455 | test-tool bitmap dump-pseudo-merge-commits 0 >actual && |
| 456 | test_cmp expect actual |
| 457 | ) |
| 458 | ' |
| 459 | |
| 460 | test_expect_success 'use pseudo-merge in boundary traversal' ' |
| 461 | git init pseudo-merge-boundary-traversal && |
| 462 | ( |
| 463 | cd pseudo-merge-boundary-traversal && |
| 464 | |
| 465 | git config bitmapPseudoMerge.test.pattern refs/ && |
| 466 | git config pack.useBitmapBoundaryTraversal true && |
| 467 | |
| 468 | test_commit A && |
| 469 | git repack -adb && |
| 470 | test_commit B && |
| 471 | |
| 472 | nr=$(git rev-list --count --use-bitmap-index HEAD~1..HEAD) && |
| 473 | test 1 -eq "$nr" |
| 474 | ) |
| 475 | ' |
| 476 | |
| 477 | test_expect_success 'apply pseudo-merges during fill-in traversal' ' |
| 478 | test_when_finished "rm -fr pseudo-merge-fill-in-traversal" && |
| 479 | git init pseudo-merge-fill-in-traversal && |
| 480 | ( |
| 481 | cd pseudo-merge-fill-in-traversal && |
| 482 | |
| 483 | git config bitmapPseudoMerge.test.pattern refs/tags/ && |
| 484 | git config bitmapPseudoMerge.test.maxMerges 1 && |
| 485 | git config bitmapPseudoMerge.test.stableThreshold never && |
| 486 | |
| 487 | test_commit_bulk 64 && |
| 488 | tag_everything && |
| 489 | git repack -ad && |
| 490 | |
| 491 | pack=$(ls .git/objects/pack/pack-*.pack) && |
| 492 | git rev-parse HEAD~63 >in && |
| 493 | test-tool bitmap write "$(basename $pack)" <in && |
| 494 | |
| 495 | test_pseudo_merges >merges && |
| 496 | test_line_count = 1 merges && |
| 497 | |
| 498 | test_commit stale && |
| 499 | |
| 500 | git rev-list --count --objects HEAD >expect && |
| 501 | |
| 502 | : >trace2.txt && |
| 503 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 504 | git rev-list --count --objects --use-bitmap-index HEAD >actual && |
| 505 | test_pseudo_merges_satisfied 1 <trace2.txt && |
| 506 | |
| 507 | test_cmp expect actual |
| 508 | ) |
| 509 | ' |
| 510 | |
| 511 | test_expect_success 'apply pseudo-merges from multiple groups during fill-in' ' |
| 512 | test_when_finished "rm -fr pseudo-merge-fill-in-multi" && |
| 513 | git init pseudo-merge-fill-in-multi && |
| 514 | ( |
| 515 | cd pseudo-merge-fill-in-multi && |
| 516 | |
| 517 | test_commit base && |
| 518 | base=$(git rev-parse HEAD) && |
| 519 | |
| 520 | for side in left right |
| 521 | do |
| 522 | git checkout -B $side base && |
| 523 | |
| 524 | test_commit_bulk --id=$side 64 && |
| 525 | git rev-list --no-object-names HEAD --not $base >in && |
| 526 | while read oid |
| 527 | do |
| 528 | echo "create refs/group-$side/$oid $oid" || return 1 |
| 529 | done <in | git update-ref --stdin || return 1 |
| 530 | done && |
| 531 | |
| 532 | git checkout left && |
| 533 | git merge right && |
| 534 | git repack -ad && |
| 535 | |
| 536 | git config bitmapPseudoMerge.left.pattern "refs/group-left/" && |
| 537 | git config bitmapPseudoMerge.left.maxMerges 1 && |
| 538 | git config bitmapPseudoMerge.left.stableThreshold never && |
| 539 | |
| 540 | git config bitmapPseudoMerge.right.pattern "refs/group-right/" && |
| 541 | git config bitmapPseudoMerge.right.maxMerges 1 && |
| 542 | git config bitmapPseudoMerge.right.stableThreshold never && |
| 543 | |
| 544 | pack="$(ls .git/objects/pack/pack-*.pack)" && |
| 545 | git rev-parse "$base" >in && |
| 546 | test-tool bitmap write "$(basename $pack)" <in && |
| 547 | |
| 548 | test_pseudo_merges >merges && |
| 549 | test_line_count = 2 merges && |
| 550 | |
| 551 | test_commit stale && |
| 552 | |
| 553 | git rev-list --count --objects HEAD >expect && |
| 554 | |
| 555 | : >trace2.txt && |
| 556 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 557 | git rev-list --count --objects --use-bitmap-index HEAD >actual && |
| 558 | test_pseudo_merges_satisfied 2 <trace2.txt && |
| 559 | |
| 560 | test_cmp expect actual |
| 561 | ) |
| 562 | ' |
| 563 | |
| 564 | test_expect_success 'apply pseudo-merges with overlapping groups during fill-in' ' |
| 565 | test_when_finished "rm -fr pseudo-merge-fill-in-overlap" && |
| 566 | git init pseudo-merge-fill-in-overlap && |
| 567 | ( |
| 568 | cd pseudo-merge-fill-in-overlap && |
| 569 | |
| 570 | test_commit_bulk 64 && |
| 571 | tag_everything && |
| 572 | git repack -ad && |
| 573 | |
| 574 | pack="$(ls .git/objects/pack/pack-*.pack)" && |
| 575 | |
| 576 | # Use two pseudo-merge group patterns that both match |
| 577 | # refs/tags/, so every tagged commit belongs to both |
| 578 | # groups. This exercises the extended lookup table |
| 579 | # path in apply_pseudo_merges_for_commit(). |
| 580 | git config bitmapPseudoMerge.all.pattern "refs/tags/" && |
| 581 | git config bitmapPseudoMerge.all.maxMerges 1 && |
| 582 | git config bitmapPseudoMerge.all.stableThreshold never && |
| 583 | |
| 584 | git config bitmapPseudoMerge.tags.pattern "refs/tags/" && |
| 585 | git config bitmapPseudoMerge.tags.maxMerges 1 && |
| 586 | git config bitmapPseudoMerge.tags.stableThreshold never && |
| 587 | |
| 588 | git rev-parse HEAD~63 >in && |
| 589 | test-tool bitmap write "$(basename $pack)" <in && |
| 590 | |
| 591 | test_pseudo_merges >merges && |
| 592 | test_line_count = 2 merges && |
| 593 | |
| 594 | test_commit stale && |
| 595 | |
| 596 | git rev-list --count --objects HEAD >expect && |
| 597 | |
| 598 | : >trace2.txt && |
| 599 | GIT_TRACE2_EVENT=$PWD/trace2.txt \ |
| 600 | git rev-list --count --objects --use-bitmap-index HEAD >actual && |
| 601 | test_pseudo_merges_satisfied 2 <trace2.txt && |
| 602 | |
| 603 | test_cmp expect actual |
| 604 | ) |
| 605 | ' |
| 606 | |
| 607 | test_expect_success 'pseudo-merge commits are correctly classified by date' ' |
| 608 | test_when_finished "rm -fr pseudo-merge-date-classification" && |
| 609 | git init pseudo-merge-date-classification && |
| 610 | ( |
| 611 | cd pseudo-merge-date-classification && |
| 612 | |
| 613 | test_commit_bulk 64 && |
| 614 | |
| 615 | tag_everything && |
| 616 | git repack -ad && |
| 617 | |
| 618 | pack="$(ls .git/objects/pack/pack-*.pack)" && |
| 619 | |
| 620 | # Configure two pseudo-merge groups: one that only |
| 621 | # matches "stable" refs (older than one month), and |
| 622 | # one that matches all refs. With 64 tags whose |
| 623 | # commits are all younger than one month, the |
| 624 | # "stable" group should have zero pseudo-merges and |
| 625 | # the "all" group should have one. |
| 626 | # |
| 627 | # Use GIT_TEST_DATE_NOW to align "now" (and therefore |
| 628 | # "1.month.ago") with the test_tick timestamps so that |
| 629 | # the commits are within the last month. |
| 630 | # |
| 631 | # Without parsing the commit, its date field would |
| 632 | # be zero, causing it to satisfy date <= threshold |
| 633 | # for the "stable" group as well, and both groups |
| 634 | # would produce pseudo-merges. |
| 635 | git config bitmapPseudoMerge.stable.pattern "refs/tags/" && |
| 636 | git config bitmapPseudoMerge.stable.maxMerges 64 && |
| 637 | git config bitmapPseudoMerge.stable.stableThreshold never && |
| 638 | git config bitmapPseudoMerge.stable.threshold 1.month.ago && |
| 639 | |
| 640 | git config bitmapPseudoMerge.all.pattern "refs/tags/" && |
| 641 | git config bitmapPseudoMerge.all.maxMerges 1 && |
| 642 | git config bitmapPseudoMerge.all.stableThreshold never && |
| 643 | git config bitmapPseudoMerge.all.threshold now && |
| 644 | |
| 645 | git rev-parse HEAD~63 >in && |
| 646 | GIT_TEST_DATE_NOW=$test_tick \ |
| 647 | test-tool bitmap write "$(basename $pack)" <in && |
| 648 | |
| 649 | test_pseudo_merges >merges && |
| 650 | test_line_count = 1 merges |
| 651 | ) |
| 652 | ' |
| 653 | |
| 654 | test_expect_success 'sampleRate=0 does not cause division by zero' ' |
| 655 | test_when_finished "rm -fr pseudo-merge-sample-rate-zero" && |
| 656 | git init pseudo-merge-sample-rate-zero && |
| 657 | ( |
| 658 | cd pseudo-merge-sample-rate-zero && |
| 659 | |
| 660 | test_commit_bulk 64 && |
| 661 | tag_everything && |
| 662 | git repack -ad && |
| 663 | |
| 664 | pack="$(ls .git/objects/pack/pack-*.pack)" && |
| 665 | |
| 666 | git config bitmapPseudoMerge.test.pattern "refs/tags/" && |
| 667 | git config bitmapPseudoMerge.test.maxMerges 1 && |
| 668 | git config bitmapPseudoMerge.test.sampleRate 0 && |
| 669 | git config bitmapPseudoMerge.test.threshold now && |
| 670 | git config bitmapPseudoMerge.test.stableThreshold never && |
| 671 | |
| 672 | git rev-parse HEAD~63 >in && |
| 673 | test-tool bitmap write "$(basename $pack)" <in |
| 674 | ) |
| 675 | ' |
| 676 | |
| 677 | test_expect_success 'duplicate pseudo-merge pattern does not leak' ' |
| 678 | test_when_finished "rm -fr pseudo-merge-dup-pattern" && |
| 679 | git init pseudo-merge-dup-pattern && |
| 680 | ( |
| 681 | cd pseudo-merge-dup-pattern && |
| 682 | |
| 683 | test_commit_bulk 64 && |
| 684 | tag_everything && |
| 685 | git repack -ad && |
| 686 | |
| 687 | pack=$(ls .git/objects/pack/pack-*.pack) && |
| 688 | |
| 689 | # Set the same group'\''s pattern twice. The second |
| 690 | # assignment should cleanly release the compiled regex |
| 691 | # from the first without leaking. |
| 692 | git config bitmapPseudoMerge.test.pattern "refs/tags/" && |
| 693 | git config --add bitmapPseudoMerge.test.pattern "refs/tags/" && |
| 694 | git config bitmapPseudoMerge.test.maxMerges 1 && |
| 695 | git config bitmapPseudoMerge.test.threshold now && |
| 696 | git config bitmapPseudoMerge.test.stableThreshold never && |
| 697 | |
| 698 | git rev-parse HEAD~63 >in && |
| 699 | test-tool bitmap write "$(basename $pack)" <in && |
| 700 | |
| 701 | test_pseudo_merges >merges && |
| 702 | test_line_count = 1 merges |
| 703 | ) |
| 704 | ' |
| 705 | |
| 706 | test_done |