3 . "$(dirname "$0")/testlib.sh"
9 # no need to setup a remote repo, since this test doesn't need to push or pull
15 echo "###############################################################################
16 # Set default behavior to automatically normalize line endings.
17 ###############################################################################
20 #*.cs diff=csharp" > .gitattributes
23 git lfs track "*.jpg" | grep "Tracking \"\*.jpg\""
24 assert_attributes_count "jpg" "filter=lfs" 1
27 git lfs track "*.jpg" | grep "\"*.jpg\" already supported"
28 assert_attributes_count "jpg" "filter=lfs" 1
30 mkdir -p a/b .git/info
32 echo "*.mov filter=lfs -text" > .git/info/attributes
33 echo "*.gif filter=lfs -text" > a/.gitattributes
34 echo "*.png filter=lfs -text" > a/b/.gitattributes
36 git lfs track | tee track.log
37 grep "Listing tracked patterns" track.log
38 grep "*.mov ($(native_path_escaped ".git/info/attributes"))" track.log
39 grep "*.jpg (.gitattributes)" track.log
40 grep "*.gif ($(native_path_escaped "a/.gitattributes"))" track.log
41 grep "*.png ($(native_path_escaped "a/b/.gitattributes"))" track.log
43 grep "Set default behavior" .gitattributes
44 grep "############" .gitattributes
45 grep "* text=auto" .gitattributes
46 grep "diff=csharp" .gitattributes
47 grep "*.jpg" .gitattributes
51 begin_test "track --verbose"
55 reponame="track_verbose_logs"
63 git lfs track --verbose "foo.dat" 2>&1 > track.log
64 grep "touching \"foo.dat\"" track.log
68 begin_test "track --dry-run"
72 reponame="track_dry_run"
80 git lfs track --dry-run "foo.dat" 2>&1 > track.log
81 grep "Tracking \"foo.dat\"" track.log
82 grep "Git LFS: touching \"foo.dat\"" track.log
84 git status --porcelain 2>&1 > status.log
85 grep "A foo.dat" status.log
89 begin_test "track directory"
96 git lfs track "foo bar\\*" | tee track.txt
97 [ "foo[[:space:]]bar/* filter=lfs diff=lfs merge=lfs -text" = "$(cat .gitattributes)" ]
98 [ "Tracking \"foo bar/*\"" = "$(cat track.txt)" ]
101 echo "a" > "foo bar/a"
102 echo "b" > "foo bar/b"
104 git commit -am "add foo bar"
106 assert_pointer "master" "foo bar/a" "87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7" 2
107 assert_pointer "master" "foo bar/b" "0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f" 2
111 begin_test "track without trailing linebreak"
119 printf "*.mov filter=lfs -text" > .gitattributes
120 [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
122 git lfs track "*.gif"
123 expected="*.mov filter=lfs -text$(cat_end)
124 *.gif filter=lfs diff=lfs merge=lfs -text$(cat_end)"
125 [ "$expected" = "$(cat -e .gitattributes)" ]
129 begin_test "track with existing crlf"
137 git config core.autocrlf true
138 git lfs track "*.mov"
139 git lfs track "*.gif"
140 expected="*.mov filter=lfs diff=lfs merge=lfs -text^M$
141 *.gif filter=lfs diff=lfs merge=lfs -text^M$"
142 [ "$expected" = "$(cat -e .gitattributes)" ]
144 git config core.autocrlf false
145 git lfs track "*.jpg"
146 expected="*.mov filter=lfs diff=lfs merge=lfs -text^M$
147 *.gif filter=lfs diff=lfs merge=lfs -text^M$
148 *.jpg filter=lfs diff=lfs merge=lfs -text^M$"
149 [ "$expected" = "$(cat -e .gitattributes)" ]
153 begin_test "track with autocrlf=true"
160 git config core.autocrlf true
162 printf "*.mov filter=lfs -text" > .gitattributes
163 [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
165 git lfs track "*.gif"
166 expected="*.mov filter=lfs -text^M$
167 *.gif filter=lfs diff=lfs merge=lfs -text^M$"
168 [ "$expected" = "$(cat -e .gitattributes)" ]
172 begin_test "track with autocrlf=input"
179 git config core.autocrlf input
181 printf "*.mov filter=lfs -text" > .gitattributes
182 [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
184 git lfs track "*.gif"
185 expected="*.mov filter=lfs -text^M$
186 *.gif filter=lfs diff=lfs merge=lfs -text^M$"
187 [ "$expected" = "$(cat -e .gitattributes)" ]
191 begin_test "track outside git repo"
195 git lfs track "*.foo" || {
196 # this fails if it's run outside of a git repo using GIT_LFS_TEST_DIR
198 # git itself returns an exit status of 128
200 # fatal: Not a git repository (or any of the parent directories): .git
208 if [ -n "$GIT_LFS_TEST_DIR" ]; then
209 echo "GIT_LFS_TEST_DIR should be set outside of any Git repository"
213 git init track-outside
216 git lfs track "*.file"
218 git lfs track "../*.foo" || {
220 # git itself returns an exit status of 128
221 # $ git add ../test.foo
222 # fatal: ../test.foo: '../test.foo' is outside repository
233 begin_test "track representation"
237 git init track-representation
238 cd track-representation
240 git lfs track "*.jpg"
243 git lfs track "a/test.file"
245 out3=$(git lfs track "test.file")
247 if [ "$out3" != "\"test.file\" already supported" ]; then
248 echo "Track didn't recognize duplicate path"
253 git lfs track "file.bin"
255 out4=$(git lfs track "a/file.bin")
256 if [ "$out4" != "\"a/file.bin\" already supported" ]; then
257 echo "Track didn't recognize duplicate path"
264 begin_test "track absolute"
266 # MinGW bash intercepts '/images' and passes 'C:/Program Files/Git/images' as arg!
267 if [[ $(uname) == *"MINGW"* ]]; then
268 echo "Skipping track absolute on Windows"
274 git init track-absolute
277 git lfs track "/images"
279 grep "^/images" .gitattributes
283 begin_test "track in gitDir"
287 git init track-in-dot-git
290 echo "some content" > test.file
293 git lfs track "../test.file" || {
294 # this fails if it's run inside a .git directory
296 # git itself returns an exit status of 128
297 # $ git add ../test.file
298 # fatal: This operation must be run in a work tree
306 # fail if track passed
311 begin_test "track in symlinked dir"
315 git init track-symlinkdst
316 ln -s track-symlinkdst track-symlinksrc
319 git lfs track "*.png"
320 grep "^*.png" .gitattributes || {
321 echo ".gitattributes doesn't contain the expected relative path *.png:"
328 begin_test "track blocklisted files by name"
332 repo="track_blocklisted_by_name"
338 git add .gitattributes
340 git lfs track .gitattributes 2>&1 > track.log
341 grep "Pattern .gitattributes matches forbidden file .gitattributes" track.log
345 begin_test "track blocklisted files with glob"
349 repo="track_blocklisted_glob"
355 git add .gitattributes
357 git lfs track ".git*" 2>&1 > track.log
358 grep "Pattern .git\* matches forbidden file" track.log
362 begin_test "track lockable"
366 repo="track_lockable"
371 # track *.jpg once, lockable
372 git lfs track --lockable "*.jpg" | grep "Tracking \"\*.jpg\""
373 assert_attributes_count "jpg" "lockable" 1
374 # track *.jpg again, don't change anything. Should retain lockable
375 git lfs track "*.jpg" | grep "\"*.jpg\" already supported"
376 assert_attributes_count "jpg" "lockable" 1
379 # track *.png once, not lockable yet
380 git lfs track "*.png" | grep "Tracking \"\*.png\""
381 assert_attributes_count "png" "filter=lfs" 1
382 assert_attributes_count "png" "lockable" 0
384 # track png again, enable lockable, should replace
385 git lfs track --lockable "*.png" | grep "Tracking \"\*.png\""
386 assert_attributes_count "png" "filter=lfs" 1
387 assert_attributes_count "png" "lockable" 1
389 # track png again, disable lockable, should replace
390 git lfs track --not-lockable "*.png" | grep "Tracking \"\*.png\""
391 assert_attributes_count "png" "filter=lfs" 1
392 assert_attributes_count "png" "lockable" 0
394 # check output reflects lockable
396 echo "$out" | grep "Listing tracked patterns"
397 echo "$out" | grep "*.jpg \[lockable\] (.gitattributes)"
398 echo "$out" | grep "*.png (.gitattributes)"
402 begin_test "track lockable read-only/read-write"
406 repo="track_lockable_ro_rw"
411 echo "blah blah" > test.bin
412 echo "foo bar" > test.dat
414 echo "sub blah blah" > subfolder/test.bin
415 echo "sub foo bar" > subfolder/test.dat
416 # should start writeable
417 assert_file_writeable test.bin
418 assert_file_writeable test.dat
419 assert_file_writeable subfolder/test.bin
420 assert_file_writeable subfolder/test.dat
422 # track *.bin, not lockable yet
423 git lfs track "*.bin" | grep "Tracking \"\*.bin\""
424 # track *.dat, lockable immediately
425 git lfs track --lockable "*.dat" | grep "Tracking \"\*.dat\""
427 # bin should remain writeable, dat should have been made read-only
429 assert_file_writeable test.bin
430 refute_file_writeable test.dat
431 assert_file_writeable subfolder/test.bin
432 refute_file_writeable subfolder/test.dat
434 git add .gitattributes test.bin test.dat
435 git commit -m "First commit"
437 # bin should still be writeable
438 assert_file_writeable test.bin
439 assert_file_writeable subfolder/test.bin
440 # now make bin lockable
441 git lfs track --lockable "*.bin" | grep "Tracking \"\*.bin\""
442 # bin should now be read-only
443 refute_file_writeable test.bin
444 refute_file_writeable subfolder/test.bin
446 # remove lockable again
447 git lfs track --not-lockable "*.bin" | grep "Tracking \"\*.bin\""
448 # bin should now be writeable again
449 assert_file_writeable test.bin
450 assert_file_writeable subfolder/test.bin
454 begin_test "track escaped pattern"
458 reponame="track-escaped-pattern"
462 git lfs track " " | grep "Tracking \" \""
463 assert_attributes_count "[[:space:]]" "filter=lfs" 1
465 git lfs track "#" | grep "Tracking \"#\""
466 assert_attributes_count "\\#" "filter=lfs" 1
470 begin_test "track (symlinked repository)"
474 reponame="tracked-symlinked-repository"
481 dir="tracked-symlinked-repository-tmp"
485 ln -s "../$reponame" "./$dir"
489 [ "Tracking \"a.dat\"" = "$(git lfs track "a.dat")" ]
490 [ "\"a.dat\" already supported" = "$(git lfs track "a.dat")" ]
495 begin_test "track (\$GIT_LFS_TRACK_NO_INSTALL_HOOKS)"
499 reponame="track-no-setup-hooks"
503 [ ! -f .git/hooks/pre-push ]
504 [ ! -f .git/hooks/post-checkout ]
505 [ ! -f .git/hooks/post-commit ]
506 [ ! -f .git/hooks/post-merge ]
508 GIT_LFS_TRACK_NO_INSTALL_HOOKS=1 git lfs track
510 [ ! -f .git/hooks/pre-push ]
511 [ ! -f .git/hooks/post-checkout ]
512 [ ! -f .git/hooks/post-commit ]
513 [ ! -f .git/hooks/post-merge ]
517 begin_test "track (with comments)"
521 reponame="track-with=comments"
525 echo "*.jpg filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
526 echo "# *.png filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
527 echo "*.pdf filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
529 git add .gitattributes
530 git commit -m "initial commit"
532 git lfs track 2>&1 | tee track.log
533 if [ "0" -ne "${PIPESTATUS[0]}" ]; then
534 echo >&2 "expected \`git lfs track\` command to exit cleanly, didn't"
538 [ "1" -eq "$(grep -c "\.jpg" track.log)" ]
539 [ "1" -eq "$(grep -c "\.pdf" track.log)" ]
540 [ "0" -eq "$(grep -c "\.png" track.log)" ]
544 begin_test "track (with current-directory prefix)"
548 reponame="track-with-current-directory-prefix"
552 git lfs track "./a.dat"
555 git add .gitattributes a.dat
556 git commit -m "initial commit"
558 grep -e "^a.dat" .gitattributes
562 begin_test "track (global gitattributes)"
566 reponame="track-global-gitattributes"
570 global="$(cd .. && pwd)/gitattributes-global"
572 echo "*.dat filter=lfs diff=lfs merge=lfs -text" > "$global"
573 git config --local core.attributesfile "$global"
575 git lfs track 2>&1 | tee track.log
576 grep "*.dat" track.log
580 begin_test "track (system gitattributes)"
584 reponame="track-system-gitattributes"
588 pushd "$TRASHDIR" > /dev/null
589 mkdir -p "prefix/${reponame}/etc"
590 cd "prefix/${reponame}/etc"
591 echo "*.dat filter=lfs diff=lfs merge=lfs -text" > gitattributes
594 PREFIX="${TRASHDIR}/prefix/${reponame}" git lfs track 2>&1 | tee track.log
595 grep "*.dat" track.log