diff options
author | Junio C Hamano <gitster@pobox.com> | 2024-01-24 00:40:42 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-01-24 00:40:42 +0300 |
commit | 199dd05723b4e725bd71f33e5cf30f79fe2200d6 (patch) | |
tree | f6b249d74fa9d1f40af90e2d77cdb58ccd519e1b | |
parent | 5567960fd08748571d9f8d2f66462d127e33f130 (diff) | |
parent | fa1033accc71edf978eb80043a6a35d7529e7209 (diff) |
Merge branch 'jc/reffiles-tests' into jch
Tests on ref API are moved around to prepare for reftable.
* jc/reffiles-tests:
t5312: move reffiles specific tests to t0601
t4202: move reffiles specific tests to t0600
t3903: make drop stash test ref backend agnostic
t1503: move reffiles specific tests to t0600
t1415: move reffiles specific tests to t0601
t1410: move reffiles specific tests to t0600
t1406: move reffiles specific tests to t0600
t1405: move reffiles specific tests to t0601
t1404: move reffiles specific tests to t0600
t1414: convert test to use Git commands instead of writing refs manually
remove REFFILES prerequisite for some tests in t1405 and t2017
t3210: move to t0601
-rwxr-xr-x | t/t0600-reffiles-backend.sh | 384 | ||||
-rwxr-xr-x | t/t0601-reffiles-pack-refs.sh (renamed from t/t3210-pack-refs.sh) | 64 | ||||
-rwxr-xr-x | t/t1404-update-ref-errors.sh | 237 | ||||
-rwxr-xr-x | t/t1405-main-ref-store.sh | 10 | ||||
-rwxr-xr-x | t/t1407-worktree-ref-store.sh | 37 | ||||
-rwxr-xr-x | t/t1410-reflog.sh | 42 | ||||
-rwxr-xr-x | t/t1414-reflog-walk.sh | 11 | ||||
-rwxr-xr-x | t/t1415-worktree-refs.sh | 11 | ||||
-rwxr-xr-x | t/t1503-rev-parse-verify.sh | 5 | ||||
-rwxr-xr-x | t/t2017-checkout-orphan.sh | 2 | ||||
-rwxr-xr-x | t/t3903-stash.sh | 12 | ||||
-rwxr-xr-x | t/t4202-log.sh | 17 | ||||
-rwxr-xr-x | t/t5312-prune-corruption.sh | 26 |
13 files changed, 461 insertions, 397 deletions
diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh new file mode 100755 index 0000000000..e6a5f1868f --- /dev/null +++ b/t/t0600-reffiles-backend.sh @@ -0,0 +1,384 @@ +#!/bin/sh + +test_description='Test reffiles backend' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +if ! test_have_prereq REFFILES +then + skip_all='skipping reffiles specific tests' + test_done +fi + +test_expect_success 'setup' ' + git commit --allow-empty -m Initial && + C=$(git rev-parse HEAD) && + git commit --allow-empty -m Second && + D=$(git rev-parse HEAD) && + git commit --allow-empty -m Third && + E=$(git rev-parse HEAD) +' + +test_expect_success 'empty directory should not fool rev-parse' ' + prefix=refs/e-rev-parse && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + echo "$C" >expected && + git rev-parse $prefix/foo >actual && + test_cmp expected actual +' + +test_expect_success 'empty directory should not fool for-each-ref' ' + prefix=refs/e-for-each-ref && + git update-ref $prefix/foo $C && + git for-each-ref $prefix >expected && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + git for-each-ref $prefix >actual && + test_cmp expected actual +' + +test_expect_success 'empty directory should not fool create' ' + prefix=refs/e-create && + mkdir -p .git/$prefix/foo/bar/baz && + printf "create %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool verify' ' + prefix=refs/e-verify && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "verify %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 1-arg update' ' + prefix=refs/e-update-1 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "update %s $D\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 2-arg update' ' + prefix=refs/e-update-2 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "update %s $D $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 0-arg delete' ' + prefix=refs/e-delete-0 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "delete %s\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 1-arg delete' ' + prefix=refs/e-delete-1 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "delete %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'non-empty directory blocks create' ' + prefix=refs/ne-create && + mkdir -p .git/$prefix/foo/bar && + : >.git/$prefix/foo/bar/baz.lock && + test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/foo $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/foo $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'broken reference blocks create' ' + prefix=refs/broken-create && + mkdir -p .git/$prefix && + echo "gobbledigook" >.git/$prefix/foo && + test_when_finished "rm -f .git/$prefix/foo" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/foo $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/foo $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'non-empty directory blocks indirect create' ' + prefix=refs/ne-indirect-create && + git symbolic-ref $prefix/symref $prefix/foo && + mkdir -p .git/$prefix/foo/bar && + : >.git/$prefix/foo/bar/baz.lock && + test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/symref $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/symref $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'broken reference blocks indirect create' ' + prefix=refs/broken-indirect-create && + git symbolic-ref $prefix/symref $prefix/foo && + echo "gobbledigook" >.git/$prefix/foo && + test_when_finished "rm -f .git/$prefix/foo" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/symref $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/symref $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'no bogus intermediate values during delete' ' + prefix=refs/slow-transaction && + # Set up a reference with differing loose and packed versions: + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + # Now try to update the reference, but hold the `packed-refs` lock + # for a while to see what happens while the process is blocked: + : >.git/packed-refs.lock && + test_when_finished "rm -f .git/packed-refs.lock" && + { + # Note: the following command is intentionally run in the + # background. We increase the timeout so that `update-ref` + # attempts to acquire the `packed-refs` lock for much longer + # than it takes for us to do the check then delete it: + git -c core.packedrefstimeout=30000 update-ref -d $prefix/foo & + } && + pid2=$! && + # Give update-ref plenty of time to get to the point where it tries + # to lock packed-refs: + sleep 1 && + # Make sure that update-ref did not complete despite the lock: + kill -0 $pid2 && + # Verify that the reference still has its old value: + sha1=$(git rev-parse --verify --quiet $prefix/foo || echo undefined) && + case "$sha1" in + $D) + # This is what we hope for; it means that nothing + # user-visible has changed yet. + : ;; + undefined) + # This is not correct; it means the deletion has happened + # already even though update-ref should not have been + # able to acquire the lock yet. + echo "$prefix/foo deleted prematurely" && + break + ;; + $C) + # This value should never be seen. Probably the loose + # reference has been deleted but the packed reference + # is still there: + echo "$prefix/foo incorrectly observed to be C" && + break + ;; + *) + # WTF? + echo "unexpected value observed for $prefix/foo: $sha1" && + break + ;; + esac >out && + rm -f .git/packed-refs.lock && + wait $pid2 && + test_must_be_empty out && + test_must_fail git rev-parse --verify --quiet $prefix/foo +' + +test_expect_success 'delete fails cleanly if packed-refs file is locked' ' + prefix=refs/locked-packed-refs && + # Set up a reference with differing loose and packed versions: + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + git for-each-ref $prefix >unchanged && + # Now try to delete it while the `packed-refs` lock is held: + : >.git/packed-refs.lock && + test_when_finished "rm -f .git/packed-refs.lock" && + test_must_fail git update-ref -d $prefix/foo >out 2>err && + git for-each-ref $prefix >actual && + test_grep "Unable to create $SQ.*packed-refs.lock$SQ: " err && + test_cmp unchanged actual +' + +test_expect_success 'delete fails cleanly if packed-refs.new write fails' ' + # Setup and expectations are similar to the test above. + prefix=refs/failed-packed-refs && + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + git for-each-ref $prefix >unchanged && + # This should not happen in practice, but it is an easy way to get a + # reliable error (we open with create_tempfile(), which uses O_EXCL). + : >.git/packed-refs.new && + test_when_finished "rm -f .git/packed-refs.new" && + test_must_fail git update-ref -d $prefix/foo && + git for-each-ref $prefix >actual && + test_cmp unchanged actual +' + +RWT="test-tool ref-store worktree:wt" +RMAIN="test-tool ref-store worktree:main" + +test_expect_success 'setup worktree' ' + test_commit first && + git worktree add -b wt-main wt && + ( + cd wt && + test_commit second + ) +' + +# Some refs (refs/bisect/*, pseudorefs) are kept per worktree, so they should +# only appear in the for-each-reflog output if it is called from the correct +# worktree, which is exercised in this test. This test is poorly written for +# mulitple reasons: 1) it creates invalidly formatted log entres. 2) it uses +# direct FS access for creating the reflogs. 3) PSEUDO-WT and refs/bisect/random +# do not create reflogs by default, so it is not testing a realistic scenario. +test_expect_success 'for_each_reflog()' ' + echo $ZERO_OID > .git/logs/PSEUDO-MAIN && + mkdir -p .git/logs/refs/bisect && + echo $ZERO_OID > .git/logs/refs/bisect/random && + + echo $ZERO_OID > .git/worktrees/wt/logs/PSEUDO-WT && + mkdir -p .git/worktrees/wt/logs/refs/bisect && + echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random && + + $RWT for-each-reflog | cut -d" " -f 2- | sort >actual && + cat >expected <<-\EOF && + HEAD 0x1 + PSEUDO-WT 0x0 + refs/bisect/wt-random 0x0 + refs/heads/main 0x0 + refs/heads/wt-main 0x0 + EOF + test_cmp expected actual && + + $RMAIN for-each-reflog | cut -d" " -f 2- | sort >actual && + cat >expected <<-\EOF && + HEAD 0x1 + PSEUDO-MAIN 0x0 + refs/bisect/random 0x0 + refs/heads/main 0x0 + refs/heads/wt-main 0x0 + EOF + test_cmp expected actual +' + +# Triggering the bug detected by this test requires a newline to fall +# exactly BUFSIZ-1 bytes from the end of the file. We don't know +# what that value is, since it's platform dependent. However, if +# we choose some value N, we also catch any D which divides N evenly +# (since we will read backwards in chunks of D). So we choose 8K, +# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). +# +# Each line is 114 characters, so we need 75 to still have a few before the +# last 8K. The 89-character padding on the final entry lines up our +# newline exactly. +test_expect_success SHA1 'parsing reverse reflogs at BUFSIZ boundaries' ' + git checkout -b reflogskip && + zf=$(test_oid zero_2) && + ident="abc <xyz> 0000000001 +0000" && + for i in $(test_seq 1 75); do + printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" && + if test $i = 75; then + for j in $(test_seq 1 89); do + printf X || return 1 + done + else + printf X + fi && + printf "\n" || return 1 + done >.git/logs/refs/heads/reflogskip && + git rev-parse reflogskip@{73} >actual && + echo ${zf}03 >expect && + test_cmp expect actual +' + +# This test takes a lock on an individual ref; this is not supported in +# reftable. +test_expect_success 'reflog expire operates on symref not referrent' ' + git branch --create-reflog the_symref && + git branch --create-reflog referrent && + git update-ref referrent HEAD && + git symbolic-ref refs/heads/the_symref refs/heads/referrent && + test_when_finished "rm -f .git/refs/heads/referrent.lock" && + touch .git/refs/heads/referrent.lock && + git reflog expire --expire=all the_symref +' + +test_expect_success 'empty reflog' ' + test_when_finished "rm -rf empty" && + git init empty && + test_commit -C empty A && + >empty/.git/logs/refs/heads/foo && + git -C empty reflog expire --all 2>err && + test_must_be_empty err +' + +test_expect_success SYMLINKS 'ref resolution not confused by broken symlinks' ' + ln -s does-not-exist .git/refs/heads/broken && + test_must_fail git rev-parse --verify broken +' + +test_expect_success 'log diagnoses bogus HEAD hash' ' + git init empty && + test_when_finished "rm -rf empty" && + echo 1234abcd >empty/.git/refs/heads/main && + test_must_fail git -C empty log 2>stderr && + test_grep broken stderr +' + +test_expect_success 'log diagnoses bogus HEAD symref' ' + git init empty && + test-tool -C empty ref-store main create-symref HEAD refs/heads/invalid.lock && + test_must_fail git -C empty log 2>stderr && + test_grep broken stderr && + test_must_fail git -C empty log --default totally-bogus 2>stderr && + test_grep broken stderr +' + +test_done diff --git a/t/t3210-pack-refs.sh b/t/t0601-reffiles-pack-refs.sh index 7f4e98db7d..c309d2bae8 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t0601-reffiles-pack-refs.sh @@ -15,6 +15,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if ! test_have_prereq REFFILES +then + skip_all='skipping reffiles specific tests' + test_done +fi + test_expect_success 'enable reflogs' ' git config core.logallrefupdates true ' @@ -26,6 +32,14 @@ test_expect_success 'prepare a trivial repository' ' HEAD=$(git rev-parse --verify HEAD) ' +test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' + N=`find .git/refs -type f | wc -l` && + test "$N" != 0 && + test-tool ref-store main pack-refs PACK_REFS_PRUNE,PACK_REFS_ALL && + N=`find .git/refs -type f` && + test -z "$N" +' + SHA1= test_expect_success 'see if git show-ref works as expected' ' @@ -294,4 +308,54 @@ test_expect_success SYMLINKS 'pack symlinked packed-refs' ' test "$(test_readlink .git/packed-refs)" = "my-deviant-packed-refs" ' +# The 'packed-refs' file is stored directly in .git/. This means it is global +# to the repository, and can only contain refs that are shared across all +# worktrees. +test_expect_success 'refs/worktree must not be packed' ' + test_commit initial && + test_commit wt1 && + test_commit wt2 && + git worktree add wt1 wt1 && + git worktree add wt2 wt2 && + git checkout initial && + git update-ref refs/worktree/foo HEAD && + git -C wt1 update-ref refs/worktree/foo HEAD && + git -C wt2 update-ref refs/worktree/foo HEAD && + git pack-refs --all && + test_path_is_missing .git/refs/tags/wt1 && + test_path_is_file .git/refs/worktree/foo && + test_path_is_file .git/worktrees/wt1/refs/worktree/foo && + test_path_is_file .git/worktrees/wt2/refs/worktree/foo +' + +# we do not want to count on running pack-refs to +# actually pack it, as it is perfectly reasonable to +# skip processing a broken ref +test_expect_success 'create packed-refs file with broken ref' ' + test_tick && git commit --allow-empty -m one && + recoverable=$(git rev-parse HEAD) && + test_tick && git commit --allow-empty -m two && + missing=$(git rev-parse HEAD) && + rm -f .git/refs/heads/main && + cat >.git/packed-refs <<-EOF && + $missing refs/heads/main + $recoverable refs/heads/other + EOF + echo $missing >expect && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'pack-refs does not silently delete broken packed ref' ' + git pack-refs --all --prune && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'pack-refs does not drop broken refs during deletion' ' + git update-ref -d refs/heads/other && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh index 0369beea33..00b7013705 100755 --- a/t/t1404-update-ref-errors.sh +++ b/t/t1404-update-ref-errors.sh @@ -191,78 +191,6 @@ test_expect_success 'one new ref is a simple prefix of another' ' ' -test_expect_success REFFILES 'empty directory should not fool rev-parse' ' - prefix=refs/e-rev-parse && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - echo "$C" >expected && - git rev-parse $prefix/foo >actual && - test_cmp expected actual -' - -test_expect_success REFFILES 'empty directory should not fool for-each-ref' ' - prefix=refs/e-for-each-ref && - git update-ref $prefix/foo $C && - git for-each-ref $prefix >expected && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - git for-each-ref $prefix >actual && - test_cmp expected actual -' - -test_expect_success REFFILES 'empty directory should not fool create' ' - prefix=refs/e-create && - mkdir -p .git/$prefix/foo/bar/baz && - printf "create %s $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool verify' ' - prefix=refs/e-verify && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "verify %s $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 1-arg update' ' - prefix=refs/e-update-1 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "update %s $D\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 2-arg update' ' - prefix=refs/e-update-2 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "update %s $D $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 0-arg delete' ' - prefix=refs/e-delete-0 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "delete %s\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 1-arg delete' ' - prefix=refs/e-delete-1 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "delete %s $C\n" $prefix/foo | - git update-ref --stdin -' - test_expect_success REFFILES 'D/F conflict prevents add long + delete short' ' df_test refs/df-al-ds --add-del foo/bar foo ' @@ -468,169 +396,4 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' ' test_cmp expected output.err ' -test_expect_success REFFILES 'non-empty directory blocks create' ' - prefix=refs/ne-create && - mkdir -p .git/$prefix/foo/bar && - : >.git/$prefix/foo/bar/baz.lock && - test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/foo $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/foo $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'broken reference blocks create' ' - prefix=refs/broken-create && - mkdir -p .git/$prefix && - echo "gobbledigook" >.git/$prefix/foo && - test_when_finished "rm -f .git/$prefix/foo" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/foo $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/foo $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'non-empty directory blocks indirect create' ' - prefix=refs/ne-indirect-create && - git symbolic-ref $prefix/symref $prefix/foo && - mkdir -p .git/$prefix/foo/bar && - : >.git/$prefix/foo/bar/baz.lock && - test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/symref $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/symref $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'broken reference blocks indirect create' ' - prefix=refs/broken-indirect-create && - git symbolic-ref $prefix/symref $prefix/foo && - echo "gobbledigook" >.git/$prefix/foo && - test_when_finished "rm -f .git/$prefix/foo" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/symref $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/symref $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'no bogus intermediate values during delete' ' - prefix=refs/slow-transaction && - # Set up a reference with differing loose and packed versions: - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - # Now try to update the reference, but hold the `packed-refs` lock - # for a while to see what happens while the process is blocked: - : >.git/packed-refs.lock && - test_when_finished "rm -f .git/packed-refs.lock" && - { - # Note: the following command is intentionally run in the - # background. We increase the timeout so that `update-ref` - # attempts to acquire the `packed-refs` lock for much longer - # than it takes for us to do the check then delete it: - git -c core.packedrefstimeout=30000 update-ref -d $prefix/foo & - } && - pid2=$! && - # Give update-ref plenty of time to get to the point where it tries - # to lock packed-refs: - sleep 1 && - # Make sure that update-ref did not complete despite the lock: - kill -0 $pid2 && - # Verify that the reference still has its old value: - sha1=$(git rev-parse --verify --quiet $prefix/foo || echo undefined) && - case "$sha1" in - $D) - # This is what we hope for; it means that nothing - # user-visible has changed yet. - : ;; - undefined) - # This is not correct; it means the deletion has happened - # already even though update-ref should not have been - # able to acquire the lock yet. - echo "$prefix/foo deleted prematurely" && - break - ;; - $C) - # This value should never be seen. Probably the loose - # reference has been deleted but the packed reference - # is still there: - echo "$prefix/foo incorrectly observed to be C" && - break - ;; - *) - # WTF? - echo "unexpected value observed for $prefix/foo: $sha1" && - break - ;; - esac >out && - rm -f .git/packed-refs.lock && - wait $pid2 && - test_must_be_empty out && - test_must_fail git rev-parse --verify --quiet $prefix/foo -' - -test_expect_success REFFILES 'delete fails cleanly if packed-refs file is locked' ' - prefix=refs/locked-packed-refs && - # Set up a reference with differing loose and packed versions: - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - git for-each-ref $prefix >unchanged && - # Now try to delete it while the `packed-refs` lock is held: - : >.git/packed-refs.lock && - test_when_finished "rm -f .git/packed-refs.lock" && - test_must_fail git update-ref -d $prefix/foo >out 2>err && - git for-each-ref $prefix >actual && - test_grep "Unable to create $SQ.*packed-refs.lock$SQ: " err && - test_cmp unchanged actual -' - -test_expect_success REFFILES 'delete fails cleanly if packed-refs.new write fails' ' - # Setup and expectations are similar to the test above. - prefix=refs/failed-packed-refs && - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - git for-each-ref $prefix >unchanged && - # This should not happen in practice, but it is an easy way to get a - # reliable error (we open with create_tempfile(), which uses O_EXCL). - : >.git/packed-refs.new && - test_when_finished "rm -f .git/packed-refs.new" && - test_must_fail git update-ref -d $prefix/foo && - git for-each-ref $prefix >actual && - test_cmp unchanged actual -' - test_done diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index e4627cf1b6..976bd71efb 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -15,14 +15,6 @@ test_expect_success 'setup' ' test_commit one ' -test_expect_success REFFILES 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' - N=`find .git/refs -type f | wc -l` && - test "$N" != 0 && - $RUN pack-refs PACK_REFS_PRUNE,PACK_REFS_ALL && - N=`find .git/refs -type f` && - test -z "$N" -' - test_expect_success 'create_symref(FOO, refs/heads/main)' ' $RUN create-symref FOO refs/heads/main nothing && echo refs/heads/main >expected && @@ -112,7 +104,7 @@ test_expect_success 'delete_reflog(HEAD)' ' test_must_fail git reflog exists HEAD ' -test_expect_success REFFILES 'create-reflog(HEAD)' ' +test_expect_success 'create-reflog(HEAD)' ' $RUN create-reflog HEAD && git reflog exists HEAD ' diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh index 05b1881c59..48b1c92a41 100755 --- a/t/t1407-worktree-ref-store.sh +++ b/t/t1407-worktree-ref-store.sh @@ -53,41 +53,4 @@ test_expect_success 'create_symref(FOO, refs/heads/main)' ' test_cmp expected actual ' -# Some refs (refs/bisect/*, pseudorefs) are kept per worktree, so they should -# only appear in the for-each-reflog output if it is called from the correct -# worktree, which is exercised in this test. This test is poorly written (and -# therefore marked REFFILES) for mulitple reasons: 1) it creates invalidly -# formatted log entres. 2) it uses direct FS access for creating the reflogs. 3) -# PSEUDO-WT and refs/bisect/random do not create reflogs by default, so it is -# not testing a realistic scenario. -test_expect_success REFFILES 'for_each_reflog()' ' - echo $ZERO_OID > .git/logs/PSEUDO-MAIN && - mkdir -p .git/logs/refs/bisect && - echo $ZERO_OID > .git/logs/refs/bisect/random && - - echo $ZERO_OID > .git/worktrees/wt/logs/PSEUDO-WT && - mkdir -p .git/worktrees/wt/logs/refs/bisect && - echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random && - - $RWT for-each-reflog | cut -d" " -f 2- | sort >actual && - cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-WT 0x0 - refs/bisect/wt-random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 - EOF - test_cmp expected actual && - - $RMAIN for-each-reflog | cut -d" " -f 2- | sort >actual && - cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-MAIN 0x0 - refs/bisect/random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 - EOF - test_cmp expected actual -' - test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index a0ff8d51f0..d2f5f42e67 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -354,36 +354,6 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' ' test_must_be_empty actual ' -# Triggering the bug detected by this test requires a newline to fall -# exactly BUFSIZ-1 bytes from the end of the file. We don't know -# what that value is, since it's platform dependent. However, if -# we choose some value N, we also catch any D which divides N evenly -# (since we will read backwards in chunks of D). So we choose 8K, -# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). -# -# Each line is 114 characters, so we need 75 to still have a few before the -# last 8K. The 89-character padding on the final entry lines up our -# newline exactly. -test_expect_success REFFILES,SHA1 'parsing reverse reflogs at BUFSIZ boundaries' ' - git checkout -b reflogskip && - zf=$(test_oid zero_2) && - ident="abc <xyz> 0000000001 +0000" && - for i in $(test_seq 1 75); do - printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" && - if test $i = 75; then - for j in $(test_seq 1 89); do - printf X || return 1 - done - else - printf X - fi && - printf "\n" || return 1 - done >.git/logs/refs/heads/reflogskip && - git rev-parse reflogskip@{73} >actual && - echo ${zf}03 >expect && - test_cmp expect actual -' - test_expect_success 'no segfaults for reflog containing non-commit sha1s' ' git update-ref --create-reflog -m "Creating ref" \ refs/tests/tree-in-reflog HEAD && @@ -397,18 +367,6 @@ test_expect_failure 'reflog with non-commit entries displays all entries' ' test_line_count = 3 actual ' -# This test takes a lock on an individual ref; this is not supported in -# reftable. -test_expect_success REFFILES 'reflog expire operates on symref not referrent' ' - git branch --create-reflog the_symref && - git branch --create-reflog referrent && - git update-ref referrent HEAD && - git symbolic-ref refs/heads/the_symref refs/heads/referrent && - test_when_finished "rm -f .git/refs/heads/referrent.lock" && - touch .git/refs/heads/referrent.lock && - git reflog expire --expire=all the_symref -' - test_expect_success 'continue walking past root commits' ' git init orphanage && ( diff --git a/t/t1414-reflog-walk.sh b/t/t1414-reflog-walk.sh index ea64cecf47..be6c3f472c 100755 --- a/t/t1414-reflog-walk.sh +++ b/t/t1414-reflog-walk.sh @@ -121,13 +121,12 @@ test_expect_success 'min/max age uses entry date to limit' ' # Create a situation where the reflog and ref database disagree about the latest # state of HEAD. -test_expect_success REFFILES 'walk prefers reflog to ref tip' ' +test_expect_success 'walk prefers reflog to ref tip' ' + test_commit A && + test_commit B && + git reflog delete HEAD@{0} && head=$(git rev-parse HEAD) && - one=$(git rev-parse one) && - ident="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" && - echo "$head $one $ident broken reflog entry" >>.git/logs/HEAD && - - echo $one >expect && + git rev-parse A >expect && git log -g --format=%H -1 >actual && test_cmp expect actual ' diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh index 3b531842dd..eb4eec8bec 100755 --- a/t/t1415-worktree-refs.sh +++ b/t/t1415-worktree-refs.sh @@ -17,17 +17,6 @@ test_expect_success 'setup' ' git -C wt2 update-ref refs/worktree/foo HEAD ' -# The 'packed-refs' file is stored directly in .git/. This means it is global -# to the repository, and can only contain refs that are shared across all -# worktrees. -test_expect_success REFFILES 'refs/worktree must not be packed' ' - git pack-refs --all && - test_path_is_missing .git/refs/tags/wt1 && - test_path_is_file .git/refs/worktree/foo && - test_path_is_file .git/worktrees/wt1/refs/worktree/foo && - test_path_is_file .git/worktrees/wt2/refs/worktree/foo -' - test_expect_success 'refs/worktree are per-worktree' ' test_cmp_rev worktree/foo initial && ( cd wt1 && test_cmp_rev worktree/foo wt1 ) && diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index bc136833c1..79df65ec7f 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -144,11 +144,6 @@ test_expect_success 'main@{n} for various n' ' test_must_fail git rev-parse --verify main@{$Np1} ' -test_expect_success SYMLINKS,REFFILES 'ref resolution not confused by broken symlinks' ' - ln -s does-not-exist .git/refs/heads/broken && - test_must_fail git rev-parse --verify broken -' - test_expect_success 'options can appear after --verify' ' git rev-parse --verify HEAD >expect && git rev-parse --verify -q HEAD >actual && diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index 947d1587ac..a5c7358eea 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -86,7 +86,7 @@ test_expect_success '--orphan makes reflog by default' ' git rev-parse --verify delta@{0} ' -test_expect_success REFFILES '--orphan does not make reflog when core.logAllRefUpdates = false' ' +test_expect_success '--orphan does not make reflog when core.logAllRefUpdates = false' ' git checkout main && git config core.logAllRefUpdates false && git checkout --orphan epsilon && diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 34faeac3f1..3319240515 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -200,7 +200,7 @@ test_expect_success 'drop stash reflog updates refs/stash' ' test_cmp expect actual ' -test_expect_success REFFILES 'drop stash reflog updates refs/stash with rewrite' ' +test_expect_success 'drop stash reflog updates refs/stash with rewrite' ' git init repo && ( cd repo && @@ -213,16 +213,16 @@ test_expect_success REFFILES 'drop stash reflog updates refs/stash with rewrite' new_oid="$(git -C repo rev-parse stash@{0})" && cat >expect <<-EOF && - $(test_oid zero) $old_oid - $old_oid $new_oid + $new_oid + $old_oid EOF - cut -d" " -f1-2 repo/.git/logs/refs/stash >actual && + git -C repo reflog show refs/stash --format=%H >actual && test_cmp expect actual && git -C repo stash drop stash@{1} && - cut -d" " -f1-2 repo/.git/logs/refs/stash >actual && + git -C repo reflog show refs/stash --format=%H >actual && cat >expect <<-EOF && - $(test_oid zero) $new_oid + $new_oid EOF test_cmp expect actual ' diff --git a/t/t4202-log.sh b/t/t4202-log.sh index ddd205f98a..60fe60d761 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -2255,23 +2255,6 @@ test_expect_success 'log on empty repo fails' ' test_grep does.not.have.any.commits stderr ' -test_expect_success REFFILES 'log diagnoses bogus HEAD hash' ' - git init empty && - test_when_finished "rm -rf empty" && - echo 1234abcd >empty/.git/refs/heads/main && - test_must_fail git -C empty log 2>stderr && - test_grep broken stderr -' - -test_expect_success REFFILES 'log diagnoses bogus HEAD symref' ' - git init empty && - test-tool -C empty ref-store main create-symref HEAD refs/heads/invalid.lock && - test_must_fail git -C empty log 2>stderr && - test_grep broken stderr && - test_must_fail git -C empty log --default totally-bogus 2>stderr && - test_grep broken stderr -' - test_expect_success 'log does not default to HEAD when rev input is given' ' git log --branches=does-not-exist >actual && test_must_be_empty actual diff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh index 230cb38712..d8d2e30468 100755 --- a/t/t5312-prune-corruption.sh +++ b/t/t5312-prune-corruption.sh @@ -111,30 +111,4 @@ test_expect_success 'pack-refs does not silently delete broken loose ref' ' test_cmp expect actual ' -# we do not want to count on running pack-refs to -# actually pack it, as it is perfectly reasonable to -# skip processing a broken ref -test_expect_success REFFILES 'create packed-refs file with broken ref' ' - rm -f .git/refs/heads/main && - cat >.git/packed-refs <<-EOF && - $missing refs/heads/main - $recoverable refs/heads/other - EOF - echo $missing >expect && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - -test_expect_success REFFILES 'pack-refs does not silently delete broken packed ref' ' - git pack-refs --all --prune && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - -test_expect_success REFFILES 'pack-refs does not drop broken refs during deletion' ' - git update-ref -d refs/heads/other && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - test_done |