git-lfs/t/t-migrate-import.sh
Chris Darroch 021a06ec55 commands,t: make import default to saving work
We update the prompt to be more explicit when the import
(or export) migration commands notice a "dirty" working
tree with uncommitted changes, and we also revise the
default action in this case to be to exit early and
preserve the work in progress.

h/t bk2204 for the suggested revisions.
2021-03-26 15:39:22 -07:00

976 lines
29 KiB
Bash
Executable File

#!/usr/bin/env bash
. "$(dirname "$0")/fixtures/migrate.sh"
. "$(dirname "$0")/testlib.sh"
begin_test "migrate import (default branch)"
(
set -e
setup_multiple_local_branches
md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
md_feature_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
git lfs migrate import
assert_pointer "refs/heads/main" "a.md" "$md_oid" "140"
assert_pointer "refs/heads/main" "a.txt" "$txt_oid" "120"
assert_local_object "$md_oid" "140"
assert_local_object "$txt_oid" "120"
refute_local_object "$md_feature_oid" "30"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
[ ! $(git cat-file -p "$feature:.gitattributes") ]
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
# Ensure that hooks are installed. If we find 'git-lfs' somewhere in
# .git/hooks/pre-push we assume that the rest went correctly, too.
grep -q "git-lfs" .git/hooks/pre-push
)
end_test
begin_test "migrate import (bare repository)"
(
set -e
setup_multiple_remote_branches
git lfs migrate import --everything
)
end_test
begin_test "migrate import (given branch)"
(
set -e
setup_multiple_local_branches
md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
md_feature_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
git lfs migrate import my-feature
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_oid" "120"
assert_pointer "refs/heads/main" "a.md" "$md_oid" "140"
assert_pointer "refs/heads/main" "a.txt" "$txt_oid" "120"
assert_local_object "$md_oid" "140"
assert_local_object "$md_feature_oid" "30"
assert_local_object "$txt_oid" "120"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (default branch with filter)"
(
set -e
setup_multiple_local_branches
md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
md_feature_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
git lfs migrate import --include "*.md"
assert_pointer "refs/heads/main" "a.md" "$md_oid" "140"
assert_local_object "$md_oid" "140"
refute_local_object "$txt_oid" "120"
refute_local_object "$md_feature_oid" "30"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
[ ! $(git cat-file -p "$feature:.gitattributes") ]
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (given branch with filter)"
(
set -e
setup_multiple_local_branches
md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
md_feature_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
git lfs migrate import --include "*.md" my-feature
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
assert_pointer "refs/heads/my-feature~1" "a.md" "$md_oid" "140"
assert_local_object "$md_oid" "140"
assert_local_object "$md_feature_oid" "30"
refute_local_object "$txt_oid" "120"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (default branch, exclude remote refs)"
(
set -e
setup_single_remote_branch
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
md_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
txt_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
git lfs migrate import
assert_pointer "refs/heads/main" "a.md" "$md_oid" "50"
assert_pointer "refs/heads/main" "a.txt" "$txt_oid" "30"
assert_local_object "$md_oid" "50"
assert_local_object "$txt_oid" "30"
refute_local_object "$md_remote_oid" "140"
refute_local_object "$txt_remote_oid" "120"
main="$(git rev-parse refs/heads/main)"
remote="$(git rev-parse refs/remotes/origin/main)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
[ ! $(git cat-file -p "$remote:.gitattributes") ]
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (given branch, exclude remote refs)"
(
set -e
setup_multiple_remote_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git lfs migrate import my-feature
assert_pointer "refs/heads/main" "a.md" "$md_main_oid" "21"
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "31"
assert_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "20"
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_feature_oid" "30"
assert_local_object "$md_feature_oid" "31"
assert_local_object "$md_main_oid" "21"
assert_local_object "$txt_feature_oid" "30"
assert_local_object "$txt_main_oid" "20"
refute_local_object "$md_remote_oid" "11"
refute_local_object "$txt_remote_oid" "10"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
remote="$(git rev-parse refs/remotes/origin/main)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
[ ! $(git cat-file -p "$remote:.gitattributes") ]
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (given ref, --skip-fetch)"
(
set -e
setup_single_remote_branch
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
git tag pseudo-remote "$(git rev-parse refs/remotes/origin/main)"
# Remove the refs/remotes/origin/main ref, and instruct 'git lfs migrate' to
# not fetch it.
git update-ref -d refs/remotes/origin/main
git lfs migrate import --skip-fetch
assert_pointer "refs/heads/main" "a.md" "$md_main_oid" "50"
assert_pointer "pseudo-remote" "a.md" "$md_remote_oid" "140"
assert_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "30"
assert_pointer "pseudo-remote" "a.txt" "$txt_remote_oid" "120"
assert_local_object "$md_main_oid" "50"
assert_local_object "$txt_main_oid" "30"
assert_local_object "$md_remote_oid" "140"
assert_local_object "$txt_remote_oid" "120"
main="$(git rev-parse refs/heads/main)"
remote="$(git rev-parse pseudo-remote)"
main_attrs="$(git cat-file -p "$main:.gitattributes")"
remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
echo "$remote_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$remote_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (un-annotated tags)"
(
set -e
setup_single_local_branch_with_tags
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
git lfs migrate import --everything
assert_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "2"
assert_local_object "$txt_main_oid" "2"
git tag --points-at "$(git rev-parse HEAD)" | grep -q "v1.0.0"
)
end_test
begin_test "migrate import (annotated tags)"
(
set -e
setup_single_local_branch_with_annotated_tags
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
git lfs migrate import --everything
assert_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "2"
assert_local_object "$txt_main_oid" "2"
git tag --points-at "$(git rev-parse HEAD)" | grep -q "v1.0.0"
)
end_test
begin_test "migrate import (include/exclude ref)"
(
set -e
setup_multiple_remote_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git lfs migrate import \
--include-ref=refs/heads/my-feature \
--exclude-ref=refs/heads/main
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "31"
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_feature_oid" "30"
assert_local_object "$md_feature_oid" "31"
refute_local_object "$md_main_oid" "21"
assert_local_object "$txt_feature_oid" "30"
refute_local_object "$txt_main_oid" "20"
refute_local_object "$md_remote_oid" "11"
refute_local_object "$txt_remote_oid" "10"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
remote="$(git rev-parse refs/remotes/origin/main)"
[ ! $(git cat-file -p "$main:.gitattributes") ]
[ ! $(git cat-file -p "$remote:.gitattributes") ]
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$feature_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (include/exclude ref args)"
(
set -e
setup_multiple_remote_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git lfs migrate import my-feature ^main
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "31"
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_feature_oid" "30"
assert_local_object "$md_feature_oid" "31"
refute_local_object "$md_main_oid" "21"
assert_local_object "$txt_feature_oid" "30"
refute_local_object "$txt_main_oid" "20"
refute_local_object "$md_remote_oid" "11"
refute_local_object "$txt_remote_oid" "10"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
remote="$(git rev-parse refs/remotes/origin/main)"
[ ! $(git cat-file -p "$main:.gitattributes") ]
[ ! $(git cat-file -p "$remote:.gitattributes") ]
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$feature_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (include/exclude ref with filter)"
(
set -e
setup_multiple_remote_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
md_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.md")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
txt_remote_oid="$(calc_oid "$(git cat-file -p "refs/remotes/origin/main:a.txt")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git lfs migrate import \
--include="*.txt" \
--include-ref=refs/heads/my-feature \
--exclude-ref=refs/heads/main
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_feature_oid" "30"
refute_local_object "$md_feature_oid" "31"
refute_local_object "$md_main_oid" "21"
assert_local_object "$txt_feature_oid" "30"
refute_local_object "$txt_main_oid" "20"
refute_local_object "$md_remote_oid" "11"
refute_local_object "$txt_remote_oid" "10"
main="$(git rev-parse refs/heads/main)"
feature="$(git rev-parse refs/heads/my-feature)"
remote="$(git rev-parse refs/remotes/origin/main)"
[ ! $(git cat-file -p "$main:.gitattributes") ]
[ ! $(git cat-file -p "$remote:.gitattributes") ]
feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
echo "$feature_attrs" | grep -vq "*.md filter=lfs diff=lfs merge=lfs"
echo "$feature_attrs" | grep -q "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (above)"
(
set -e
setup_single_local_branch_untracked
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
git lfs migrate import --above 121B
# Ensure that 'a.md', whose size is above our 121 byte threshold
# was converted into a git-lfs pointer by the migration.
assert_local_object "$md_main_oid" "140"
assert_pointer "refs/heads/main" "a.md" "$md_main_oid" "140"
refute_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "120"
refute_local_object "$txt_main_oid" "120"
# The migration should have identified that *.md files are now
# tracked because it migrated a.md
main_attrs="$(git cat-file -p "$main:.gitattributes")"
echo "$main_attrs" | grep -q "*.md filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (above without extension)"
(
set -e
setup_single_local_branch_untracked "just-b"
b_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:just-b")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
git lfs migrate import --above 121B
# Ensure that 'b', whose size is above our 121 byte threshold
# was converted into a git-lfs pointer by the migration.
assert_local_object "$b_main_oid" "140"
assert_pointer "refs/heads/main" "just-b" "$b_main_oid" "140"
refute_pointer "refs/heads/main" "a.txt" "$txt_main_oid" "120"
refute_local_object "$txt_main_oid" "120"
# The migration should have identified that /b is now tracked
# because it migrated it.
main_attrs="$(git cat-file -p "$main:.gitattributes")"
echo "$main_attrs" | grep -q "/just-b filter=lfs diff=lfs merge=lfs"
echo "$main_attrs" | grep -vq "*.txt filter=lfs diff=lfs merge=lfs"
)
end_test
begin_test "migrate import (existing .gitattributes)"
(
set -e
setup_local_branch_with_gitattrs
main="$(git rev-parse refs/heads/main)"
txt_main_oid="$(calc_oid "$(git cat-file -p "$main:a.txt")")"
git lfs migrate import --yes --include-ref=refs/heads/main --include="*.txt"
assert_local_object "$txt_main_oid" "120"
main="$(git rev-parse refs/heads/main)"
prev="$(git rev-parse refs/heads/main^1)"
diff -u <(git cat-file -p $main:.gitattributes) <(cat <<-EOF
*.txt filter=lfs diff=lfs merge=lfs -text
*.other filter=lfs diff=lfs merge=lfs -text
EOF)
diff -u <(git cat-file -p $prev:.gitattributes) <(cat <<-EOF
*.txt filter=lfs diff=lfs merge=lfs -text
EOF)
)
end_test
begin_test "migrate import (--exclude with existing .gitattributes)"
(
set -e
setup_local_branch_with_gitattrs
main="$(git rev-parse refs/heads/main)"
txt_main_oid="$(calc_oid "$(git cat-file -p "$main:a.txt")")"
git lfs migrate import --yes --include-ref=refs/heads/main --include="*.txt" --exclude="*.bin"
assert_local_object "$txt_main_oid" "120"
main="$(git rev-parse refs/heads/main)"
prev="$(git rev-parse refs/heads/main^1)"
diff -u <(git cat-file -p $main:.gitattributes) <(cat <<-EOF
*.txt filter=lfs diff=lfs merge=lfs -text
*.other filter=lfs diff=lfs merge=lfs -text
*.bin !text -filter -merge -diff
EOF)
diff -u <(git cat-file -p $prev:.gitattributes) <(cat <<-EOF
*.txt filter=lfs diff=lfs merge=lfs -text
*.bin !text -filter -merge -diff
EOF)
)
end_test
begin_test "migrate import (identical contents, different permissions)"
(
set -e
# Windows lacks POSIX permissions.
[ "$IS_WINDOWS" -eq 1 ] && exit 0
setup_multiple_local_branches
git checkout main
echo "foo" >foo.dat
git add .
git commit -m "add file"
chmod u+x foo.dat
git add .
git commit -m "make file executable"
# Verify we have executable permissions.
ls -la foo.dat | grep 'rwx'
git lfs migrate import --everything --include="*.dat"
# Verify we have executable permissions.
ls -la foo.dat | grep 'rwx'
)
end_test
begin_test "migrate import (tags with same name as branches)"
(
set -e
setup_multiple_local_branches
git checkout main
contents="hello"
oid=$(calc_oid "$contents")
printf "$contents" >hello.dat
git add .
git commit -m "add file"
git branch foo
git tag foo
git tag bar
git lfs migrate import --everything --include="*.dat"
[ "$(git rev-parse refs/heads/foo)" = "$(git rev-parse refs/tags/foo)" ]
[ "$(git rev-parse refs/heads/foo)" = "$(git rev-parse refs/tags/bar)" ]
assert_pointer "refs/heads/foo" hello.dat "$oid" 5
)
end_test
begin_test "migrate import (bare repository)"
(
set -e
setup_multiple_local_branches
make_bare
git lfs migrate import \
--include-ref=main
)
end_test
begin_test "migrate import (nested sub-trees, no filter)"
(
set -e
setup_single_local_branch_deep_trees
oid="$(calc_oid "$(git cat-file -p :foo/bar/baz/a.txt)")"
size="$(git cat-file -p :foo/bar/baz/a.txt | wc -c | awk '{ print $1 }')"
git lfs migrate import --everything
assert_local_object "$oid" "$size"
)
end_test
begin_test "migrate import (prefix include(s))"
(
set -e
includes="foo/bar/baz foo/**/baz/a.txt *.txt"
for include in $includes; do
setup_single_local_branch_deep_trees
oid="$(calc_oid "$(git cat-file -p :foo/bar/baz/a.txt)")"
git lfs migrate import --include="$include"
assert_local_object "$oid" 120
cd ..
done
)
end_test
begin_test "migrate import (--everything)"
(
set -e
setup_multiple_local_branches
git checkout main
main_txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
main_md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
feature_md_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
main_txt_size="$(git cat-file -p :a.txt | wc -c | awk '{ print $1 }')"
main_md_size="$(git cat-file -p :a.md | wc -c | awk '{ print $1 }')"
feature_md_size="$(git cat-file -p my-feature:a.md | wc -c | awk '{ print $1 }')"
git lfs migrate import --everything
assert_pointer "main" "a.txt" "$main_txt_oid" "$main_txt_size"
assert_pointer "main" "a.md" "$main_md_oid" "$main_md_size"
assert_pointer "my-feature" "a.md" "$feature_md_oid" "$feature_md_size"
)
end_test
begin_test "migrate import (ambiguous reference)"
(
set -e
setup_multiple_local_branches
# Create an ambiguously named reference sharing the name as the SHA-1 of
# "HEAD".
sha="$(git rev-parse HEAD)"
git tag "$sha"
git lfs migrate import --everything
)
end_test
begin_test "migrate import (--everything with args)"
(
set -e
setup_multiple_local_branches
[ "$(git lfs migrate import --everything main 2>&1)" = \
"fatal: cannot use --everything with explicit reference arguments" ]
)
end_test
begin_test "migrate import (--everything with --include-ref)"
(
set -e
setup_multiple_local_branches
[ "$(git lfs migrate import --everything --include-ref=refs/heads/main 2>&1)" = \
"fatal: cannot use --everything with --include-ref or --exclude-ref" ]
)
end_test
begin_test "migrate import (--everything with --exclude-ref)"
(
set -e
setup_multiple_local_branches
[ "$(git lfs migrate import --everything --exclude-ref=refs/heads/main 2>&1)" = \
"fatal: cannot use --everything with --include-ref or --exclude-ref" ]
)
end_test
begin_test "migrate import (--everything and --include with glob pattern)"
(
set -e
setup_multiple_local_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git lfs migrate import --verbose --everything --include='*.[mM][dD]'
assert_pointer "refs/heads/main" "a.md" "$md_main_oid" "140"
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
assert_local_object "$md_main_oid" "140"
assert_local_object "$md_feature_oid" "30"
refute_local_object "$txt_main_oid"
refute_local_object "$txt_feature_oid"
)
end_test
begin_test "migrate import (--everything with tag pointing to tag)"
(
set -e
setup_multiple_local_branches
md_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.md")")"
txt_main_oid="$(calc_oid "$(git cat-file -p "refs/heads/main:a.txt")")"
md_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.md")")"
txt_feature_oid="$(calc_oid "$(git cat-file -p "refs/heads/my-feature:a.txt")")"
git tag -a -m abc abc refs/heads/main
git tag -a -m def def refs/tags/abc
git lfs migrate import --verbose --everything --include='*.[mM][dD]'
assert_pointer "refs/heads/main" "a.md" "$md_main_oid" "140"
assert_pointer "refs/tags/abc" "a.md" "$md_main_oid" "140"
assert_pointer "refs/tags/def" "a.md" "$md_main_oid" "140"
assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
git tag --points-at refs/tags/abc | grep -q def
! git tag --points-at refs/tags/def | grep -q abc
assert_local_object "$md_main_oid" "140"
assert_local_object "$md_feature_oid" "30"
refute_local_object "$txt_main_oid"
refute_local_object "$txt_feature_oid"
)
end_test
begin_test "migrate import (nested sub-trees and --include with wildcard)"
(
set -e
setup_single_local_branch_deep_trees
oid="$(calc_oid "$(git cat-file -p :foo/bar/baz/a.txt)")"
size="$(git cat-file -p :foo/bar/baz/a.txt | wc -c | awk '{ print $1 }')"
git lfs migrate import --include="**/*ar/**"
assert_pointer "refs/heads/main" "foo/bar/baz/a.txt" "$oid" "$size"
assert_local_object "$oid" "$size"
)
end_test
begin_test "migrate import (handle copies of files)"
(
set -e
setup_single_local_branch_deep_trees
# add the object from the sub-tree to the root directory
cp foo/bar/baz/a.txt a.txt
git add a.txt
git commit -m "duplicated file"
oid_root="$(calc_oid "$(git cat-file -p :a.txt)")"
oid_tree="$(calc_oid "$(git cat-file -p :foo/bar/baz/a.txt)")"
size="$(git cat-file -p :foo/bar/baz/a.txt | wc -c | awk '{ print $1 }')"
# only import objects under "foo"
git lfs migrate import --include="foo/**"
assert_pointer "refs/heads/main" "foo/bar/baz/a.txt" "$oid_tree" "$size"
assert_local_object "$oid_tree" "$size"
# "a.txt" is not under "foo" and therefore should not be in LFS
oid_root_after_migration="$(calc_oid "$(git cat-file -p :a.txt)")"
[ "$oid_root" = "$oid_root_after_migration" ]
)
end_test
begin_test "migrate import (--object-map)"
(
set -e
setup_multiple_local_branches
output_dir=$(mktemp -d)
git log --all --pretty='format:%H' > "${output_dir}/old_sha.txt"
git lfs migrate import --everything --object-map "${output_dir}/object-map.txt"
git log --all --pretty='format:%H' > "${output_dir}/new_sha.txt"
paste -d',' "${output_dir}/old_sha.txt" "${output_dir}/new_sha.txt" > "${output_dir}/expected-map.txt"
diff -u <(sort "${output_dir}/expected-map.txt") <(sort "${output_dir}/object-map.txt")
)
end_test
begin_test "migrate import (--include with space)"
(
set -e
setup_local_branch_with_space
oid="$(calc_oid "$(git cat-file -p :"a file.txt")")"
git lfs migrate import --include "a file.txt"
assert_pointer "refs/heads/main" "a file.txt" "$oid" 50
cat .gitattributes
if [ 1 -ne "$(grep -c "a\[\[:space:\]\]file.txt" .gitattributes)" ]; then
echo >&2 "fatal: expected \"a[[:space:]]file.txt\" to appear in .gitattributes"
echo >&2 "fatal: got"
sed -e 's/^/ /g' < .gitattributes >&2
exit 1
fi
)
end_test
begin_test "migrate import (handle symbolic link)"
(
set -e
setup_local_branch_with_symlink
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
link_oid="$(calc_oid "$(git cat-file -p :link.txt)")"
git lfs migrate import --include="*.txt"
assert_pointer "refs/heads/main" "a.txt" "$txt_oid" "120"
assert_local_object "$txt_oid" "120"
# "link.txt" is a symbolic link so it should be not in LFS
refute_local_object "$link_oid" "5"
)
end_test
begin_test "migrate import (commit --allow-empty)"
(
set -e
reponame="migrate---allow-empty"
git init "$reponame"
cd "$reponame"
git commit --allow-empty -m "initial commit"
original_head="$(git rev-parse HEAD)"
git lfs migrate import --everything
migrated_head="$(git rev-parse HEAD)"
assert_ref_unmoved "HEAD" "$original_head" "$migrated_head"
)
end_test
begin_test "migrate import (multiple remotes)"
(
set -e
setup_multiple_remotes
original_main="$(git rev-parse main)"
git lfs migrate import
migrated_main="$(git rev-parse main)"
assert_ref_unmoved "main" "$original_main" "$migrated_main"
)
end_test
begin_test "migrate import (dirty copy, default negative answer)"
(
set -e
setup_local_branch_with_dirty_copy
original_main="$(git rev-parse main)"
echo | git lfs migrate import --everything 2>&1 | tee migrate.log
grep "migrate: working copy must not be dirty" migrate.log
migrated_main="$(git rev-parse main)"
assert_ref_unmoved "main" "$original_main" "$migrated_main"
)
end_test
begin_test "migrate import (dirty copy, negative answer)"
(
set -e
setup_local_branch_with_dirty_copy
original_main="$(git rev-parse main)"
echo "n" | git lfs migrate import --everything 2>&1 | tee migrate.log
grep "migrate: working copy must not be dirty" migrate.log
migrated_main="$(git rev-parse main)"
assert_ref_unmoved "main" "$original_main" "$migrated_main"
)
end_test
begin_test "migrate import (dirty copy, unknown then negative answer)"
(
set -e
setup_local_branch_with_dirty_copy
original_main="$(git rev-parse main)"
echo "x\nn" | git lfs migrate import --everything 2>&1 | tee migrate.log
cat migrate.log
[ "2" -eq "$(grep -o "override changes in your working copy" migrate.log \
| wc -l | awk '{ print $1 }')" ]
grep "migrate: working copy must not be dirty" migrate.log
migrated_main="$(git rev-parse main)"
assert_ref_unmoved "main" "$original_main" "$migrated_main"
)
end_test
begin_test "migrate import (dirty copy, positive answer)"
(
set -e
setup_local_branch_with_dirty_copy
oid="$(calc_oid "$(git cat-file -p :a.txt)")"
echo "y" | git lfs migrate import --everything 2>&1 | tee migrate.log
grep "migrate: changes in your working copy will be overridden ..." \
migrate.log
assert_pointer "refs/heads/main" "a.txt" "$oid" "5"
assert_local_object "$oid" "5"
)
end_test
begin_test "migrate import (non-standard refs)"
(
set -e
setup_multiple_local_branches_non_standard
md_oid="$(calc_oid "$(git cat-file -p :a.md)")"
txt_oid="$(calc_oid "$(git cat-file -p :a.txt)")"
md_feature_oid="$(calc_oid "$(git cat-file -p my-feature:a.md)")"
git lfs migrate import --everything
assert_pointer "refs/heads/main" "a.md" "$md_oid" "140"
assert_pointer "refs/heads/main" "a.txt" "$txt_oid" "120"
assert_pointer "refs/pull/1/base" "a.md" "$md_oid" "140"
assert_pointer "refs/pull/1/base" "a.txt" "$txt_oid" "120"
assert_pointer "refs/heads/my-feature" "a.txt" "$txt_oid" "120"
assert_pointer "refs/pull/1/head" "a.txt" "$txt_oid" "120"
assert_local_object "$md_oid" "140"
assert_local_object "$txt_oid" "120"
assert_local_object "$md_feature_oid" "30"
)
end_test