Imported Upstream version 2.5.1
[scm/test.git] / t / t-track.sh
1 #!/usr/bin/env bash
2
3 . "$(dirname "$0")/testlib.sh"
4
5 begin_test "track"
6 (
7   set -e
8
9   # no need to setup a remote repo, since this test doesn't need to push or pull
10
11   mkdir track
12   cd track
13   git init
14
15   echo "###############################################################################
16 # Set default behavior to automatically normalize line endings.
17 ###############################################################################
18 * text=auto
19
20 #*.cs     diff=csharp" > .gitattributes
21
22   # track *.jpg once
23   git lfs track "*.jpg" | grep "Tracking \"\*.jpg\""
24   assert_attributes_count "jpg" "filter=lfs" 1
25
26   # track *.jpg again
27   git lfs track "*.jpg" | grep "\"*.jpg\" already supported"
28   assert_attributes_count "jpg" "filter=lfs" 1
29
30   mkdir -p a/b .git/info
31
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
35
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
42
43   grep "Set default behavior" .gitattributes
44   grep "############" .gitattributes
45   grep "* text=auto" .gitattributes
46   grep "diff=csharp" .gitattributes
47   grep "*.jpg" .gitattributes
48 )
49 end_test
50
51 begin_test "track --verbose"
52 (
53   set -e
54
55   reponame="track_verbose_logs"
56   mkdir "$reponame"
57   cd "$reponame"
58   git init
59
60   touch foo.dat
61   git add foo.dat
62
63   git lfs track --verbose "foo.dat" 2>&1 > track.log
64   grep "touching \"foo.dat\"" track.log
65 )
66 end_test
67
68 begin_test "track --dry-run"
69 (
70   set -e
71
72   reponame="track_dry_run"
73   mkdir "$reponame"
74   cd "$reponame"
75   git init
76
77   touch foo.dat
78   git add foo.dat
79
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
83
84   git status --porcelain 2>&1 > status.log
85   grep "A  foo.dat" status.log
86 )
87 end_test
88
89 begin_test "track directory"
90 (
91   set -e
92   mkdir dir
93   cd dir
94   git init
95
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)" ]
99
100   mkdir "foo bar"
101   echo "a" > "foo bar/a"
102   echo "b" > "foo bar/b"
103   git add foo\ bar
104   git commit -am "add foo bar"
105
106   assert_pointer "master" "foo bar/a" "87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7" 2
107   assert_pointer "master" "foo bar/b" "0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f" 2
108 )
109 end_test
110
111 begin_test "track without trailing linebreak"
112 (
113   set -e
114
115   mkdir no-linebreak
116   cd no-linebreak
117   git init
118
119   printf "*.mov filter=lfs -text" > .gitattributes
120   [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
121
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)" ]
126 )
127 end_test
128
129 begin_test "track with existing crlf"
130 (
131   set -e
132
133   mkdir existing-crlf
134   cd existing-crlf
135   git init
136
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)" ]
143
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)" ]
150 )
151 end_test
152
153 begin_test "track with autocrlf=true"
154 (
155   set -e
156
157   mkdir autocrlf-true
158   cd autocrlf-true
159   git init
160   git config core.autocrlf true
161
162   printf "*.mov filter=lfs -text" > .gitattributes
163   [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
164
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)" ]
169 )
170 end_test
171
172 begin_test "track with autocrlf=input"
173 (
174   set -e
175
176   mkdir autocrlf-input
177   cd autocrlf-input
178   git init
179   git config core.autocrlf input
180
181   printf "*.mov filter=lfs -text" > .gitattributes
182   [ "*.mov filter=lfs -text" = "$(cat .gitattributes)" ]
183
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)" ]
188 )
189 end_test
190
191 begin_test "track outside git repo"
192 (
193   set -e
194
195   git lfs track "*.foo" || {
196     # this fails if it's run outside of a git repo using GIT_LFS_TEST_DIR
197
198     # git itself returns an exit status of 128
199     # $ git show
200     # fatal: Not a git repository (or any of the parent directories): .git
201     # $ echo "$?"
202     # 128
203
204     [ "$?" = "128" ]
205     exit 0
206   }
207
208   if [ -n "$GIT_LFS_TEST_DIR" ]; then
209     echo "GIT_LFS_TEST_DIR should be set outside of any Git repository"
210     exit 1
211   fi
212
213   git init track-outside
214   cd track-outside
215
216   git lfs track "*.file"
217
218   git lfs track "../*.foo" || {
219
220     # git itself returns an exit status of 128
221     # $ git add ../test.foo
222     # fatal: ../test.foo: '../test.foo' is outside repository
223     # $ echo "$?"
224     # 128
225
226     [ "$?" = "128" ]
227     exit 0
228   }
229   exit 1
230 )
231 end_test
232
233 begin_test "track representation"
234 (
235   set -e
236
237   git init track-representation
238   cd track-representation
239
240   git lfs track "*.jpg"
241
242   mkdir a
243   git lfs track "a/test.file"
244   cd a
245   out3=$(git lfs track "test.file")
246
247   if [ "$out3" != "\"test.file\" already supported" ]; then
248     echo "Track didn't recognize duplicate path"
249     cat .gitattributes
250     exit 1
251   fi
252
253   git lfs track "file.bin"
254   cd ..
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"
258     cat .gitattributes
259     exit 1
260   fi
261 )
262 end_test
263
264 begin_test "track absolute"
265 (
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"
269     exit 0
270   fi
271
272   set -e
273
274   git init track-absolute
275   cd track-absolute
276
277   git lfs track "/images"
278   cat .gitattributes
279   grep "^/images" .gitattributes
280 )
281 end_test
282
283 begin_test "track in gitDir"
284 (
285   set -e
286
287   git init track-in-dot-git
288   cd track-in-dot-git
289
290   echo "some content" > test.file
291
292   cd .git
293   git lfs track "../test.file" || {
294     # this fails if it's run inside a .git directory
295
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
299     # $ echo "$?"
300     # 128
301
302         [ "$?" = "128" ]
303         exit 0
304   }
305
306   # fail if track passed
307   exit 1
308 )
309 end_test
310
311 begin_test "track in symlinked dir"
312 (
313   set -e
314
315   git init track-symlinkdst
316   ln -s track-symlinkdst track-symlinksrc
317   cd track-symlinksrc
318
319   git lfs track "*.png"
320   grep "^*.png" .gitattributes || {
321     echo ".gitattributes doesn't contain the expected relative path *.png:"
322     cat .gitattributes
323     exit 1
324   }
325 )
326 end_test
327
328 begin_test "track blocklisted files by name"
329 (
330   set -e
331
332   repo="track_blocklisted_by_name"
333   mkdir "$repo"
334   cd "$repo"
335   git init
336
337   touch .gitattributes
338   git add .gitattributes
339
340   git lfs track .gitattributes 2>&1 > track.log
341   grep "Pattern .gitattributes matches forbidden file .gitattributes" track.log
342 )
343 end_test
344
345 begin_test "track blocklisted files with glob"
346 (
347   set -e
348
349   repo="track_blocklisted_glob"
350   mkdir "$repo"
351   cd "$repo"
352   git init
353
354   touch .gitattributes
355   git add .gitattributes
356
357   git lfs track ".git*" 2>&1 > track.log
358   grep "Pattern .git\* matches forbidden file" track.log
359 )
360 end_test
361
362 begin_test "track lockable"
363 (
364   set -e
365
366   repo="track_lockable"
367   mkdir "$repo"
368   cd "$repo"
369   git init
370
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
377
378
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
383
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
388
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
393
394   # check output reflects lockable
395   out=$(git lfs track)
396   echo "$out" | grep "Listing tracked patterns"
397   echo "$out" | grep "*.jpg \[lockable\] (.gitattributes)"
398   echo "$out" | grep "*.png (.gitattributes)"
399 )
400 end_test
401
402 begin_test "track lockable read-only/read-write"
403 (
404   set -e
405
406   repo="track_lockable_ro_rw"
407   mkdir "$repo"
408   cd "$repo"
409   git init
410
411   echo "blah blah" > test.bin
412   echo "foo bar" > test.dat
413   mkdir subfolder
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
421
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\""
426
427   # bin should remain writeable, dat should have been made read-only
428
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
433
434   git add .gitattributes test.bin test.dat
435   git commit -m "First commit"
436
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
445
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
451 )
452 end_test
453
454 begin_test "track escaped pattern"
455 (
456   set -e
457
458   reponame="track-escaped-pattern"
459   git init "$reponame"
460   cd "$reponame"
461
462   git lfs track " " | grep "Tracking \" \""
463   assert_attributes_count "[[:space:]]" "filter=lfs" 1
464
465   git lfs track "#" | grep "Tracking \"#\""
466   assert_attributes_count "\\#" "filter=lfs" 1
467 )
468 end_test
469
470 begin_test "track (symlinked repository)"
471 (
472   set -e
473
474   reponame="tracked-symlinked-repository"
475   git init "$reponame"
476   cd "$reponame"
477
478   touch a.dat
479
480   pushd .. > /dev/null
481     dir="tracked-symlinked-repository-tmp"
482
483     mkdir -p "$dir"
484
485     ln -s "../$reponame" "./$dir"
486
487     cd "$dir/$reponame"
488
489     [ "Tracking \"a.dat\"" = "$(git lfs track "a.dat")" ]
490     [ "\"a.dat\" already supported" = "$(git lfs track "a.dat")" ]
491   popd > /dev/null
492 )
493 end_test
494
495 begin_test "track (\$GIT_LFS_TRACK_NO_INSTALL_HOOKS)"
496 (
497   set -e
498
499   reponame="track-no-setup-hooks"
500   git init "$reponame"
501   cd "$reponame"
502
503   [ ! -f .git/hooks/pre-push ]
504   [ ! -f .git/hooks/post-checkout ]
505   [ ! -f .git/hooks/post-commit ]
506   [ ! -f .git/hooks/post-merge ]
507
508   GIT_LFS_TRACK_NO_INSTALL_HOOKS=1 git lfs track
509
510   [ ! -f .git/hooks/pre-push ]
511   [ ! -f .git/hooks/post-checkout ]
512   [ ! -f .git/hooks/post-commit ]
513   [ ! -f .git/hooks/post-merge ]
514 )
515 end_test
516
517 begin_test "track (with comments)"
518 (
519   set -e
520
521   reponame="track-with=comments"
522   git init "$reponame"
523   cd "$reponame"
524
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
528
529   git add .gitattributes
530   git commit -m "initial commit"
531
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"
535     exit 1
536   fi
537
538   [ "1" -eq "$(grep -c "\.jpg" track.log)" ]
539   [ "1" -eq "$(grep -c "\.pdf" track.log)" ]
540   [ "0" -eq "$(grep -c "\.png" track.log)" ]
541 )
542 end_test
543
544 begin_test "track (with current-directory prefix)"
545 (
546   set -e
547
548   reponame="track-with-current-directory-prefix"
549   git init "$reponame"
550   cd "$reponame"
551
552   git lfs track "./a.dat"
553   printf "a" > a.dat
554
555   git add .gitattributes a.dat
556   git commit -m "initial commit"
557
558   grep -e "^a.dat" .gitattributes
559 )
560 end_test
561
562 begin_test "track (global gitattributes)"
563 (
564   set -e
565
566   reponame="track-global-gitattributes"
567   git init "$reponame"
568   cd "$reponame"
569
570   global="$(cd .. && pwd)/gitattributes-global"
571
572   echo "*.dat filter=lfs diff=lfs merge=lfs -text" > "$global"
573   git config --local core.attributesfile "$global"
574
575   git lfs track 2>&1 | tee track.log
576   grep "*.dat" track.log
577 )
578 end_test
579
580 begin_test "track (system gitattributes)"
581 (
582   set -e
583
584   reponame="track-system-gitattributes"
585   git init "$reponame"
586   cd "$reponame"
587
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
592   popd > /dev/null
593
594   PREFIX="${TRASHDIR}/prefix/${reponame}" git lfs track 2>&1 | tee track.log
595   grep "*.dat" track.log
596 )
597 end_test