In the early days of Git, Perl was used quite prominently throughout the
project. This has changed significantly as almost all of the executables
we ship nowadays have eventually been rewritten in C. Only a handful of
subsystems remain that require Perl:
- gitweb, a read-only web interface.
- A couple of scripts that allow importing repositories from GNU Arch,
CVS and Subversion.
- git-send-email(1), which can be used to send mails.
- git-request-pull(1), which is used to request somebody to pull from
a URL by sending an email.
- git-filter-branch(1), which uses Perl with the `--state-branch`
option. This command is typically recommended against nowadays in
favor of git-filter-repo(1).
- Our Perl bindings for Git.
- The netrc Git credential helper.
None of these subsystems can really be considered to be part of the
"core" of Git, and an installation without them is fully functional.
It is more likely than not that an end user wouldn't even notice that
any features are missing if those tools weren't installed. But while
Perl nowadays very much is an optional dependency of Git, there is a
significant limitation when Perl isn't available: developers cannot run
our test suite.
Preceding commits have started to lift this restriction by removing the
strict dependency on Perl in many central parts of the test library. But
there are still many tests that rely on small Perl helpers to do various
different things.
Introduce a new PERL_TEST_HELPERS prerequisite that guards all tests
that require Perl. This prerequisite is explicitly different than the
preexisting PERL prerequisite:
- PERL records whether or not features depending on the Perl
interpreter are built.
- PERL_TEST_HELPERS records whether or not a Perl interpreter is
available for our tests.
By having these two separate prerequisites we can thus distinguish
between tests that inherently depend on Perl because the underlying
feature does, and those tests that depend on Perl because the test
itself is using Perl.
Adapt all tests to set the PERL_TEST_HELPERS prerequisite as needed.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
380 lines
12 KiB
Bash
Executable File
380 lines
12 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='fetch/receive strict mode'
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'setup and inject "corrupt or missing" object' '
|
|
echo hello >greetings &&
|
|
git add greetings &&
|
|
git commit -m greetings &&
|
|
|
|
S=$(git rev-parse :greetings | sed -e "s|^..|&/|") &&
|
|
X=$(echo bye | git hash-object -w --stdin | sed -e "s|^..|&/|") &&
|
|
echo $S >S &&
|
|
echo $X >X &&
|
|
cp .git/objects/$S .git/objects/$S.back &&
|
|
mv -f .git/objects/$X .git/objects/$S &&
|
|
|
|
test_must_fail git fsck
|
|
'
|
|
|
|
test_expect_success 'fetch without strict' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config fetch.fsckobjects false &&
|
|
git config transfer.fsckobjects false &&
|
|
test_must_fail git fetch ../.git main
|
|
)
|
|
'
|
|
|
|
test_expect_success 'fetch with !fetch.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config fetch.fsckobjects false &&
|
|
git config transfer.fsckobjects true &&
|
|
test_must_fail git fetch ../.git main
|
|
)
|
|
'
|
|
|
|
test_expect_success 'fetch with fetch.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config fetch.fsckobjects true &&
|
|
git config transfer.fsckobjects false &&
|
|
test_must_fail git fetch ../.git main
|
|
)
|
|
'
|
|
|
|
test_expect_success 'fetch with transfer.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config transfer.fsckobjects true &&
|
|
test_must_fail git fetch ../.git main
|
|
)
|
|
'
|
|
|
|
test_expect_success 'push without strict' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config fetch.fsckobjects false &&
|
|
git config transfer.fsckobjects false
|
|
) &&
|
|
cat >exp <<-\EOF &&
|
|
To dst
|
|
! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects)
|
|
Done
|
|
EOF
|
|
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
|
|
test_cmp exp act
|
|
'
|
|
|
|
test_expect_success 'push with !receive.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config receive.fsckobjects false &&
|
|
git config transfer.fsckobjects true
|
|
) &&
|
|
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
|
|
test_cmp exp act
|
|
'
|
|
|
|
test_expect_success 'push with receive.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config receive.fsckobjects true &&
|
|
git config transfer.fsckobjects false
|
|
) &&
|
|
cat >exp <<-\EOF &&
|
|
To dst
|
|
! refs/heads/main:refs/heads/test [remote rejected] (unpacker error)
|
|
EOF
|
|
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
|
|
test_cmp exp act
|
|
'
|
|
|
|
test_expect_success 'push with transfer.fsckobjects' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
(
|
|
cd dst &&
|
|
git config transfer.fsckobjects true
|
|
) &&
|
|
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
|
|
test_cmp exp act
|
|
'
|
|
|
|
test_expect_success 'repair the "corrupt or missing" object' '
|
|
mv -f .git/objects/$(cat S) .git/objects/$(cat X) &&
|
|
mv .git/objects/$(cat S).back .git/objects/$(cat S) &&
|
|
rm -rf .git/objects/$(cat X) &&
|
|
git fsck
|
|
'
|
|
|
|
test_expect_success 'setup bogus commit' '
|
|
cat >bogus-commit <<-EOF &&
|
|
tree $EMPTY_TREE
|
|
author Bugs Bunny 1234567890 +0000
|
|
committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000
|
|
|
|
This commit object intentionally broken
|
|
EOF
|
|
commit="$(git hash-object --literally -t commit -w --stdin <bogus-commit)"
|
|
'
|
|
|
|
test_expect_success 'fsck with no skipList input' '
|
|
test_must_fail git fsck 2>err &&
|
|
test_grep "missingEmail" err
|
|
'
|
|
|
|
test_expect_success 'setup sorted and unsorted skipLists' '
|
|
cat >SKIP.unsorted <<-EOF &&
|
|
$(test_oid 004)
|
|
$(test_oid 002)
|
|
$commit
|
|
$(test_oid 001)
|
|
$(test_oid 003)
|
|
EOF
|
|
sort SKIP.unsorted >SKIP.sorted
|
|
'
|
|
|
|
test_expect_success 'fsck with sorted skipList' '
|
|
git -c fsck.skipList=SKIP.sorted fsck
|
|
'
|
|
|
|
test_expect_success 'fsck with unsorted skipList' '
|
|
git -c fsck.skipList=SKIP.unsorted fsck
|
|
'
|
|
|
|
test_expect_success 'fsck with invalid or bogus skipList input' '
|
|
git -c fsck.skipList=/dev/null -c fsck.missingEmail=ignore fsck &&
|
|
test_must_fail git -c fsck.skipList -c fsck.missingEmail=ignore fsck 2>err &&
|
|
test_grep "unable to parse '\'fsck.skiplist\'' from command-line config" err &&
|
|
test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err &&
|
|
test_grep "could not open.*: does-not-exist" err &&
|
|
test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err &&
|
|
test_grep "invalid object name: " err
|
|
'
|
|
|
|
test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' '
|
|
cat >SKIP.with-comment <<-EOF &&
|
|
# Some bad commit
|
|
$(test_oid 001)
|
|
EOF
|
|
test_must_fail git -c fsck.skipList=SKIP.with-comment fsck 2>err-with-comment &&
|
|
test_grep "missingEmail" err-with-comment &&
|
|
cat >SKIP.with-empty-line <<-EOF &&
|
|
$(test_oid 001)
|
|
|
|
$(test_oid 002)
|
|
EOF
|
|
test_must_fail git -c fsck.skipList=SKIP.with-empty-line fsck 2>err-with-empty-line &&
|
|
test_grep "missingEmail" err-with-empty-line
|
|
'
|
|
|
|
test_expect_success 'fsck no garbage output from comments & empty lines errors' '
|
|
test_line_count = 1 err-with-comment &&
|
|
test_line_count = 1 err-with-empty-line
|
|
'
|
|
|
|
test_expect_success 'fsck with invalid abbreviated skipList input' '
|
|
echo $commit | test_copy_bytes 20 >SKIP.abbreviated &&
|
|
test_must_fail git -c fsck.skipList=SKIP.abbreviated fsck 2>err-abbreviated &&
|
|
test_grep "^fatal: invalid object name: " err-abbreviated
|
|
'
|
|
|
|
test_expect_success 'fsck with exhaustive accepted skipList input (various types of comments etc.)' '
|
|
>SKIP.exhaustive &&
|
|
echo "# A commented line" >>SKIP.exhaustive &&
|
|
echo "" >>SKIP.exhaustive &&
|
|
echo " " >>SKIP.exhaustive &&
|
|
echo " # Comment after whitespace" >>SKIP.exhaustive &&
|
|
echo "$commit # Our bad commit (with leading whitespace and trailing comment)" >>SKIP.exhaustive &&
|
|
echo "# Some bad commit (leading whitespace)" >>SKIP.exhaustive &&
|
|
echo " $(test_oid 001)" >>SKIP.exhaustive &&
|
|
git -c fsck.skipList=SKIP.exhaustive fsck 2>err &&
|
|
test_must_be_empty err
|
|
'
|
|
|
|
test_expect_success 'receive-pack with missing receive.fsck.skipList path' '
|
|
test_must_fail git -c receive.fsck.skipList receive-pack dst 2>err &&
|
|
test_grep "unable to parse '\'receive.fsck.skiplist\'' from command-line config" err
|
|
'
|
|
|
|
test_expect_success 'push with receive.fsck.skipList' '
|
|
git push . $commit:refs/heads/bogus &&
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config receive.fsckObjects true &&
|
|
test_must_fail git push --porcelain dst bogus &&
|
|
echo $commit >dst/.git/SKIP &&
|
|
|
|
# receive.fsck.* does not fall back on fsck.*
|
|
git --git-dir=dst/.git config fsck.skipList SKIP &&
|
|
test_must_fail git push --porcelain dst bogus &&
|
|
|
|
# Invalid and/or bogus skipList input
|
|
git --git-dir=dst/.git config receive.fsck.skipList /dev/null &&
|
|
test_must_fail git push --porcelain dst bogus &&
|
|
git --git-dir=dst/.git config receive.fsck.skipList does-not-exist &&
|
|
test_must_fail git push --porcelain dst bogus 2>err &&
|
|
test_grep "could not open.*: does-not-exist" err &&
|
|
git --git-dir=dst/.git config receive.fsck.skipList config &&
|
|
test_must_fail git push --porcelain dst bogus 2>err &&
|
|
test_grep "invalid object name: " err &&
|
|
|
|
git --git-dir=dst/.git config receive.fsck.skipList SKIP &&
|
|
git push --porcelain dst bogus
|
|
'
|
|
|
|
test_expect_success 'fetch with fetch.fsck.skipList' '
|
|
refspec=refs/heads/bogus:refs/heads/bogus &&
|
|
git push . $commit:refs/heads/bogus &&
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config fetch.fsckObjects true &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
echo $commit >dst/.git/SKIP &&
|
|
|
|
# fetch.fsck.* does not fall back on fsck.*
|
|
git --git-dir=dst/.git config fsck.skipList dst/.git/SKIP &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
|
|
# Invalid and/or bogus skipList input
|
|
test_must_fail git --git-dir=dst/.git -c fetch.fsck.skipList fetch \
|
|
"file://$(pwd)" $refspec 2>err &&
|
|
test_grep "unable to parse '\'fetch.fsck.skiplist\'' from command-line config" err &&
|
|
git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
git --git-dir=dst/.git config fetch.fsck.skipList does-not-exist &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
|
|
test_grep "could not open.*: does-not-exist" err &&
|
|
git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
|
|
test_grep "invalid object name: " err &&
|
|
|
|
git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP &&
|
|
git --git-dir=dst/.git fetch "file://$(pwd)" $refspec
|
|
'
|
|
|
|
test_expect_success 'fsck.<unknownmsg-id> dies' '
|
|
test_must_fail git -c fsck.whatEver=ignore fsck 2>err &&
|
|
test_grep "Unhandled message id: whatever" err
|
|
'
|
|
|
|
test_expect_success 'push with receive.fsck.missingEmail=warn' '
|
|
git push . $commit:refs/heads/bogus &&
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config receive.fsckobjects true &&
|
|
test_must_fail git push --porcelain dst bogus &&
|
|
|
|
# receive.fsck.<msg-id> does not fall back on fsck.<msg-id>
|
|
git --git-dir=dst/.git config fsck.missingEmail warn &&
|
|
test_must_fail git push --porcelain dst bogus &&
|
|
|
|
# receive.fsck.<unknownmsg-id> warns
|
|
git --git-dir=dst/.git config \
|
|
receive.fsck.whatEver error &&
|
|
|
|
git --git-dir=dst/.git config \
|
|
receive.fsck.missingEmail warn &&
|
|
git push --porcelain dst bogus >act 2>&1 &&
|
|
grep "missingEmail" act &&
|
|
test_grep "skipping unknown msg id.*whatever" act &&
|
|
git --git-dir=dst/.git branch -D bogus &&
|
|
git --git-dir=dst/.git config --add \
|
|
receive.fsck.missingEmail ignore &&
|
|
git push --porcelain dst bogus >act 2>&1 &&
|
|
! grep "missingEmail" act
|
|
'
|
|
|
|
test_expect_success 'fetch with fetch.fsck.missingEmail=warn' '
|
|
refspec=refs/heads/bogus:refs/heads/bogus &&
|
|
git push . $commit:refs/heads/bogus &&
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config fetch.fsckobjects true &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
|
|
# fetch.fsck.<msg-id> does not fall back on fsck.<msg-id>
|
|
git --git-dir=dst/.git config fsck.missingEmail warn &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
|
|
|
|
# receive.fsck.<unknownmsg-id> warns
|
|
git --git-dir=dst/.git config \
|
|
fetch.fsck.whatEver error &&
|
|
|
|
git --git-dir=dst/.git config \
|
|
fetch.fsck.missingEmail warn &&
|
|
git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
|
|
grep "missingEmail" act &&
|
|
test_grep "Skipping unknown msg id.*whatever" act &&
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config fetch.fsckobjects true &&
|
|
git --git-dir=dst/.git config \
|
|
fetch.fsck.missingEmail ignore &&
|
|
git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
|
|
! grep "missingEmail" act
|
|
'
|
|
|
|
test_expect_success \
|
|
'receive.fsck.unterminatedHeader=warn triggers error' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config receive.fsckobjects true &&
|
|
git --git-dir=dst/.git config \
|
|
receive.fsck.unterminatedheader warn &&
|
|
test_must_fail git push --porcelain dst HEAD >act 2>&1 &&
|
|
grep "Cannot demote unterminatedheader" act
|
|
'
|
|
|
|
test_expect_success \
|
|
'fetch.fsck.unterminatedHeader=warn triggers error' '
|
|
rm -rf dst &&
|
|
git init dst &&
|
|
git --git-dir=dst/.git config fetch.fsckobjects true &&
|
|
git --git-dir=dst/.git config \
|
|
fetch.fsck.unterminatedheader warn &&
|
|
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" HEAD &&
|
|
grep "Cannot demote unterminatedheader" act
|
|
'
|
|
|
|
test_expect_success PERL_TEST_HELPERS 'badFilemode is not a strict error' '
|
|
git init --bare badmode.git &&
|
|
tree=$(
|
|
cd badmode.git &&
|
|
blob=$(echo blob | git hash-object -w --stdin | hex2oct) &&
|
|
printf "123456 foo\0${blob}" |
|
|
git hash-object -t tree --stdin -w --literally
|
|
) &&
|
|
|
|
rm -rf dst.git &&
|
|
git init --bare dst.git &&
|
|
git -C dst.git config transfer.fsckObjects true &&
|
|
|
|
git -C badmode.git push ../dst.git $tree:refs/tags/tree 2>err &&
|
|
grep "$tree: badFilemode" err
|
|
'
|
|
|
|
test_done
|