git-lfs/t/t-push.sh
Chris Darroch 115484e8ad commands,t: report invalid ref in push command
Unlike the "git lfs fetch" command, the "git lfs push" command does
not currently report an error if an invalid ref is provided as a
command-line argument, so we update the command to output an error
message in this situation, and we add a test to confirm the new
behaviour works as expected.

Note that in contrast to the "git lfs fetch" command's older
implementation of this type of check, we simply report an error message
when an invalid ref is encountered, rather than calling our Panic()
function and also writing a stack trace to a log file.  This approach is
more in keeping with how many of our commands now handle similar error
conditions; e.g., the "git lfs fsck" and "git lfs migrate" commands
call ExitWithError() rather than Panic() when refs cannot be resolved.

Co-authored-by: Philip Peterson <philip.c.peterson@gmail.com>
2024-01-31 22:09:35 -08:00

961 lines
28 KiB
Bash
Executable File

#!/usr/bin/env bash
. "$(dirname "$0")/testlib.sh"
# sets up the repos for the first few push tests. The passed argument is the
# name of the repo to setup. The resulting repo will have a local file tracked
# with LFS and committed, but not yet pushed to the remote
push_repo_setup() {
reponame="$1"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" false
git lfs track "*.dat"
echo "push a" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat"
}
begin_test "push with good ref"
(
set -e
push_repo_setup "push-main-branch-required"
git lfs push origin main
)
end_test
begin_test "push with tracked ref"
(
set -e
push_repo_setup "push-tracked-branch-required"
git config push.default upstream
git config branch.main.merge refs/heads/tracked
git lfs push origin main
)
end_test
begin_test "push with invalid ref"
(
set -e
push_repo_setup "push-invalid-branch-required"
git lfs push origin jibberish >push.log 2>&1 && exit 1
grep "Invalid ref argument" push.log
)
end_test
begin_test "push with bad ref"
(
set -e
push_repo_setup "push-other-branch-required"
git lfs push origin main 2>&1 | tee push.log
if [ "0" -eq "${PIPESTATUS[0]}" ]; then
echo "expected command to fail"
exit 1
fi
grep 'batch response: Expected ref "refs/heads/other", got "refs/heads/main"' push.log
)
end_test
begin_test "push with nothing"
(
set -e
push_repo_setup "push-nothing"
git lfs push origin 2>&1 | tee push.log
grep "At least one ref must be supplied without --all" push.log
)
end_test
begin_test "push with given remote, configured pushRemote"
(
set -e
push_repo_setup "push-given-and-config"
git remote add bad-remote "invalid-url"
git config branch.main.pushRemote bad-remote
git lfs push --all origin
)
end_test
begin_test "push via stdin with extra arguments"
(
set -e
push_repo_setup "push-stdin-extra-args"
echo "main" | git lfs push origin --stdin --dry-run "another-ref" \
2>&1 | tee push.log
grep "Further command line arguments are ignored with --stdin" push.log
)
begin_test "push"
(
set -e
reponame="$(basename "$0" ".sh")"
setup_remote_repo "$reponame"
clone_repo "$reponame" repo
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" true
git lfs track "*.dat"
echo "push a" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat"
git lfs push --dry-run origin main 2>&1 | tee push.log
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 => a.dat" push.log
[ $(grep -c "^push " push.log) -eq 1 ]
git lfs push origin main 2>&1 | tee push.log
grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
git checkout -b push-b
echo "push b" > b.dat
git add b.dat
git commit -m "add b.dat"
git lfs push --dry-run origin push-b 2>&1 | tee push.log
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 => a.dat" push.log
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 => b.dat" push.log
[ $(grep -c "^push " < push.log) -eq 2 ]
printf "push-b\n\n" | git lfs push --dry-run origin --stdin 2>&1 | tee push.log
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 => a.dat" push.log
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 => b.dat" push.log
[ $(grep -c "^push " < push.log) -eq 2 ]
# simulate remote ref
mkdir -p .git/refs/remotes/origin
git rev-parse HEAD > .git/refs/remotes/origin/HEAD
git lfs push --dry-run origin push-b 2>&1 | tee push.log
[ $(grep -c "^push " push.log) -eq 0 ]
rm -rf .git/refs/remotes
git lfs push origin push-b 2>&1 | tee push.log
grep "Uploading LFS objects: 100% (2/2), 14 B" push.log
)
end_test
# helper used by the next few push --all tests to set up their repos
push_all_setup() {
suffix="$1"
reponame="$(basename "$0" ".sh")-all-$suffix"
content1="initial"
content2="update"
content3="branch"
content4="tagged"
content5="main"
extracontent="extra"
oid1=$(calc_oid "$content1")
oid2=$(calc_oid "$content2")
oid3=$(calc_oid "$content3")
oid4=$(calc_oid "$content4")
oid5=$(calc_oid "$content5")
extraoid=$(calc_oid "$extracontent")
clone_repo "$reponame" "push-all-$suffix"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" true
git lfs track "*.dat"
echo "[
{
\"CommitDate\":\"$(get_date -6m)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content1},\"Data\":\"$content1\"}
]
},
{
\"CommitDate\":\"$(get_date -5m)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content2},\"Data\":\"$content2\"}
]
},
{
\"CommitDate\":\"$(get_date -4m)\",
\"NewBranch\":\"branch\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content3},\"Data\":\"$content3\"}
]
},
{
\"CommitDate\":\"$(get_date -4m)\",
\"ParentBranches\":[\"main\"],
\"Tags\":[\"tag\"],
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content4},\"Data\":\"$content4\"}
]
},
{
\"CommitDate\":\"$(get_date -2m)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content5},\"Data\":\"$content5\"},
{\"Filename\":\"file2.dat\",\"Size\":${#extracontent},\"Data\":\"$extracontent\"}
]
}
]" | lfstest-testutils addcommits
git rm file2.dat
git commit -m "remove file2.dat"
# simulate remote ref
mkdir -p .git/refs/remotes/origin
git rev-parse HEAD > .git/refs/remotes/origin/HEAD
setup_alternate_remote "$reponame-$suffix"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame-$suffix").locksverify" true
}
begin_test "push --all (no ref args)"
(
set -e
push_all_setup "everything"
git lfs push --dry-run --all origin 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
grep "push $oid5 => file1.dat" push.log
grep "push $extraoid => file2.dat" push.log
[ $(grep -c "^push " < push.log) -eq 6 ]
git push --all origin 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (6/6)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix" "$oid1"
assert_server_object "$reponame-$suffix" "$oid2"
assert_server_object "$reponame-$suffix" "$oid3"
assert_server_object "$reponame-$suffix" "$oid4"
assert_server_object "$reponame-$suffix" "$oid5"
assert_server_object "$reponame-$suffix" "$extraoid"
echo "push while missing old objects locally"
setup_alternate_remote "$reponame-$suffix-2"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame-$suffix-2").locksverify" true
git lfs push --object-id origin $oid1
assert_server_object "$reponame-$suffix-2" "$oid1"
refute_server_object "$reponame-$suffix-2" "$oid2"
refute_server_object "$reponame-$suffix-2" "$oid3"
refute_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
rm ".git/lfs/objects/${oid1:0:2}/${oid1:2:2}/$oid1"
echo "dry run missing local object that exists on server"
git lfs push --dry-run --all origin 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
grep "push $oid5 => file1.dat" push.log
grep "push $extraoid => file2.dat" push.log
[ $(grep -c "^push " push.log) -eq 6 ]
git push --all origin 2>&1 | tee push.log
grep "Uploading LFS objects: 100% (6/6)" push.log
assert_server_object "$reponame-$suffix-2" "$oid2"
assert_server_object "$reponame-$suffix-2" "$oid3"
assert_server_object "$reponame-$suffix-2" "$oid4"
assert_server_object "$reponame-$suffix-2" "$oid5"
assert_server_object "$reponame-$suffix-2" "$extraoid"
)
end_test
begin_test "push --all (1 ref arg)"
(
set -e
push_all_setup "ref"
git lfs push --dry-run --all origin branch 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
[ $(grep -c "^push " < push.log) -eq 3 ]
git lfs push --all origin branch 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (3/3)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix" "$oid1"
assert_server_object "$reponame-$suffix" "$oid2"
assert_server_object "$reponame-$suffix" "$oid3"
refute_server_object "$reponame-$suffix" "$oid4" # in main and the tag
refute_server_object "$reponame-$suffix" "$oid5"
refute_server_object "$reponame-$suffix" "$extraoid"
echo "push while missing old objects locally"
setup_alternate_remote "$reponame-$suffix-2"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame-$suffix-2").locksverify" true
git lfs push --object-id origin $oid1
assert_server_object "$reponame-$suffix-2" "$oid1"
refute_server_object "$reponame-$suffix-2" "$oid2"
refute_server_object "$reponame-$suffix-2" "$oid3"
refute_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
rm ".git/lfs/objects/${oid1:0:2}/${oid1:2:2}/$oid1"
# dry run doesn't change
git lfs push --dry-run --all origin branch 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
[ $(grep -c "^push " push.log) -eq 3 ]
git push origin branch 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (3/3)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix-2" "$oid2"
assert_server_object "$reponame-$suffix-2" "$oid3"
refute_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
)
end_test
begin_test "push --all (multiple ref args)"
(
set -e
push_all_setup "multiple-refs"
git lfs push --dry-run --all origin branch tag 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
[ $(grep -c "^push " push.log) -eq 4 ]
printf "branch\ntag" | git lfs push --dry-run --all origin --stdin 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
[ $(grep -c "^push " push.log) -eq 4 ]
git lfs push --all origin branch tag 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (4/4)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix" "$oid1"
assert_server_object "$reponame-$suffix" "$oid2"
assert_server_object "$reponame-$suffix" "$oid3"
assert_server_object "$reponame-$suffix" "$oid4"
refute_server_object "$reponame-$suffix" "$oid5" # only in main
refute_server_object "$reponame-$suffix" "$extraoid"
echo "push while missing old objects locally"
setup_alternate_remote "$reponame-$suffix-2"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame-$suffix-2").locksverify" true
git lfs push --object-id origin $oid1
assert_server_object "$reponame-$suffix-2" "$oid1"
refute_server_object "$reponame-$suffix-2" "$oid2"
refute_server_object "$reponame-$suffix-2" "$oid3"
refute_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
rm ".git/lfs/objects/${oid1:0:2}/${oid1:2:2}/$oid1"
# dry run doesn't change
git lfs push --dry-run --all origin branch tag 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid3 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
[ $(grep -c "^push " push.log) -eq 4 ]
git push origin branch refs/tags/tag 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (4/4)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix-2" "$oid2"
assert_server_object "$reponame-$suffix-2" "$oid3"
assert_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
)
end_test
begin_test "push --all (ref with deleted files)"
(
set -e
push_all_setup "ref-with-deleted"
git lfs push --dry-run --all origin main 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
grep "push $oid5 => file1.dat" push.log
grep "push $extraoid => file2.dat" push.log
[ $(grep -c "^push " push.log) -eq 5 ]
git lfs push --all origin main 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (5/5)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix" "$oid1"
assert_server_object "$reponame-$suffix" "$oid2"
refute_server_object "$reponame-$suffix" "$oid3" # only in the branch
assert_server_object "$reponame-$suffix" "$oid4"
assert_server_object "$reponame-$suffix" "$oid5"
assert_server_object "$reponame-$suffix" "$extraoid"
echo "push while missing old objects locally"
setup_alternate_remote "$reponame-$suffix-2"
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame-$suffix-2").locksverify" true
git lfs push --object-id origin $oid1
assert_server_object "$reponame-$suffix-2" "$oid1"
refute_server_object "$reponame-$suffix-2" "$oid2"
refute_server_object "$reponame-$suffix-2" "$oid3"
refute_server_object "$reponame-$suffix-2" "$oid4"
refute_server_object "$reponame-$suffix-2" "$oid5"
refute_server_object "$reponame-$suffix-2" "$extraoid"
rm ".git/lfs/objects/${oid1:0:2}/${oid1:2:2}/$oid1"
# dry run doesn't change
git lfs push --dry-run --all origin main 2>&1 | tee push.log
grep "push $oid1 => file1.dat" push.log
grep "push $oid2 => file1.dat" push.log
grep "push $oid4 => file1.dat" push.log
grep "push $oid5 => file1.dat" push.log
grep "push $extraoid => file2.dat" push.log
[ $(grep -c "^push " push.log) -eq 5 ]
git push origin main 2>&1 | tee push.log
[ $(grep -c "Uploading LFS objects: 100% (5/5)" push.log) -eq 1 ]
assert_server_object "$reponame-$suffix-2" "$oid2"
refute_server_object "$reponame-$suffix-2" "$oid3"
assert_server_object "$reponame-$suffix-2" "$oid4"
assert_server_object "$reponame-$suffix-2" "$oid5"
assert_server_object "$reponame-$suffix-2" "$extraoid"
)
end_test
begin_test "push object id(s)"
(
set -e
reponame="$(basename "$0" ".sh")"
setup_remote_repo "$reponame"
clone_repo "$reponame" repo2
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" true
git lfs track "*.dat"
echo "push a" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat"
git lfs push --object-id origin --dry-run 2>&1 | tee push.log
grep "At least one object ID must be supplied with --object-id" push.log
git lfs push --object-id origin \
4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 \
2>&1 | tee push.log
grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
echo "push b" > b.dat
git add b.dat
git commit -m "add b.dat"
git lfs push --object-id origin \
4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 \
82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 \
2>&1 | tee push.log
grep "Uploading LFS objects: 100% (2/2), 14 B" push.log
)
end_test
begin_test "push object id(s) via stdin"
(
set -e
reponame="$(basename "$0" ".sh")"
setup_remote_repo "$reponame"
clone_repo "$reponame" repo3
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" true
git lfs track "*.dat"
echo "push a" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat"
git lfs push --object-id origin --stdin --dry-run </dev/null 2>&1 | tee push.log
grep "At least one object ID must be supplied with --object-id" push.log && exit 1
echo "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340" | \
git lfs push --object-id origin --stdin --dry-run "c0ffee" \
2>&1 | tee push.log
grep "Further command line arguments are ignored with --stdin" push.log
echo "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340" | \
git lfs push --object-id origin --stdin --dry-run \
2>&1 | tee push.log
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 =>" push.log
echo "push b" > b.dat
git add b.dat
git commit -m "add b.dat"
printf "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340\n82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7\n\n" | \
git lfs push --object-id origin --stdin --dry-run \
2>&1 | tee push.log
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 =>" push.log
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 =>" push.log
)
end_test
begin_test "push modified files"
(
set -e
reponame="$(basename "$0" ".sh")-modified"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
# generate content we'll use
content1="filecontent1"
content2="filecontent2"
content3="filecontent3"
content4="filecontent4"
content5="filecontent5"
oid1=$(calc_oid "$content1")
oid2=$(calc_oid "$content2")
oid3=$(calc_oid "$content3")
oid4=$(calc_oid "$content4")
oid5=$(calc_oid "$content5")
echo "[
{
\"CommitDate\":\"$(get_date -6m)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content1}, \"Data\":\"$content1\"}]
},
{
\"CommitDate\":\"$(get_date -3m)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content2}, \"Data\":\"$content2\"}]
},
{
\"CommitDate\":\"$(get_date -1m)\",
\"NewBranch\":\"other_branch\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content5}, \"Data\":\"$content5\"}]
},
{
\"CommitDate\":\"$(get_date -1m)\",
\"ParentBranches\":[\"main\"],
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content3}, \"Data\":\"$content3\"},
{\"Filename\":\"file2.dat\",\"Size\":${#content4}, \"Data\":\"$content4\"}]
}
]" | lfstest-testutils addcommits
git lfs push origin main
git lfs push origin other_branch
assert_server_object "$reponame" "$oid1"
assert_server_object "$reponame" "$oid2"
assert_server_object "$reponame" "$oid3"
assert_server_object "$reponame" "$oid4"
assert_server_object "$reponame" "$oid5"
)
end_test
begin_test "push with invalid remote"
(
set -e
cd repo
git lfs push not-a-remote 2>&1 | tee push.log
grep "Invalid remote name" push.log
)
end_test
begin_test "push ambiguous branch name"
(
set -e
reponame="$(basename "$0" ".sh")-ambiguous-branch"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat" 2>&1 | tee track.log
grep "Tracking \"\*.dat\"" track.log
NUMFILES=5
# generate content we'll use
for ((a=0; a < NUMFILES ; a++))
do
content[$a]="filecontent$a"
oid[$a]=$(calc_oid "${content[$a]}")
done
echo "[
{
\"CommitDate\":\"$(get_date -10d)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content[0]}, \"Data\":\"${content[0]}\"},
{\"Filename\":\"file2.dat\",\"Size\":${#content[1]}, \"Data\":\"${content[1]}\"}]
},
{
\"NewBranch\":\"ambiguous\",
\"CommitDate\":\"$(get_date -5d)\",
\"Files\":[
{\"Filename\":\"file3.dat\",\"Size\":${#content[2]}, \"Data\":\"${content[2]}\"}]
},
{
\"CommitDate\":\"$(get_date -2d)\",
\"Files\":[
{\"Filename\":\"file4.dat\",\"Size\":${#content[3]}, \"Data\":\"${content[3]}\"}]
},
{
\"ParentBranches\":[\"main\"],
\"CommitDate\":\"$(get_date -1d)\",
\"Files\":[
{\"Filename\":\"file1.dat\",\"Size\":${#content[4]}, \"Data\":\"${content[4]}\"}]
}
]" | lfstest-testutils addcommits
# create tag with same name as branch
git tag ambiguous
# lfs push main, should work
git lfs push origin main
# push ambiguous, does not fail since lfs scans git with sha, not ref name
git lfs push origin ambiguous
)
end_test
begin_test "push (retry with expired actions)"
(
set -e
reponame="push_retry_expired_action"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
contents="return-expired-action"
contents_oid="$(calc_oid "$contents")"
contents_size="$(printf "%s" "$contents" | wc -c | awk '{ print $1 }')"
printf "%s" "$contents" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat, .gitattributes" 2>&1 | tee commit.log
grep "main (root-commit)" commit.log
grep "2 files changed" commit.log
grep "create mode 100644 a.dat" commit.log
grep "create mode 100644 .gitattributes" commit.log
GIT_TRACE=1 git push origin main 2>&1 | tee push.log
expected="enqueue retry #1 after 0.25s for \"$contents_oid\" (size: $contents_size): LFS: action \"upload\" expires at"
grep "$expected" push.log
grep "Uploading LFS objects: 100% (1/1), 21 B" push.log
)
end_test
begin_test "push to raw remote url"
(
set -e
setup_remote_repo "push-raw"
mkdir push-raw
cd push-raw
git init
git lfs track "*.dat"
contents="raw"
contents_oid=$(calc_oid "$contents")
printf "%s" "$contents" > raw.dat
git add raw.dat .gitattributes
git commit -m "add" 2>&1 | tee commit.log
grep "main (root-commit)" commit.log
grep "2 files changed" commit.log
grep "create mode 100644 raw.dat" commit.log
grep "create mode 100644 .gitattributes" commit.log
refute_server_object push-raw "$contents_oid"
git lfs push $GITSERVER/push-raw main
assert_server_object push-raw "$contents_oid"
)
end_test
begin_test "push (with invalid object size)"
(
set -e
reponame="push-invalid-object-size"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
contents="return-invalid-size"
printf "%s" "$contents" > a.dat
git add a.dat .gitattributes
git commit -m "add a.dat, .gitattributes" 2>&1 | tee commit.log
grep "main (root-commit)" commit.log
grep "2 files changed" commit.log
grep "create mode 100644 a.dat" commit.log
grep "create mode 100644 .gitattributes" commit.log
set +e
git push origin main 2>&1 2> push.log
res="$?"
set -e
grep "invalid size (got: -1)" push.log
[ "0" -eq "$(grep -c "panic" push.log)" ]
[ "0" -ne "$res" ]
refute_server_object "$reponame" "$(calc_oid "$contents")"
)
end_test
begin_test "push with deprecated _links"
(
set -e
reponame="$(basename "$0" ".sh")-deprecated"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
git add .gitattributes
git commit -m "initial commit"
contents="send-deprecated-links"
contents_oid="$(calc_oid "$contents")"
printf "%s" "$contents" > a.dat
git add a.dat
git commit -m "add a.dat"
git push origin main
assert_server_object "$reponame" "$contents_oid"
)
end_test
begin_test "push with invalid pushInsteadof"
(
set -e
push_repo_setup "push-invalid-pushinsteadof"
# set pushInsteadOf to rewrite the href of uploading LFS object.
git config url."$GITSERVER/storage/invalid".pushInsteadOf "$GITSERVER/storage/"
# Enable href rewriting explicitly.
git config lfs.transfer.enablehrefrewrite true
set +e
git lfs push origin main > push.log 2>&1
res=$?
set -e
[ "$res" = "2" ]
# check rewritten href is used to upload LFS object.
grep "LFS: Authorization error: $GITSERVER/storage/invalid" push.log
# lfs-push succeed after unsetting enableHrefRewrite config
git config --unset lfs.transfer.enablehrefrewrite
git lfs push origin main
)
end_test
begin_test 'push with data the server already has'
(
set -e
reponame="push-server-data"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
git add .gitattributes
git commit -m "initial commit"
contents="abc123"
contents_oid="$(calc_oid "$contents")"
printf "%s" "$contents" > a.dat
git add a.dat
git commit -m "add a.dat"
git push origin main
assert_server_object "$reponame" "$contents_oid"
git checkout -b side
# Use a different file name for the second file; otherwise, this test
# unexpectedly passes with the old code, since we fail to notice that the
# object we run through the clean filter is not the object we wanted.
contents2="def456"
contents2_oid="$(calc_oid "$contents2")"
printf "%s" "$contents2" > b.dat
git add b.dat
git commit -m "add b.dat"
# We remove the original object. The server already has this.
delete_local_object "$contents_oid"
# We use the URL so that we cannot take advantage of the existing "origin/*"
# refs that we know the server must have. We will traverse the entire history
# for this push, and we should not fail because the server already has the
# object we deleted above.
git push "$(git config remote.origin.url)" side
assert_server_object "$reponame" "$contents2_oid"
)
end_test
begin_test 'push with multiple refs and data the server already has'
(
set -e
reponame="push-multi-ref-server-data"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
git add .gitattributes
git commit -m "initial commit"
contents="abc123"
contents_oid="$(calc_oid "$contents")"
printf "%s" "$contents" > a.dat
git add a.dat
git commit -m "add a.dat"
git push origin main
assert_server_object "$reponame" "$contents_oid"
contents2="def456"
contents2_oid="$(calc_oid "$contents2")"
printf "%s" "$contents2" > b.dat
git add b.dat
git commit -m "add b.dat"
# Create a tag. Normally this would cause the entire history to be traversed
# since it's a new ref, but we no longer do that since we're pushing multiple
# refs.
git tag -m v1.0.0 -a v1.0.0
# We remove the original object. The server already has this.
delete_local_object "$contents_oid"
# We use the URL so that we cannot take advantage of the existing "origin/*"
# refs that we know the server must have.
GIT_TRACE=1 GIT_TRANSFER_TRACE=1 GIT_CURL_VERBOSE=1 \
git push "$(git config remote.origin.url)" main v1.0.0 2>&1 | tee push.log
# We should not find a batch request for the object which is in the earlier
# version of main, since we know the remote side has it.
[ "$(grep -c "$contents_oid" push.log)" = 0 ]
# Yet we should have pushed the new object successfully.
assert_server_object "$reponame" "$contents2_oid"
)
end_test
begin_test "push custom reference"
(
set -e
reponame="push-custom-reference"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"
git lfs track "*.dat"
# generate content we'll use
content="filecontent"
oid=$(calc_oid "$content")
echo "[
{
\"CommitDate\":\"$(get_date -6m)\",
\"Files\":[
{\"Filename\":\"file.dat\",\"Size\":${#content}, \"Data\":\"$content\"}]
}
]" | lfstest-testutils addcommits
# Create and try pushing a reference in a nonstandard namespace, that is,
# outside of refs/heads, refs/tags, and refs/remotes.
git update-ref refs/custom/remote/heads/main refs/heads/main
git lfs push origin refs/custom/remote/heads/main
assert_server_object "$reponame" "$oid"
)
end_test
begin_test "push --object-id (invalid value)"
(
set -e
push_all_setup "push-invalid-oid"
git lfs push --object-id origin '' 2>&1 | tee push.log
git lfs push --object-id origin "${oid1:0:3}" 2>&1 | tee -a push.log
[ "$(grep -c 'too short object ID' push.log)" -eq 2 ]
)
end_test
begin_test "storage upload with compression"
(
set -e
reponame="storage-compress"
setup_remote_repo "$reponame"
clone_repo "$reponame" storage-compress
contents="storage-compress"
oid="$(calc_oid "$contents")"
printf "%s" "$contents" > a.dat
git lfs track "*.dat"
git add .gitattributes a.dat
git commit -m "initial commit"
GIT_CURL_VERBOSE=1 git push origin main | tee push.log
assert_server_object "$reponame" "$oid"
pushd ..
git \
-c "filter.lfs.process=" \
-c "filter.lfs.smudge=cat" \
-c "filter.lfs.required=false" \
clone "$GITSERVER/$reponame" "$reponame-assert"
cd "$reponame-assert"
git config credential.helper lfstest
GIT_TRACE=1 git lfs pull origin main 2>&1 | tee pull.log
if [ "0" -ne "${PIPESTATUS[0]}" ]; then
echo >&2 "fatal: expected \`git lfs pull origin main\` to succeed ..."
exit 1
fi
grep "decompressed gzipped response" pull.log
assert_local_object "$oid" "${#contents}"
popd
)
end_test