| 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2007 Junio C Hamano |
| 4 | # |
| 5 | |
| 6 | test_description='Test prune and reflog expiration' |
| 7 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 8 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 9 | |
| 10 | . ./test-lib.sh |
| 11 | |
| 12 | check_have () { |
| 13 | gaah= && |
| 14 | for N in "$@" |
| 15 | do |
| 16 | eval "o=\$$N" && git cat-file -t $o || { |
| 17 | echo Gaah $N |
| 18 | gaah=$N |
| 19 | break |
| 20 | } |
| 21 | done && |
| 22 | test -z "$gaah" |
| 23 | } |
| 24 | |
| 25 | check_fsck () { |
| 26 | git fsck --full >fsck.output |
| 27 | case "$1" in |
| 28 | '') |
| 29 | test_must_be_empty fsck.output ;; |
| 30 | *) |
| 31 | test_grep "$1" fsck.output ;; |
| 32 | esac |
| 33 | } |
| 34 | |
| 35 | corrupt () { |
| 36 | mv .git/objects/$(test_oid_to_path $1) .git/$1 |
| 37 | } |
| 38 | |
| 39 | recover () { |
| 40 | aa=$(echo $1 | cut -c 1-2) |
| 41 | mkdir -p .git/objects/$aa |
| 42 | mv .git/$1 .git/objects/$(test_oid_to_path $1) |
| 43 | } |
| 44 | |
| 45 | check_dont_have () { |
| 46 | gaah= && |
| 47 | for N in "$@" |
| 48 | do |
| 49 | eval "o=\$$N" |
| 50 | git cat-file -t $o && { |
| 51 | echo Gaah $N |
| 52 | gaah=$N |
| 53 | break |
| 54 | } |
| 55 | done |
| 56 | test -z "$gaah" |
| 57 | } |
| 58 | |
| 59 | test_expect_success setup ' |
| 60 | mkdir -p A/B && |
| 61 | echo rat >C && |
| 62 | echo ox >A/D && |
| 63 | echo tiger >A/B/E && |
| 64 | git add . && |
| 65 | |
| 66 | test_tick && git commit -m rabbit && |
| 67 | H=$(git rev-parse --verify HEAD) && |
| 68 | A=$(git rev-parse --verify HEAD:A) && |
| 69 | B=$(git rev-parse --verify HEAD:A/B) && |
| 70 | C=$(git rev-parse --verify HEAD:C) && |
| 71 | D=$(git rev-parse --verify HEAD:A/D) && |
| 72 | E=$(git rev-parse --verify HEAD:A/B/E) && |
| 73 | check_fsck && |
| 74 | |
| 75 | test_chmod +x C && |
| 76 | git add C && |
| 77 | test_tick && git commit -m dragon && |
| 78 | L=$(git rev-parse --verify HEAD) && |
| 79 | check_fsck && |
| 80 | |
| 81 | rm -f C A/B/E && |
| 82 | echo snake >F && |
| 83 | echo horse >A/G && |
| 84 | git add F A/G && |
| 85 | test_tick && git commit -a -m sheep && |
| 86 | F=$(git rev-parse --verify HEAD:F) && |
| 87 | G=$(git rev-parse --verify HEAD:A/G) && |
| 88 | I=$(git rev-parse --verify HEAD:A) && |
| 89 | J=$(git rev-parse --verify HEAD) && |
| 90 | check_fsck && |
| 91 | |
| 92 | rm -f A/G && |
| 93 | test_tick && git commit -a -m monkey && |
| 94 | K=$(git rev-parse --verify HEAD) && |
| 95 | check_fsck && |
| 96 | |
| 97 | check_have A B C D E F G H I J K L && |
| 98 | |
| 99 | git prune && |
| 100 | |
| 101 | check_have A B C D E F G H I J K L && |
| 102 | |
| 103 | check_fsck && |
| 104 | |
| 105 | git reflog refs/heads/main >output && |
| 106 | test_line_count = 4 output |
| 107 | ' |
| 108 | |
| 109 | test_expect_success 'correct usage on sub-command -h' ' |
| 110 | test_expect_code 129 git reflog expire -h >err && |
| 111 | grep "git reflog expire" err |
| 112 | ' |
| 113 | |
| 114 | test_expect_success 'correct usage on "git reflog show -h"' ' |
| 115 | test_expect_code 129 git reflog show -h >err && |
| 116 | grep -F "git reflog [show]" err |
| 117 | ' |
| 118 | |
| 119 | test_expect_success 'pass through -- to sub-command' ' |
| 120 | test_when_finished "rm -rf repo" && |
| 121 | git init repo && |
| 122 | test_commit -C repo message --a-file contents dash-tag && |
| 123 | |
| 124 | git -C repo reflog show -- --does-not-exist >out && |
| 125 | test_must_be_empty out && |
| 126 | git -C repo reflog show >expect && |
| 127 | git -C repo reflog show -- --a-file >actual && |
| 128 | test_cmp expect actual |
| 129 | ' |
| 130 | |
| 131 | test_expect_success rewind ' |
| 132 | test_tick && git reset --hard HEAD~2 && |
| 133 | test_path_is_file C && |
| 134 | test_path_is_file A/B/E && |
| 135 | test_path_is_missing F && |
| 136 | test_path_is_missing A/G && |
| 137 | |
| 138 | check_have A B C D E F G H I J K L && |
| 139 | |
| 140 | git prune && |
| 141 | |
| 142 | check_have A B C D E F G H I J K L && |
| 143 | |
| 144 | git reflog refs/heads/main >output && |
| 145 | test_line_count = 5 output |
| 146 | ' |
| 147 | |
| 148 | test_expect_success 'reflog expire should not barf on an annotated tag' ' |
| 149 | test_when_finished "git tag -d v0.tag || :" && |
| 150 | git -c core.logAllRefUpdates=always \ |
| 151 | tag -a -m "tag name" v0.tag main && |
| 152 | git reflog expire --dry-run refs/tags/v0.tag 2>err && |
| 153 | test_grep ! "error: [Oo]bject .* not a commit" err |
| 154 | ' |
| 155 | |
| 156 | test_expect_success 'corrupt and check' ' |
| 157 | |
| 158 | corrupt $F && |
| 159 | check_fsck "missing blob $F" |
| 160 | |
| 161 | ' |
| 162 | |
| 163 | test_expect_success 'reflog expire --dry-run should not touch reflog' ' |
| 164 | |
| 165 | git reflog expire --dry-run \ |
| 166 | --expire=$(($test_tick - 10000)) \ |
| 167 | --expire-unreachable=$(($test_tick - 10000)) \ |
| 168 | --stale-fix \ |
| 169 | --all && |
| 170 | |
| 171 | git reflog refs/heads/main >output && |
| 172 | test_line_count = 5 output && |
| 173 | |
| 174 | check_fsck "missing blob $F" |
| 175 | ' |
| 176 | |
| 177 | test_expect_success 'reflog expire' ' |
| 178 | |
| 179 | git reflog expire --verbose \ |
| 180 | --expire=$(($test_tick - 10000)) \ |
| 181 | --expire-unreachable=$(($test_tick - 10000)) \ |
| 182 | --stale-fix \ |
| 183 | --all && |
| 184 | |
| 185 | git reflog refs/heads/main >output && |
| 186 | test_line_count = 2 output && |
| 187 | |
| 188 | check_fsck "dangling commit $K" |
| 189 | ' |
| 190 | |
| 191 | test_expect_success '--stale-fix handles missing objects generously' ' |
| 192 | git -c core.logAllRefUpdates=false fast-import --date-format=now <<-EOS && |
| 193 | commit refs/heads/stale-fix |
| 194 | mark :1 |
| 195 | committer Author <a@uth.or> now |
| 196 | data <<EOF |
| 197 | start stale fix |
| 198 | EOF |
| 199 | M 100644 inline file |
| 200 | data <<EOF |
| 201 | contents |
| 202 | EOF |
| 203 | commit refs/heads/stale-fix |
| 204 | committer Author <a@uth.or> now |
| 205 | data <<EOF |
| 206 | stale fix branch tip |
| 207 | EOF |
| 208 | from :1 |
| 209 | EOS |
| 210 | |
| 211 | parent_oid=$(git rev-parse stale-fix^) && |
| 212 | test_when_finished "recover $parent_oid" && |
| 213 | corrupt $parent_oid && |
| 214 | git reflog expire --stale-fix |
| 215 | ' |
| 216 | |
| 217 | test_expect_success 'prune and fsck' ' |
| 218 | |
| 219 | git prune && |
| 220 | check_fsck && |
| 221 | |
| 222 | check_have A B C D E H L && |
| 223 | check_dont_have F G I J K |
| 224 | |
| 225 | ' |
| 226 | |
| 227 | test_expect_success 'recover and check' ' |
| 228 | |
| 229 | recover $F && |
| 230 | check_fsck "dangling blob $F" |
| 231 | |
| 232 | ' |
| 233 | |
| 234 | test_expect_success 'delete' ' |
| 235 | echo 1 > C && |
| 236 | test_tick && |
| 237 | git commit -m rat C && |
| 238 | |
| 239 | echo 2 > C && |
| 240 | test_tick && |
| 241 | git commit -m ox C && |
| 242 | |
| 243 | echo 3 > C && |
| 244 | test_tick && |
| 245 | git commit -m tiger C && |
| 246 | |
| 247 | HEAD_entry_count=$(git reflog | wc -l) && |
| 248 | main_entry_count=$(git reflog show main | wc -l) && |
| 249 | |
| 250 | test $HEAD_entry_count = 5 && |
| 251 | test $main_entry_count = 5 && |
| 252 | |
| 253 | |
| 254 | git reflog delete main@{1} && |
| 255 | git reflog show main > output && |
| 256 | test_line_count = $(($main_entry_count - 1)) output && |
| 257 | test $HEAD_entry_count = $(git reflog | wc -l) && |
| 258 | ! grep ox < output && |
| 259 | |
| 260 | main_entry_count=$(wc -l < output) && |
| 261 | |
| 262 | git reflog delete HEAD@{1} && |
| 263 | test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) && |
| 264 | test $main_entry_count = $(git reflog show main | wc -l) && |
| 265 | |
| 266 | HEAD_entry_count=$(git reflog | wc -l) && |
| 267 | |
| 268 | git reflog delete main@{07.04.2005.15:15:00.-0700} && |
| 269 | git reflog show main > output && |
| 270 | test_line_count = $(($main_entry_count - 1)) output && |
| 271 | ! grep dragon < output |
| 272 | |
| 273 | ' |
| 274 | |
| 275 | test_expect_success 'rewind2' ' |
| 276 | |
| 277 | test_tick && git reset --hard HEAD~2 && |
| 278 | git reflog refs/heads/main >output && |
| 279 | test_line_count = 4 output |
| 280 | ' |
| 281 | |
| 282 | test_expect_success '--expire=never' ' |
| 283 | |
| 284 | git reflog expire --verbose \ |
| 285 | --expire=never \ |
| 286 | --expire-unreachable=never \ |
| 287 | --all && |
| 288 | git reflog refs/heads/main >output && |
| 289 | test_line_count = 4 output |
| 290 | ' |
| 291 | |
| 292 | test_expect_success 'gc.reflogexpire=never' ' |
| 293 | test_config gc.reflogexpire never && |
| 294 | test_config gc.reflogexpireunreachable never && |
| 295 | |
| 296 | git reflog expire --verbose --all >output && |
| 297 | test_line_count = 9 output && |
| 298 | |
| 299 | git reflog refs/heads/main >output && |
| 300 | test_line_count = 4 output |
| 301 | ' |
| 302 | |
| 303 | test_expect_success 'gc.reflogexpire=false' ' |
| 304 | test_config gc.reflogexpire false && |
| 305 | test_config gc.reflogexpireunreachable false && |
| 306 | |
| 307 | git reflog expire --verbose --all && |
| 308 | git reflog refs/heads/main >output && |
| 309 | test_line_count = 4 output |
| 310 | |
| 311 | ' |
| 312 | |
| 313 | test_expect_success 'git reflog expire unknown reference' ' |
| 314 | test_config gc.reflogexpire never && |
| 315 | test_config gc.reflogexpireunreachable never && |
| 316 | |
| 317 | test_must_fail git reflog expire main@{123} 2>stderr && |
| 318 | test_grep "error: reflog could not be found: ${SQ}main@{123}${SQ}" stderr && |
| 319 | test_must_fail git reflog expire does-not-exist 2>stderr && |
| 320 | test_grep "error: reflog could not be found: ${SQ}does-not-exist${SQ}" stderr |
| 321 | ' |
| 322 | |
| 323 | test_expect_success 'checkout should not delete log for packed ref' ' |
| 324 | test $(git reflog main | wc -l) = 4 && |
| 325 | git branch foo && |
| 326 | git pack-refs --all && |
| 327 | git checkout foo && |
| 328 | test $(git reflog main | wc -l) = 4 |
| 329 | ' |
| 330 | |
| 331 | test_expect_success 'stale dirs do not cause d/f conflicts (reflogs on)' ' |
| 332 | test_when_finished "git branch -d one || git branch -d one/two" && |
| 333 | |
| 334 | git branch one/two main && |
| 335 | echo "one/two@{0} branch: Created from main" >expect && |
| 336 | git log -g --format="%gd %gs" one/two >actual && |
| 337 | test_cmp expect actual && |
| 338 | git branch -d one/two && |
| 339 | |
| 340 | # now logs/refs/heads/one is a stale directory, but |
| 341 | # we should move it out of the way to create "one" reflog |
| 342 | git branch one main && |
| 343 | echo "one@{0} branch: Created from main" >expect && |
| 344 | git log -g --format="%gd %gs" one >actual && |
| 345 | test_cmp expect actual |
| 346 | ' |
| 347 | |
| 348 | test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' ' |
| 349 | test_when_finished "git branch -d one || git branch -d one/two" && |
| 350 | |
| 351 | git branch one/two main && |
| 352 | echo "one/two@{0} branch: Created from main" >expect && |
| 353 | git log -g --format="%gd %gs" one/two >actual && |
| 354 | test_cmp expect actual && |
| 355 | git branch -d one/two && |
| 356 | |
| 357 | # same as before, but we only create a reflog for "one" if |
| 358 | # it already exists, which it does not |
| 359 | git -c core.logallrefupdates=false branch one main && |
| 360 | git log -g --format="%gd %gs" one >actual && |
| 361 | test_must_be_empty actual |
| 362 | ' |
| 363 | |
| 364 | test_expect_success 'no segfaults for reflog containing non-commit sha1s' ' |
| 365 | git update-ref --create-reflog -m "Creating ref" \ |
| 366 | refs/tests/tree-in-reflog HEAD && |
| 367 | git update-ref -m "Forcing tree" refs/tests/tree-in-reflog HEAD^{tree} && |
| 368 | git update-ref -m "Restoring to commit" refs/tests/tree-in-reflog HEAD && |
| 369 | git reflog refs/tests/tree-in-reflog |
| 370 | ' |
| 371 | |
| 372 | test_expect_failure 'reflog with non-commit entries displays all entries' ' |
| 373 | git reflog refs/tests/tree-in-reflog >actual && |
| 374 | test_line_count = 3 actual |
| 375 | ' |
| 376 | |
| 377 | test_expect_success 'continue walking past root commits' ' |
| 378 | git init orphanage && |
| 379 | ( |
| 380 | cd orphanage && |
| 381 | cat >expect <<-\EOF && |
| 382 | HEAD@{0} commit (initial): orphan2-1 |
| 383 | HEAD@{1} commit: orphan1-2 |
| 384 | HEAD@{2} commit (initial): orphan1-1 |
| 385 | HEAD@{3} commit (initial): initial |
| 386 | EOF |
| 387 | test_commit initial && |
| 388 | git checkout --orphan orphan1 && |
| 389 | test_commit orphan1-1 && |
| 390 | test_commit orphan1-2 && |
| 391 | git checkout --orphan orphan2 && |
| 392 | test_commit orphan2-1 && |
| 393 | git log -g --format="%gd %gs" >actual && |
| 394 | test_cmp expect actual |
| 395 | ) |
| 396 | ' |
| 397 | |
| 398 | test_expect_success 'expire with multiple worktrees' ' |
| 399 | git init main-wt && |
| 400 | ( |
| 401 | cd main-wt && |
| 402 | test_tick && |
| 403 | test_commit foo && |
| 404 | git worktree add link-wt && |
| 405 | test_tick && |
| 406 | test_commit -C link-wt foobar && |
| 407 | test_tick && |
| 408 | git reflog expire --verbose --all --expire=$test_tick && |
| 409 | test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD >actual && |
| 410 | test_must_be_empty actual |
| 411 | ) |
| 412 | ' |
| 413 | |
| 414 | test_expect_success 'expire one of multiple worktrees' ' |
| 415 | git init main-wt2 && |
| 416 | ( |
| 417 | cd main-wt2 && |
| 418 | test_tick && |
| 419 | test_commit foo && |
| 420 | git worktree add link-wt && |
| 421 | test_tick && |
| 422 | test_commit -C link-wt foobar && |
| 423 | test_tick && |
| 424 | test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \ |
| 425 | >expect-link-wt && |
| 426 | git reflog expire --verbose --all --expire=$test_tick \ |
| 427 | --single-worktree && |
| 428 | test-tool ref-store worktree:main for-each-reflog-ent HEAD \ |
| 429 | >actual-main && |
| 430 | test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \ |
| 431 | >actual-link-wt && |
| 432 | test_must_be_empty actual-main && |
| 433 | test_cmp expect-link-wt actual-link-wt |
| 434 | ) |
| 435 | ' |
| 436 | |
| 437 | test_expect_success 'empty reflog' ' |
| 438 | test_when_finished "rm -rf empty" && |
| 439 | git init empty && |
| 440 | test_commit -C empty A && |
| 441 | test-tool ref-store main create-reflog refs/heads/foo && |
| 442 | git -C empty reflog expire --all 2>err && |
| 443 | test_must_be_empty err |
| 444 | ' |
| 445 | |
| 446 | test_expect_success 'list reflogs' ' |
| 447 | test_when_finished "rm -rf repo" && |
| 448 | git init repo && |
| 449 | ( |
| 450 | cd repo && |
| 451 | git reflog list >actual && |
| 452 | test_must_be_empty actual && |
| 453 | |
| 454 | test_commit A && |
| 455 | cat >expect <<-EOF && |
| 456 | HEAD |
| 457 | refs/heads/main |
| 458 | EOF |
| 459 | git reflog list >actual && |
| 460 | test_cmp expect actual && |
| 461 | |
| 462 | git branch b && |
| 463 | cat >expect <<-EOF && |
| 464 | HEAD |
| 465 | refs/heads/b |
| 466 | refs/heads/main |
| 467 | EOF |
| 468 | git reflog list >actual && |
| 469 | test_cmp expect actual |
| 470 | ) |
| 471 | ' |
| 472 | |
| 473 | test_expect_success 'list reflogs with worktree' ' |
| 474 | test_when_finished "rm -rf repo" && |
| 475 | git init repo && |
| 476 | ( |
| 477 | cd repo && |
| 478 | |
| 479 | test_commit A && |
| 480 | git worktree add wt && |
| 481 | git -c core.logAllRefUpdates=always \ |
| 482 | update-ref refs/worktree/main HEAD && |
| 483 | git -c core.logAllRefUpdates=always \ |
| 484 | update-ref refs/worktree/per-worktree HEAD && |
| 485 | git -c core.logAllRefUpdates=always -C wt \ |
| 486 | update-ref refs/worktree/per-worktree HEAD && |
| 487 | git -c core.logAllRefUpdates=always -C wt \ |
| 488 | update-ref refs/worktree/worktree HEAD && |
| 489 | |
| 490 | cat >expect <<-EOF && |
| 491 | HEAD |
| 492 | refs/heads/main |
| 493 | refs/heads/wt |
| 494 | refs/worktree/main |
| 495 | refs/worktree/per-worktree |
| 496 | EOF |
| 497 | git reflog list >actual && |
| 498 | test_cmp expect actual && |
| 499 | |
| 500 | cat >expect <<-EOF && |
| 501 | HEAD |
| 502 | refs/heads/main |
| 503 | refs/heads/wt |
| 504 | refs/worktree/per-worktree |
| 505 | refs/worktree/worktree |
| 506 | EOF |
| 507 | git -C wt reflog list >actual && |
| 508 | test_cmp expect actual |
| 509 | ) |
| 510 | ' |
| 511 | |
| 512 | test_expect_success 'reflog list returns error with additional args' ' |
| 513 | cat >expect <<-EOF && |
| 514 | error: list does not accept arguments: ${SQ}bogus${SQ} |
| 515 | EOF |
| 516 | test_must_fail git reflog list bogus 2>err && |
| 517 | test_cmp expect err |
| 518 | ' |
| 519 | |
| 520 | test_expect_success 'reflog for symref with unborn target can be listed' ' |
| 521 | test_when_finished "rm -rf repo" && |
| 522 | git init repo && |
| 523 | ( |
| 524 | cd repo && |
| 525 | test_commit A && |
| 526 | git symbolic-ref HEAD refs/heads/unborn && |
| 527 | cat >expect <<-EOF && |
| 528 | HEAD |
| 529 | refs/heads/main |
| 530 | EOF |
| 531 | git reflog list >actual && |
| 532 | test_cmp expect actual |
| 533 | ) |
| 534 | ' |
| 535 | |
| 536 | test_expect_success 'reflog with invalid object ID can be listed' ' |
| 537 | test_when_finished "rm -rf repo" && |
| 538 | git init repo && |
| 539 | ( |
| 540 | cd repo && |
| 541 | test_commit A && |
| 542 | test-tool ref-store main update-ref msg refs/heads/missing \ |
| 543 | $(test_oid deadbeef) "$ZERO_OID" REF_SKIP_OID_VERIFICATION && |
| 544 | cat >expect <<-EOF && |
| 545 | HEAD |
| 546 | refs/heads/main |
| 547 | refs/heads/missing |
| 548 | EOF |
| 549 | git reflog list >actual && |
| 550 | test_cmp expect actual |
| 551 | ) |
| 552 | ' |
| 553 | |
| 554 | test_expect_success 'reflog drop non-existent ref' ' |
| 555 | test_when_finished "rm -rf repo" && |
| 556 | git init repo && |
| 557 | ( |
| 558 | cd repo && |
| 559 | test_must_fail git reflog exists refs/heads/non-existent && |
| 560 | test_must_fail git reflog drop refs/heads/non-existent 2>stderr && |
| 561 | test_grep "error: reflog could not be found: ${SQ}refs/heads/non-existent${SQ}" stderr |
| 562 | ) |
| 563 | ' |
| 564 | |
| 565 | test_expect_success 'reflog drop' ' |
| 566 | test_when_finished "rm -rf repo" && |
| 567 | git init repo && |
| 568 | ( |
| 569 | cd repo && |
| 570 | test_commit A && |
| 571 | test_commit_bulk --ref=refs/heads/branch 1 && |
| 572 | git reflog exists refs/heads/main && |
| 573 | git reflog exists refs/heads/branch && |
| 574 | git reflog drop refs/heads/main && |
| 575 | test_must_fail git reflog exists refs/heads/main && |
| 576 | git reflog exists refs/heads/branch |
| 577 | ) |
| 578 | ' |
| 579 | |
| 580 | test_expect_success 'reflog drop multiple references' ' |
| 581 | test_when_finished "rm -rf repo" && |
| 582 | git init repo && |
| 583 | ( |
| 584 | cd repo && |
| 585 | test_commit A && |
| 586 | test_commit_bulk --ref=refs/heads/branch 1 && |
| 587 | git reflog exists refs/heads/main && |
| 588 | git reflog exists refs/heads/branch && |
| 589 | git reflog drop refs/heads/main refs/heads/branch && |
| 590 | test_must_fail git reflog exists refs/heads/main && |
| 591 | test_must_fail git reflog exists refs/heads/branch |
| 592 | ) |
| 593 | ' |
| 594 | |
| 595 | test_expect_success 'reflog drop multiple references some non-existent' ' |
| 596 | test_when_finished "rm -rf repo" && |
| 597 | git init repo && |
| 598 | ( |
| 599 | cd repo && |
| 600 | test_commit A && |
| 601 | test_commit_bulk --ref=refs/heads/branch 1 && |
| 602 | git reflog exists refs/heads/main && |
| 603 | git reflog exists refs/heads/branch && |
| 604 | test_must_fail git reflog exists refs/heads/non-existent && |
| 605 | test_must_fail git reflog drop refs/heads/main refs/heads/non-existent refs/heads/branch 2>stderr && |
| 606 | test_must_fail git reflog exists refs/heads/main && |
| 607 | test_must_fail git reflog exists refs/heads/branch && |
| 608 | test_must_fail git reflog exists refs/heads/non-existent && |
| 609 | test_grep "error: reflog could not be found: ${SQ}refs/heads/non-existent${SQ}" stderr |
| 610 | ) |
| 611 | ' |
| 612 | |
| 613 | test_expect_success 'reflog drop --all' ' |
| 614 | test_when_finished "rm -rf repo" && |
| 615 | git init repo && |
| 616 | ( |
| 617 | cd repo && |
| 618 | test_commit A && |
| 619 | test_commit_bulk --ref=refs/heads/branch 1 && |
| 620 | git reflog exists refs/heads/main && |
| 621 | git reflog exists refs/heads/branch && |
| 622 | git reflog drop --all && |
| 623 | test_must_fail git reflog exists refs/heads/main && |
| 624 | test_must_fail git reflog exists refs/heads/branch |
| 625 | ) |
| 626 | ' |
| 627 | |
| 628 | test_expect_success 'reflog drop --all multiple worktrees' ' |
| 629 | test_when_finished "rm -rf repo" && |
| 630 | test_when_finished "rm -rf wt" && |
| 631 | git init repo && |
| 632 | ( |
| 633 | cd repo && |
| 634 | test_commit A && |
| 635 | git worktree add ../wt && |
| 636 | test_commit_bulk -C ../wt --ref=refs/heads/branch 1 && |
| 637 | git reflog exists refs/heads/main && |
| 638 | git reflog exists refs/heads/branch && |
| 639 | git reflog drop --all && |
| 640 | test_must_fail git reflog exists refs/heads/main && |
| 641 | test_must_fail git reflog exists refs/heads/branch |
| 642 | ) |
| 643 | ' |
| 644 | |
| 645 | test_expect_success 'reflog drop --all --single-worktree' ' |
| 646 | test_when_finished "rm -rf repo" && |
| 647 | test_when_finished "rm -rf wt" && |
| 648 | git init repo && |
| 649 | ( |
| 650 | cd repo && |
| 651 | test_commit A && |
| 652 | git worktree add ../wt && |
| 653 | test_commit -C ../wt foobar && |
| 654 | git reflog exists refs/heads/main && |
| 655 | git reflog exists refs/heads/wt && |
| 656 | test-tool ref-store worktree:wt reflog-exists HEAD && |
| 657 | git reflog drop --all --single-worktree && |
| 658 | test_must_fail git reflog exists refs/heads/main && |
| 659 | test_must_fail git reflog exists refs/heads/wt && |
| 660 | test_must_fail test-tool ref-store worktree:main reflog-exists HEAD && |
| 661 | test-tool ref-store worktree:wt reflog-exists HEAD |
| 662 | ) |
| 663 | ' |
| 664 | |
| 665 | test_expect_success 'reflog drop --all with reference' ' |
| 666 | test_when_finished "rm -rf repo" && |
| 667 | git init repo && |
| 668 | ( |
| 669 | cd repo && |
| 670 | test_commit A && |
| 671 | test_must_fail git reflog drop --all refs/heads/main 2>stderr && |
| 672 | test_grep "usage: references specified along with --all" stderr |
| 673 | ) |
| 674 | ' |
| 675 | |
| 676 | test_expect_success 'expire with pattern config' ' |
| 677 | # Split refs/heads/ into two roots so we can apply config to each. Make |
| 678 | # two branches per root to verify that config is applied correctly |
| 679 | # multiple times. |
| 680 | git branch root1/branch1 && |
| 681 | git branch root1/branch2 && |
| 682 | git branch root2/branch1 && |
| 683 | git branch root2/branch2 && |
| 684 | |
| 685 | test_config "gc.reflogexpire" "never" && |
| 686 | test_config "gc.refs/heads/root2/*.reflogExpire" "now" && |
| 687 | git reflog expire \ |
| 688 | root1/branch1 root1/branch2 \ |
| 689 | root2/branch1 root2/branch2 && |
| 690 | |
| 691 | cat >expect <<-\EOF && |
| 692 | root1/branch1@{0} |
| 693 | root1/branch2@{0} |
| 694 | EOF |
| 695 | git log -g --branches="root*" --format=%gD >actual.raw && |
| 696 | # The sole reflog entry of each branch points to the same commit, so |
| 697 | # the order in which they are shown is nondeterministic. We just care |
| 698 | # about the what was expired (and what was not), so sort to get a known |
| 699 | # order. |
| 700 | sort <actual.raw >actual.sorted && |
| 701 | test_cmp expect actual.sorted |
| 702 | ' |
| 703 | |
| 704 | test_done |