#!/usr/bin/env bash . "test/testlib.sh" begin_test "track" ( set -e # no need to setup a remote repo, since this test doesn't need to push or pull mkdir track cd track git init # track *.jpg once git lfs track "*.jpg" | grep "Tracking \*.jpg" assert_attributes_count "jpg" "filter=lfs" 1 # track *.jpg again git lfs track "*.jpg" | grep "*.jpg already supported" assert_attributes_count "jpg" "filter=lfs" 1 mkdir -p a/b echo "*.mov filter=lfs -text" > .git/info/attributes echo "*.gif filter=lfs -text" > a/.gitattributes echo "*.png filter=lfs -text" > a/b/.gitattributes out=$(git lfs track) echo "$out" | grep "Listing tracked patterns" echo "$out" | grep "*.mov ($(native_path_escaped ".git/info/attributes"))" echo "$out" | grep "*.jpg (.gitattributes)" echo "$out" | grep "*.gif ($(native_path_escaped "a/.gitattributes"))" echo "$out" | grep "*.png ($(native_path_escaped "a/b/.gitattributes"))" ) end_test begin_test "track --verbose" ( set -e reponame="track_verbose_logs" mkdir "$reponame" cd "$reponame" git init touch foo.dat git add foo.dat git lfs track --verbose "foo.dat" 2>&1 > track.log grep "touching foo.dat" track.log ) end_test begin_test "track --dry-run" ( set -e reponame="track_dry_run" mkdir "$reponame" cd "$reponame" git init touch foo.dat git add foo.dat git lfs track --dry-run "foo.dat" 2>&1 > track.log grep "Tracking foo.dat" track.log grep "Git LFS: touching foo.dat" track.log git status --porcelain 2>&1 > status.log grep "A foo.dat" status.log ) end_test begin_test "track directory" ( set -e mkdir dir cd dir git init git lfs track "foo bar/*" mkdir "foo bar" echo "a" > "foo bar/a" echo "b" > "foo bar/b" git add foo\ bar git commit -am "add foo bar" assert_pointer "master" "foo bar/a" "87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7" 2 assert_pointer "master" "foo bar/b" "0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f" 2 ) begin_test "track without trailing linebreak" ( set -e mkdir no-linebreak cd no-linebreak git init printf "*.mov filter=lfs -text" > .gitattributes git lfs track "*.gif" expected="*.mov filter=lfs -text$(win_cr) *.gif filter=lfs diff=lfs merge=lfs -text" if [ "$expected" != "$(cat .gitattributes)" ]; then exit 1 fi ) end_test begin_test "track outside git repo" ( set -e git lfs track "*.foo" || { # this fails if it's run outside of a git repo using GIT_LFS_TEST_DIR # git itself returns an exit status of 128 # $ git show # fatal: Not a git repository (or any of the parent directories): .git # $ echo "$?" # 128 [ "$?" = "128" ] exit 0 } if [ -n "$GIT_LFS_TEST_DIR" ]; then echo "GIT_LFS_TEST_DIR should be set outside of any Git repository" exit 1 fi git init track-outside cd track-outside git lfs track "*.file" git lfs track "../*.foo" || { # git itself returns an exit status of 128 # $ git add ../test.foo # fatal: ../test.foo: '../test.foo' is outside repository # $ echo "$?" # 128 [ "$?" = "128" ] exit 0 } exit 1 ) end_test begin_test "track representation" ( set -e git init track-representation cd track-representation git lfs track "*.jpg" mkdir a git lfs track "a/test.file" cd a out3=$(git lfs track "test.file") if [ "$out3" != "test.file already supported" ]; then echo "Track didn't recognize duplicate path" cat .gitattributes exit 1 fi git lfs track "file.bin" cd .. out4=$(git lfs track "a/file.bin") if [ "$out4" != "a/file.bin already supported" ]; then echo "Track didn't recognize duplicate path" cat .gitattributes exit 1 fi ) end_test begin_test "track absolute" ( # MinGW bash intercepts '/images' and passes 'C:/Program Files/Git/images' as arg! if [[ $(uname) == *"MINGW"* ]]; then echo "Skipping track absolute on Windows" exit 0 fi set -e git init track-absolute cd track-absolute git lfs track "/images" cat .gitattributes grep "^/images" .gitattributes ) end_test begin_test "track in gitDir" ( set -e git init track-in-dot-git cd track-in-dot-git echo "some content" > test.file cd .git git lfs track "../test.file" || { # this fails if it's run inside a .git directory # git itself returns an exit status of 128 # $ git add ../test.file # fatal: This operation must be run in a work tree # $ echo "$?" # 128 [ "$?" = "128" ] exit 0 } # fail if track passed exit 1 ) end_test begin_test "track in symlinked dir" ( set -e git init track-symlinkdst ln -s track-symlinkdst track-symlinksrc cd track-symlinksrc git lfs track "*.png" grep "^*.png" .gitattributes || { echo ".gitattributes doesn't contain the expected relative path *.png:" cat .gitattributes exit 1 } ) end_test begin_test "track blocklisted files by name" ( set -e repo="track_blocklisted_by_name" mkdir "$repo" cd "$repo" git init touch .gitattributes git add .gitattributes git lfs track .gitattributes 2>&1 > track.log grep "Pattern .gitattributes matches forbidden file .gitattributes" track.log ) end_test begin_test "track blocklisted files with glob" ( set -e repo="track_blocklisted_glob" mkdir "$repo" cd "$repo" git init touch .gitattributes git add .gitattributes git lfs track ".git*" 2>&1 > track.log grep "Pattern .git\* matches forbidden file" track.log ) end_test begin_test "track lockable" ( set -e repo="track_lockable" mkdir "$repo" cd "$repo" git init # track *.jpg once, lockable git lfs track --lockable "*.jpg" | grep "Tracking \*.jpg" assert_attributes_count "jpg" "lockable" 1 # track *.jpg again, don't change anything. Should retain lockable git lfs track "*.jpg" | grep "*.jpg already supported" assert_attributes_count "jpg" "lockable" 1 # track *.png once, not lockable yet git lfs track "*.png" | grep "Tracking \*.png" assert_attributes_count "png" "filter=lfs" 1 assert_attributes_count "png" "lockable" 0 # track png again, enable lockable, should replace git lfs track --lockable "*.png" | grep "Tracking \*.png" assert_attributes_count "png" "filter=lfs" 1 assert_attributes_count "png" "lockable" 1 # track png again, disable lockable, should replace git lfs track --not-lockable "*.png" | grep "Tracking \*.png" assert_attributes_count "png" "filter=lfs" 1 assert_attributes_count "png" "lockable" 0 # check output reflects lockable out=$(git lfs track) echo "$out" | grep "Listing tracked patterns" echo "$out" | grep "*.jpg \[lockable\] (.gitattributes)" echo "$out" | grep "*.png (.gitattributes)" ) end_test begin_test "track lockable read-only/read-write" ( set -e repo="track_lockable_ro_rw" mkdir "$repo" cd "$repo" git init echo "blah blah" > test.bin echo "foo bar" > test.dat mkdir subfolder echo "sub blah blah" > subfolder/test.bin echo "sub foo bar" > subfolder/test.dat # should start writeable [ -w test.bin ] [ -w test.dat ] [ -w subfolder/test.bin ] [ -w subfolder/test.dat ] # track *.bin, not lockable yet git lfs track "*.bin" | grep "Tracking \*.bin" # track *.dat, lockable immediately git lfs track --lockable "*.dat" | grep "Tracking \*.dat" # bin should remain writeable, dat should have been made read-only [ -w test.bin ] [ ! -w test.dat ] [ -w subfolder/test.bin ] [ ! -w subfolder/test.dat ] git add .gitattributes test.bin test.dat git commit -m "First commit" # bin should still be writeable [ -w test.bin ] [ -w subfolder/test.bin ] # now make bin lockable git lfs track --lockable "*.bin" | grep "Tracking \*.bin" # bin should now be read-only [ ! -w test.bin ] [ ! -w subfolder/test.bin ] # remove lockable again git lfs track --not-lockable "*.bin" | grep "Tracking \*.bin" # bin should now be writeable again [ -w test.bin ] [ -w subfolder/test.bin ] ) end_test