b8d97e3dd7
In commit 1ff52542da97d6418689a5528112b57e37536014 of PR #3391 we introduced the MacroProcessor type and methods to support the use of macro attributes in .gitattributes files. However, we do not currently support the case where a macro attributes is specified with a "!" prefix, which Git handles by setting all attributes defined by the macro attribute back to the unspecified state. (Note that the "-" prefix is not supported by Git for macro attributes, only the "!" one.) To mimic the same behaviour in Git LFS we add a check for a macro attribute with its Unspecified bool set to "true", and when this is detected we iterate through the set of attributes defined by the macro attribute and set them all to the same unspecified state. We also add tests to confirm this new handling works as expected, both a new Go test and a new "fsck does not detect invalid pointers with negated macro patterns" test in t/t-fsck.sh that will not succeed without the changes to the MacroProcessor in this commit. Without these changes, any patterns that reference a macro attribute with the "!" prefix are not processed as making the macro's attributes all unspecified again, and so non-pointer files matching those patterns are reported as invalid Git LFS pointers. In the new test in t/t-fsck.sh we include comments describing how the "git lfs fsck" command currently processes .gitattributes files in the order returned by "git ls-tree", and so a .gitattributes file in a subdirectory such as .dir/ will be parsed before the top-level .gitattributes one because it appears first in the "git ls-tree" output. The result is that any macro attribute references in the .dir/.gitattributes file will not be resolved properly, and so our test succeeds but not quite for the right reasons. We also add a new "macros with unspecified flag" test in the t/t-attributes.sh test script, but this test ultimately is only a placeholder as it can not actually test that the "git lfs track" command will not overwrite a pattern in a .gitattributes file in a subdirectory if it references a macro attribute defined in the top-level .gitattributes file and the reference has the "!" prefix. This is due to the fact that the "git lfs track" command parses .gitattributes files in the order of the length of their full paths, from longest to shortest, and so macro attribute references can not be resolved except within the top-level .gitattributes file (with some caveats regarding the .git/info/attributes file and the global and system attributes files). For now we defer resolution of both this issue and the one described regarding the "git lfs fsck" command to the future.
148 lines
4.2 KiB
Bash
Executable File
148 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
. "$(dirname "$0")/testlib.sh"
|
|
|
|
begin_test "macros"
|
|
(
|
|
set -e
|
|
|
|
reponame="$(basename "$0" ".sh")"
|
|
clone_repo "$reponame" repo
|
|
|
|
mkdir dir
|
|
printf '[attr]lfs filter=lfs diff=lfs merge=lfs -text\n*.dat lfs\n' \
|
|
> .gitattributes
|
|
printf '[attr]lfs2 filter=lfs diff=lfs merge=lfs -text\n*.bin lfs2\n' \
|
|
> dir/.gitattributes
|
|
git add .gitattributes dir
|
|
git commit -m 'initial import'
|
|
|
|
contents="some data"
|
|
printf "$contents" > foo.dat
|
|
git add *.dat
|
|
git commit -m 'foo.dat'
|
|
assert_local_object "$(calc_oid "$contents")" 9
|
|
|
|
contents2="other data"
|
|
printf "$contents2" > dir/foo.bin
|
|
git add dir
|
|
git commit -m 'foo.bin'
|
|
refute_local_object "$(calc_oid "$contents2")"
|
|
|
|
git lfs track '*.dat' 2>&1 | tee track.log
|
|
grep '"*.dat" already supported' track.log
|
|
|
|
cd dir
|
|
git lfs track '*.bin' 2>&1 | tee track.log
|
|
! grep '"*.bin" already supported' track.log
|
|
|
|
# NOTE: At present we do not test that "git lfs track" reports
|
|
# "already supported" when it finds a pattern in a subdirectory's
|
|
# .gitattributes file which references a macro attribute in
|
|
# the top-level .gitattributes file that sets "filter=lfs".
|
|
# This is because, while "git check-attr" resolves macro references
|
|
# from a file such as dir/.gitattributes to .gitattributess,
|
|
# "git lfs track" only resolves macro references as it reads these
|
|
# files in depth-first order, so unlike Git it does not expand an
|
|
# "lfs" reference to "filter=lfs" if it appears in dir/.gitattributes.
|
|
)
|
|
end_test
|
|
|
|
begin_test "macros with HOME"
|
|
(
|
|
set -e
|
|
|
|
reponame="$(basename "$0" ".sh")-home"
|
|
clone_repo "$reponame" repo-home
|
|
|
|
mkdir -p "$HOME/.config/git"
|
|
printf '[attr]lfs filter=lfs diff=lfs merge=lfs -text\n*.dat lfs\n' \
|
|
> "$HOME/.config/git/attributes"
|
|
|
|
contents="some data"
|
|
printf "$contents" > foo.dat
|
|
git add *.dat
|
|
git commit -m 'foo.dat'
|
|
assert_local_object "$(calc_oid "$contents")" 9
|
|
|
|
git lfs track 2>&1 | tee track.log
|
|
grep '*.dat' track.log
|
|
)
|
|
end_test
|
|
|
|
begin_test "macros with HOME split"
|
|
(
|
|
set -e
|
|
|
|
reponame="$(basename "$0" ".sh")-home-split"
|
|
clone_repo "$reponame" repo-home-split
|
|
|
|
mkdir -p "$HOME/.config/git"
|
|
printf '[attr]lfs filter=lfs diff=lfs merge=lfs -text\n' \
|
|
> "$HOME/.config/git/attributes"
|
|
|
|
printf '*.dat lfs\n' > .gitattributes
|
|
git add .gitattributes
|
|
git commit -m 'initial import'
|
|
|
|
contents="some data"
|
|
printf "$contents" > foo.dat
|
|
git add *.dat
|
|
git commit -m 'foo.dat'
|
|
assert_local_object "$(calc_oid "$contents")" 9
|
|
|
|
git lfs track '*.dat' 2>&1 | tee track.log
|
|
grep '"*.dat" already supported' track.log
|
|
)
|
|
end_test
|
|
|
|
begin_test "macros with unspecified flag"
|
|
(
|
|
set -e
|
|
|
|
reponame="$(basename "$0" ".sh")"
|
|
clone_repo "$reponame" repo-unspecified
|
|
|
|
mkdir dir
|
|
printf '[attr]lfs filter=lfs diff=lfs merge=lfs -text\n**/*.dat lfs\n' \
|
|
> .gitattributes
|
|
printf '*.dat !lfs\n' \
|
|
> dir/.gitattributes
|
|
git add .gitattributes dir
|
|
git commit -m 'initial import'
|
|
|
|
contents="some data"
|
|
printf "$contents" > foo.dat
|
|
git add *.dat
|
|
git commit -m 'foo.dat'
|
|
assert_local_object "$(calc_oid "$contents")" 9
|
|
|
|
contents2="other data"
|
|
printf "$contents2" > dir/foo.dat
|
|
git add dir
|
|
git commit -m 'dir/foo.dat'
|
|
refute_local_object "$(calc_oid "$contents2")"
|
|
|
|
git lfs track '**/*.dat' 2>&1 | tee track.log
|
|
grep '"*\*/\*.dat" already supported' track.log
|
|
|
|
# NOTE: The intent of this test is to confirm that running the
|
|
# "git lfs track '*.dat'" command in the dir/ directory returns
|
|
# "already supported", because it finds the "*.dat" pattern and
|
|
# resolves its reference to the "lfs" macro attribute in
|
|
# top-level .gitattributes file such that a "filter" attribute
|
|
# is recognized, albeit with the unspecified state set.
|
|
#
|
|
# However, as noted in the "macros" test above, because the
|
|
# "git lfs track" command parses the dir/.gitattributes file
|
|
# before the top-level .gitattributes file, it does not resolve
|
|
# the macro attribute reference, and our test would fail despite
|
|
# our ability to parse macro attribute references with a "!"
|
|
# unspecified flag character prefix.
|
|
|
|
#cd dir
|
|
#git lfs track '*.dat' 2>&1 | tee track.log
|
|
#grep '"*.dat" already supported' track.log
|
|
)
|
|
end_test
|