934ae52066
'git lfs status' is functional in a non-work tree repository only some of the time. Particularly, when there is nothing to report (and therefore no files to open), 'git lfs status' work as expected. However, when there are files changed in the index, Git LFS tries to open them to see what their hash was before/after the change, and in particular, if they are/were/remain Git LFS pointers. This feature is used to power the "Git <sha-1> -> LFS <sha-256>" output of 'git lfs status'. When in a bare repository and in the aforementioned scenario, the above operation will fail to open a file that does not exist, for the repository is bare and thus does not contain a working tree. In order to bring about a more consistent experience when using 'git lfs status', let's match the behavior upstream and exit immediately with the message: $ git lfs status This operation must be run in a work tree.
467 lines
9.6 KiB
Bash
Executable File
467 lines
9.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
. "$(dirname "$0")/testlib.sh"
|
|
|
|
begin_test "status"
|
|
(
|
|
set -e
|
|
|
|
mkdir repo-1
|
|
cd repo-1
|
|
git init
|
|
git lfs track "*.dat"
|
|
|
|
file_1="some data"
|
|
file_1_oid="$(calc_oid "$file_1")"
|
|
file_1_oid_short="$(echo "$file_1_oid" | head -c 7)"
|
|
printf "%s" "$file_1" > file1.dat
|
|
git add file1.dat
|
|
git commit -m "file1.dat"
|
|
|
|
file_1_new="other data"
|
|
file_1_new_oid="$(calc_oid "$file_1_new")"
|
|
file_1_new_oid_short="$(echo "$file_1_new_oid" | head -c 7)"
|
|
printf "%s" "$file_1_new" > file1.dat
|
|
|
|
file_2="file2 data"
|
|
file_2_oid="$(calc_oid "$file_2")"
|
|
file_2_oid_short="$(echo "$file_2_oid" | head -c 7)"
|
|
printf "%s" "$file_2" > file2.dat
|
|
git add file2.dat
|
|
|
|
file_3="file3 data"
|
|
file_3_oid="$(calc_oid "$file_3")"
|
|
file_3_oid_short="$(echo "$file_3_oid" | head -c 7)"
|
|
printf "%s" "$file_3" > file3.dat
|
|
git add file3.dat
|
|
|
|
file_3_new="file3 other data"
|
|
file_3_new_oid="$(calc_oid "$file_3_new")"
|
|
file_3_new_oid_short="$(echo "$file_3_new_oid" | head -c 7)"
|
|
printf "%s" "$file_3_new" > file3.dat
|
|
|
|
expected="On branch master
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
file2.dat (LFS: $file_2_oid_short)
|
|
file3.dat (LFS: $file_3_oid_short)
|
|
|
|
Git LFS objects not staged for commit:
|
|
|
|
file1.dat (LFS: $file_1_oid_short -> File: $file_1_new_oid_short)
|
|
file3.dat (File: $file_3_new_oid_short)"
|
|
|
|
[ "$expected" = "$(git lfs status)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status --porcelain"
|
|
(
|
|
set -e
|
|
|
|
mkdir repo-2
|
|
cd repo-2
|
|
git init
|
|
git lfs track "*.dat"
|
|
echo "some data" > file1.dat
|
|
git add file1.dat
|
|
git commit -m "file1.dat"
|
|
|
|
echo "other data" > file1.dat
|
|
echo "file2 data" > file2.dat
|
|
git add file2.dat
|
|
|
|
echo "file3 data" > file3.dat
|
|
git add file3.dat
|
|
|
|
echo "file3 other data" > file3.dat
|
|
|
|
expected=" M file1.dat
|
|
A file3.dat
|
|
A file2.dat"
|
|
|
|
[ "$expected" = "$(git lfs status --porcelain)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status --json"
|
|
(
|
|
set -e
|
|
|
|
mkdir repo-3
|
|
cd repo-3
|
|
git init
|
|
git lfs track "*.dat"
|
|
echo "some data" > file1.dat
|
|
git add file1.dat
|
|
git commit -m "file1.dat"
|
|
|
|
echo "other data" > file1.dat
|
|
|
|
expected='{"files":{"file1.dat":{"status":"M"}}}'
|
|
[ "$expected" = "$(git lfs status --json)" ]
|
|
|
|
git add file1.dat
|
|
git commit -m "file1.dat changed"
|
|
git mv file1.dat file2.dat
|
|
|
|
expected='{"files":{"file2.dat":{"status":"R","from":"file1.dat"}}}'
|
|
[ "$expected" = "$(git lfs status --json)" ]
|
|
|
|
git commit -m "file1.dat -> file2.dat"
|
|
|
|
# Ensure status --json does not include non-lfs files
|
|
echo hi > test1.txt
|
|
git add test1.txt
|
|
expected='{"files":{}}'
|
|
[ "$expected" = "$(git lfs status --json)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status in a sub-directory"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-sub-directory"
|
|
git init "$reponame"
|
|
cd "$reponame"
|
|
|
|
git lfs track "*.dat"
|
|
printf "asdf" > file.dat
|
|
mkdir -p dir
|
|
git add .gitattributes file.dat
|
|
git commit -m "initial commit"
|
|
|
|
printf "ASDF" > file.dat
|
|
|
|
expected="On branch master
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
|
|
Git LFS objects not staged for commit:
|
|
|
|
../file.dat (LFS: f0e4c2f -> File: 99b3bcf)"
|
|
|
|
[ "$expected" = "$(cd dir && git lfs status)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status: outside git repository"
|
|
(
|
|
set +e
|
|
git lfs status 2>&1 > status.log
|
|
res=$?
|
|
|
|
set -e
|
|
if [ "$res" = "0" ]; then
|
|
echo "Passes because $GIT_LFS_TEST_DIR is unset."
|
|
exit 0
|
|
fi
|
|
[ "$res" = "128" ]
|
|
grep "Not in a git repository" status.log
|
|
)
|
|
end_test
|
|
|
|
begin_test "status - before initial commit"
|
|
(
|
|
set -e
|
|
|
|
git init repo-initial
|
|
cd repo-initial
|
|
git lfs track "*.dat"
|
|
|
|
# should not fail when nothing to display (ignore output, will be blank)
|
|
git lfs status
|
|
|
|
contents="some data"
|
|
contents_oid="$(calc_oid "$contents")"
|
|
contents_oid_short="$(echo "$contents_oid" | head -c 7)"
|
|
|
|
printf "%s" "$contents" > file1.dat
|
|
git add file1.dat
|
|
|
|
expected="
|
|
Git LFS objects to be committed:
|
|
|
|
file1.dat (LFS: $contents_oid_short)
|
|
|
|
Git LFS objects not staged for commit:"
|
|
|
|
[ "$expected" = "$(git lfs status)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status shows multiple files with identical contents"
|
|
(
|
|
set -e
|
|
|
|
reponame="uniq-status"
|
|
mkdir "$reponame"
|
|
cd "$reponame"
|
|
|
|
git init
|
|
git lfs track "*.dat"
|
|
|
|
contents="contents"
|
|
printf "%s" "$contents" > a.dat
|
|
printf "%s" "$contents" > b.dat
|
|
|
|
git add --all .
|
|
|
|
git lfs status | tee status.log
|
|
|
|
[ "1" -eq "$(grep -c "a.dat" status.log)" ]
|
|
[ "1" -eq "$(grep -c "b.dat" status.log)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status shows multiple copies of partially staged files"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-partially-staged"
|
|
git init "$reponame"
|
|
cd "$reponame"
|
|
|
|
git lfs track "*.dat"
|
|
git add .gitattributes
|
|
git commit -m "initial commit"
|
|
|
|
contents_1="part 1"
|
|
contents_1_oid="$(calc_oid "$contents_1")"
|
|
contents_1_oid_short="$(echo "$contents_1_oid" | head -c 7)"
|
|
printf "%s" "$contents_1" > a.dat
|
|
|
|
# "$contents_1" changes are staged
|
|
git add a.dat
|
|
|
|
# "$contents_2" changes are unstaged
|
|
contents_2="part 2"
|
|
contents_2_oid="$(calc_oid "$contents_2")"
|
|
contents_2_oid_short="$(echo "$contents_2_oid" | head -c 7)"
|
|
printf "%s" "$contents_2" > a.dat
|
|
|
|
expected="On branch master
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
a.dat (LFS: $contents_1_oid_short)
|
|
|
|
Git LFS objects not staged for commit:
|
|
|
|
a.dat (File: $contents_2_oid_short)"
|
|
actual="$(git lfs status)"
|
|
|
|
diff -u <(echo "$expected") <(echo "$actual")
|
|
)
|
|
end_test
|
|
|
|
begin_test "status: LFS to LFS change"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-lfs-to-lfs-change"
|
|
setup_remote_repo "$reponame"
|
|
clone_repo "$reponame" "$reponame"
|
|
|
|
contents="contents"
|
|
contents_oid="$(calc_oid "$contents")"
|
|
contents_oid_short="$(echo "$contents_oid" | head -c 7)"
|
|
|
|
git lfs track "*.dat"
|
|
git add .gitattributes
|
|
git commit -m "track *.dat files"
|
|
|
|
printf "%s" "$contents" > a.dat
|
|
git add a.dat
|
|
git commit -m "add a.dat"
|
|
|
|
contents_new="$contents +extra"
|
|
contents_new_oid="$(calc_oid "$contents_new")"
|
|
contents_new_oid_short="$(echo $contents_new_oid | head -c 7)"
|
|
|
|
printf "%s" "$contents_new" > a.dat
|
|
git add a.dat
|
|
|
|
expected="On branch master
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
a.dat (LFS: $contents_oid_short -> LFS: $contents_new_oid_short)
|
|
|
|
Git LFS objects not staged for commit:"
|
|
actual="$(git lfs status)"
|
|
|
|
[ "$expected" = "$actual" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status: Git to LFS change"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-git-to-lfs-change"
|
|
setup_remote_repo "$reponame"
|
|
clone_repo "$reponame" "$reponame"
|
|
|
|
contents="contents"
|
|
contents_oid="$(calc_oid "$contents")"
|
|
contents_oid_short="$(echo "$contents_oid" | head -c 7)"
|
|
|
|
printf "%s" "$contents" > a.dat
|
|
git add a.dat
|
|
git commit -m "add a.dat"
|
|
|
|
git lfs track "*.dat"
|
|
git add .gitattributes
|
|
git commit -m "track *.dat files"
|
|
|
|
contents_new="$contents +extra"
|
|
contents_new_oid="$(calc_oid "$contents_new")"
|
|
contents_new_oid_short="$(echo $contents_new_oid | head -c 7)"
|
|
|
|
printf "%s" "$contents_new" > a.dat
|
|
git add a.dat
|
|
|
|
expected="On branch master
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
a.dat (Git: $contents_oid_short -> LFS: $contents_new_oid_short)
|
|
|
|
Git LFS objects not staged for commit:"
|
|
actual="$(git lfs status)"
|
|
|
|
[ "$expected" = "$actual" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status: Git to LFS conversion"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-git-to-lfs-conversion"
|
|
setup_remote_repo "$reponame"
|
|
clone_repo "$reponame" "$reponame"
|
|
|
|
contents="contents"
|
|
contents_oid="$(calc_oid "$contents")"
|
|
contents_oid_short="$(echo "$contents_oid" | head -c 7)"
|
|
|
|
printf "%s" "$contents" > a.dat
|
|
git add a.dat
|
|
git commit -m "add a.dat"
|
|
|
|
git lfs track "*.dat"
|
|
git add .gitattributes
|
|
git commit -m "track *.dat"
|
|
|
|
git push origin master
|
|
|
|
pushd "$TRASHDIR" > /dev/null
|
|
clone_repo "$reponame" "$reponame-2"
|
|
|
|
git add a.dat
|
|
|
|
git lfs status 2>&1 | tee status.log
|
|
if [ "0" -ne "${PIPESTATUS[0]}" ]; then
|
|
echo >&2 "git lfs status should have succeeded, didn't ..."
|
|
exit 1
|
|
fi
|
|
|
|
expected="On branch master
|
|
Git LFS objects to be pushed to origin/master:
|
|
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
a.dat (Git: $contents_oid_short -> LFS: $contents_oid_short)
|
|
|
|
Git LFS objects not staged for commit:"
|
|
actual="$(cat status.log)"
|
|
|
|
[ "$expected" = "$actual" ]
|
|
popd > /dev/null
|
|
)
|
|
end_test
|
|
|
|
begin_test "status (missing objects)"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-missing-objects"
|
|
git init "$reponame"
|
|
cd "$reponame"
|
|
|
|
git lfs track "*.dat"
|
|
printf "a" > a.dat
|
|
|
|
git add .gitattributes a.dat
|
|
git commit -m "initial commit"
|
|
|
|
# Remove the original object "a.dat" (ensure '--no-filters' is not given).
|
|
oid="$(git hash-object -t blob -- a.dat)"
|
|
rm -rf ".git/objects/${oid:0:2}/${oid:2}"
|
|
|
|
# Create an unstaged change against a source file that doesn't exist.
|
|
printf "b" > a.dat
|
|
git add a.dat
|
|
|
|
git lfs status \
|
|
| grep "a.dat (?: <missing> -> LFS: $(calc_oid b | head -c 7))"
|
|
)
|
|
end_test
|
|
|
|
begin_test "status (unpushed objects)"
|
|
(
|
|
set -e
|
|
|
|
reponame="status-unpushed-objects"
|
|
setup_remote_repo "$reponame"
|
|
clone_repo "$reponame" "$reponame"
|
|
|
|
git lfs track "*.dat"
|
|
git add .gitattributes
|
|
git commit -m "initial commit"
|
|
|
|
git push origin master
|
|
|
|
contents="a"
|
|
oid="$(calc_oid "$contents")"
|
|
printf "%s" "$contents" > a.dat
|
|
|
|
git add a.dat
|
|
git commit -m "add a large file"
|
|
|
|
expected="On branch master
|
|
Git LFS objects to be pushed to origin/master:
|
|
|
|
a.dat ($oid)
|
|
|
|
Git LFS objects to be committed:
|
|
|
|
|
|
Git LFS objects not staged for commit:"
|
|
|
|
[ "$expected" = "$(git lfs status)" ]
|
|
)
|
|
end_test
|
|
|
|
begin_test "status (without a working copy)"
|
|
(
|
|
reponame="status-no-working-copy.git"
|
|
|
|
git init --bare "$reponame"
|
|
cd "$reponame"
|
|
|
|
git lfs status 2>&1 | tee status.log
|
|
if [ "0" -eq "${PIPESTATUS[0]}" ]; then
|
|
echo >&2 "git lfs status should have failed, didn't ..."
|
|
exit 1
|
|
fi
|
|
[ "This operation must be run in a work tree." = "$(cat status.log)" ]
|
|
)
|
|
end_test
|