Imported Upstream version 2.5.0
[scm/test.git] / t / t-clone.sh
1 #!/usr/bin/env bash
2
3 . "$(dirname "$0")/testlib.sh"
4
5 ensure_git_version_isnt $VERSION_LOWER "2.2.0"
6
7 begin_test "clone"
8 (
9   set -e
10
11   reponame="$(basename "$0" ".sh")"
12   setup_remote_repo "$reponame"
13   clone_repo "$reponame" repo
14
15   git lfs track "*.dat" 2>&1 | tee track.log
16   grep "Tracking \"\*.dat\"" track.log
17
18   # generate some test data & commits with random LFS data
19   echo "[
20   {
21     \"CommitDate\":\"$(get_date -10d)\",
22     \"Files\":[
23       {\"Filename\":\"file1.dat\",\"Size\":100},
24       {\"Filename\":\"file2.dat\",\"Size\":75}]
25   },
26   {
27     \"CommitDate\":\"$(get_date -7d)\",
28     \"Files\":[
29       {\"Filename\":\"file1.dat\",\"Size\":110},
30       {\"Filename\":\"file3.dat\",\"Size\":66},
31       {\"Filename\":\"file4.dat\",\"Size\":23}]
32   },
33   {
34     \"CommitDate\":\"$(get_date -10d)\",
35     \"Files\":[
36       {\"Filename\":\"file5.dat\",\"Size\":120},
37       {\"Filename\":\"file6.dat\",\"Size\":30}]
38   }
39   ]" | lfstest-testutils addcommits
40
41   git push origin master
42
43   # Now clone again, test specific clone dir
44   cd "$TRASHDIR"
45
46   newclonedir="testclone1"
47   git lfs clone "$GITSERVER/$reponame" "$newclonedir" 2>&1 | tee lfsclone.log
48   grep "Cloning into" lfsclone.log
49   grep "Downloading LFS objects:" lfsclone.log
50   # should be no filter errors
51   [ ! $(grep "filter" lfsclone.log) ]
52   [ ! $(grep "error" lfsclone.log) ]
53   # should be cloned into location as per arg
54   [ -d "$newclonedir" ]
55
56   # check a few file sizes to make sure pulled
57   pushd "$newclonedir"
58     [ $(wc -c < "file1.dat") -eq 110 ]
59     [ $(wc -c < "file2.dat") -eq 75 ]
60     [ $(wc -c < "file3.dat") -eq 66 ]
61     assert_hooks "$(dot_git_dir)"
62     [ ! -e "lfs" ]
63     assert_clean_status
64   popd
65
66   # Now check clone with implied dir
67   rm -rf "$reponame"
68   git lfs clone "$GITSERVER/$reponame" 2>&1 | tee lfsclone.log
69   grep "Cloning into" lfsclone.log
70   grep "Downloading LFS objects:" lfsclone.log
71   # should be no filter errors
72   [ ! $(grep "filter" lfsclone.log) ]
73   [ ! $(grep "error" lfsclone.log) ]
74   # clone location should be implied
75   [ -d "$reponame" ]
76
77   pushd "$reponame"
78     [ $(wc -c < "file1.dat") -eq 110 ]
79     [ $(wc -c < "file2.dat") -eq 75 ]
80     [ $(wc -c < "file3.dat") -eq 66 ]
81     assert_hooks "$(dot_git_dir)"
82     [ ! -e "lfs" ]
83     assert_clean_status
84   popd
85
86 )
87 end_test
88
89 begin_test "cloneSSL"
90 (
91   set -e
92   if $TRAVIS; then
93     echo "Skipping SSL tests, Travis has weird behaviour in validating custom certs, test locally only"
94     exit 0
95   fi
96
97   reponame="test-cloneSSL"
98   setup_remote_repo "$reponame"
99   clone_repo_ssl "$reponame" "$reponame"
100
101   git lfs track "*.dat" 2>&1 | tee track.log
102   grep "Tracking \"\*.dat\"" track.log
103
104   # generate some test data & commits with random LFS data
105   echo "[
106   {
107     \"CommitDate\":\"$(get_date -5d)\",
108     \"Files\":[
109       {\"Filename\":\"file1.dat\",\"Size\":100},
110       {\"Filename\":\"file2.dat\",\"Size\":75}]
111   },
112   {
113     \"CommitDate\":\"$(get_date -1d)\",
114     \"Files\":[
115       {\"Filename\":\"file3.dat\",\"Size\":30}]
116   }
117   ]" | lfstest-testutils addcommits
118
119   git push origin master
120
121   # Now SSL clone again with 'git lfs clone', test specific clone dir
122   cd "$TRASHDIR"
123
124   newclonedir="testcloneSSL1"
125   git lfs clone "$SSLGITSERVER/$reponame" "$newclonedir" 2>&1 | tee lfsclone.log
126   assert_clean_status
127   grep "Cloning into" lfsclone.log
128   grep "Git LFS:" lfsclone.log
129   # should be no filter errors
130   [ ! $(grep "filter" lfsclone.log) ]
131   [ ! $(grep "error" lfsclone.log) ]
132   # should be cloned into location as per arg
133   [ -d "$newclonedir" ]
134
135   # check a few file sizes to make sure pulled
136   pushd "$newclonedir"
137   [ $(wc -c < "file1.dat") -eq 100 ]
138   [ $(wc -c < "file2.dat") -eq 75 ]
139   [ $(wc -c < "file3.dat") -eq 30 ]
140   assert_hooks "$(dot_git_dir)"
141   popd
142
143
144   # Now check SSL clone with standard 'git clone' and smudge download
145   rm -rf "$reponame"
146   git clone "$SSLGITSERVER/$reponame"
147 )
148 end_test
149
150 begin_test "clone ClientCert"
151 (
152   set -e
153   reponame="test-cloneClientCert"
154   setup_remote_repo "$reponame"
155   clone_repo_clientcert "$reponame" "$reponame"
156   if [ $(grep -c "client-cert-mac-openssl" clone_client_cert.log) -gt 0 ]; then
157     echo "Skipping due to SSL client cert bug in Git"
158     exit 0
159   fi
160
161   git lfs track "*.dat" 2>&1 | tee track.log
162   grep "Tracking \"\*.dat\"" track.log
163
164   # generate some test data & commits with random LFS data
165   echo "[
166   {
167     \"CommitDate\":\"$(get_date -5d)\",
168     \"Files\":[
169       {\"Filename\":\"file1.dat\",\"Size\":100},
170       {\"Filename\":\"file2.dat\",\"Size\":75}]
171   },
172   {
173     \"CommitDate\":\"$(get_date -1d)\",
174     \"Files\":[
175       {\"Filename\":\"file3.dat\",\"Size\":30}]
176   }
177   ]" | lfstest-testutils addcommits
178
179   git push origin master
180
181   # Now clone again with 'git lfs clone', test specific clone dir
182   cd "$TRASHDIR"
183
184   newclonedir="testcloneClietCert1"
185   git lfs clone "$CLIENTCERTGITSERVER/$reponame" "$newclonedir" 2>&1 | tee lfsclone.log
186   grep "Cloning into" lfsclone.log
187   grep "Git LFS:" lfsclone.log
188   # should be no filter errors
189   [ ! $(grep "filter" lfsclone.log) ]
190   [ ! $(grep "error" lfsclone.log) ]
191   # should be cloned into location as per arg
192   [ -d "$newclonedir" ]
193
194   # check a few file sizes to make sure pulled
195   pushd "$newclonedir"
196     [ $(wc -c < "file1.dat") -eq 100 ]
197     [ $(wc -c < "file2.dat") -eq 75 ]
198     [ $(wc -c < "file3.dat") -eq 30 ]
199     assert_hooks "$(dot_git_dir)"
200     assert_clean_status
201   popd
202
203
204   # Now check SSL clone with standard 'git clone' and smudge download
205   rm -rf "$reponame"
206   git clone "$CLIENTCERTGITSERVER/$reponame"
207
208 )
209 end_test
210
211 begin_test "clone with flags"
212 (
213   set -e
214
215   reponame="$(basename "$0" ".sh")-flags"
216   setup_remote_repo "$reponame"
217   clone_repo "$reponame" "$reponame"
218
219   git lfs track "*.dat" 2>&1 | tee track.log
220   grep "Tracking \"\*.dat\"" track.log
221
222   # generate some test data & commits with random LFS data
223   echo "[
224   {
225     \"CommitDate\":\"$(get_date -10d)\",
226     \"Files\":[
227       {\"Filename\":\"file1.dat\",\"Size\":100},
228       {\"Filename\":\"file2.dat\",\"Size\":75}]
229   },
230   {
231     \"CommitDate\":\"$(get_date -7d)\",
232     \"NewBranch\":\"branch2\",
233     \"Files\":[
234       {\"Filename\":\"fileonbranch2.dat\",\"Size\":66}]
235   },
236   {
237     \"CommitDate\":\"$(get_date -3d)\",
238     \"ParentBranches\":[\"master\"],
239     \"Files\":[
240       {\"Filename\":\"file3.dat\",\"Size\":120},
241       {\"Filename\":\"file4.dat\",\"Size\":30}]
242   }
243   ]" | lfstest-testutils addcommits
244
245   git push origin master branch2
246
247   # Now clone again, test specific clone dir
248   cd "$TRASHDIR"
249   mkdir "$TRASHDIR/templatedir"
250
251   newclonedir="testflagsclone1"
252   # many of these flags won't do anything but make sure they're not rejected
253   git lfs clone --template "$TRASHDIR/templatedir" --local --no-hardlinks --shared --verbose --progress --recursive "$GITSERVER/$reponame" "$newclonedir"
254   rm -rf "$newclonedir"
255
256   # specific test for --no-checkout
257   git lfs clone --quiet --no-checkout "$GITSERVER/$reponame" "$newclonedir"
258   if [ -e "$newclonedir/file1.dat" ]; then
259     exit 1
260   fi
261   rm -rf "$newclonedir"
262
263   # specific test for --branch and --origin
264   git lfs clone --branch branch2 --recurse-submodules --origin differentorigin "$GITSERVER/$reponame" "$newclonedir"
265   pushd "$newclonedir"
266   # this file is only on branch2
267   [ -e "fileonbranch2.dat" ]
268   # confirm remote is called differentorigin
269   git remote get-url differentorigin
270   assert_hooks "$(dot_git_dir)"
271   popd
272   rm -rf "$newclonedir"
273
274   # specific test for --separate-git-dir
275   gitdir="$TRASHDIR/separategitdir"
276   git lfs clone --separate-git-dir "$gitdir" "$GITSERVER/$reponame" "$newclonedir"
277   # .git should be a file not dir
278   if [ -d "$newclonedir/.git" ]; then
279     exit 1
280   fi
281   [ -e "$newclonedir/.git" ]
282   [ -d "$gitdir/objects" ]
283   assert_hooks "$gitdir"
284   rm -rf "$newclonedir"
285   rm -rf "$gitdir"
286
287   # specific test for --bare
288   git lfs clone --bare "$GITSERVER/$reponame" "$newclonedir"
289   [ -d "$newclonedir/objects" ]
290   rm -rf "$newclonedir"
291
292   # short flags
293   git lfs clone -l -v -n -s -b branch2 "$GITSERVER/$reponame" "$newclonedir"
294   rm -rf "$newclonedir"
295 )
296 end_test
297
298 begin_test "clone (with include/exclude args)"
299 (
300   set -e
301
302   reponame="clone_include_exclude"
303   setup_remote_repo "$reponame"
304   clone_repo "$reponame" "$reponame"
305
306   git lfs track "*.dat" 2>&1 | tee track.log
307   grep "Tracking \"\*.dat\"" track.log
308
309   contents_a="a"
310   contents_a_oid=$(calc_oid "$contents_a")
311   printf "$contents_a" > "a.dat"
312   printf "$contents_a" > "a-dupe.dat"
313   printf "$contents_a" > "dupe-a.dat"
314
315   contents_b="b"
316   contents_b_oid=$(calc_oid "$contents_b")
317   printf "$contents_b" > "b.dat"
318
319   git add *.dat .gitattributes
320   git commit -m "add a.dat, b.dat" 2>&1 | tee commit.log
321   grep "master (root-commit)" commit.log
322   grep "5 files changed" commit.log
323   grep "create mode 100644 a.dat" commit.log
324   grep "create mode 100644 a-dupe.dat" commit.log
325   grep "create mode 100644 dupe-a.dat" commit.log
326   grep "create mode 100644 b.dat" commit.log
327   grep "create mode 100644 .gitattributes" commit.log
328
329   git push origin master 2>&1 | tee push.log
330   grep "master -> master" push.log
331   grep "Uploading LFS objects: 100% (2/2), 2 B" push.log
332
333   cd "$TRASHDIR"
334
335   local_reponame="clone_with_includes"
336   git lfs clone "$GITSERVER/$reponame" "$local_reponame" -I "a*.dat"
337   pushd "$local_reponame"
338   assert_local_object "$contents_a_oid" 1
339   refute_local_object "$contents_b_oid"
340   [ "a" = "$(cat a.dat)" ]
341   [ "a" = "$(cat a-dupe.dat)" ]
342   [ "$(pointer $contents_a_oid 1)" = "$(cat dupe-a.dat)" ]
343   [ "$(pointer $contents_b_oid 1)" = "$(cat b.dat)" ]
344   assert_hooks "$(dot_git_dir)"
345   popd
346
347   local_reponame="clone_with_excludes"
348   git lfs clone "$GITSERVER/$reponame" "$local_reponame" -I "b.dat" -X "a.dat"
349   pushd "$local_reponame"
350   assert_local_object "$contents_b_oid" 1
351   refute_local_object "$contents_a_oid"
352   [ "$(pointer $contents_a_oid 1)" = "$(cat a.dat)" ]
353   [ "b" = "$(cat b.dat)" ]
354   assert_hooks "$(dot_git_dir)"
355   popd
356 )
357 end_test
358
359 begin_test "clone (with .lfsconfig)"
360 (
361   set -e
362
363   reponame="clone_with_lfsconfig"
364   setup_remote_repo "$reponame"
365   clone_repo "$reponame" "$reponame"
366
367   git lfs track "*.dat" 2>&1 | tee track.log
368   grep "Tracking \"\*.dat\"" track.log
369
370   contents_a="a"
371   contents_a_oid=$(calc_oid "$contents_a")
372   printf "$contents_a" > "a.dat"
373
374   contents_b="b"
375   contents_b_oid=$(calc_oid "$contents_b")
376   printf "$contents_b" > "b.dat"
377
378   git add a.dat b.dat .gitattributes
379   git commit -m "add a.dat, b.dat" 2>&1 | tee commit.log
380   grep "master (root-commit)" commit.log
381   grep "3 files changed" commit.log
382   grep "create mode 100644 a.dat" commit.log
383   grep "create mode 100644 b.dat" commit.log
384   grep "create mode 100644 .gitattributes" commit.log
385
386   git config -f ".lfsconfig" "lfs.fetchinclude" "a*"
387   git add ".lfsconfig"
388   git commit -m "config lfs.fetchinclude a*" 2>&1 | tee commit.log
389   grep "master" commit.log
390   grep "1 file changed" commit.log
391   grep "create mode 100644 .lfsconfig" commit.log
392
393   git push origin master 2>&1 | tee push.log
394   grep "master -> master" push.log
395   grep "Uploading LFS objects: 100% (2/2), 2 B" push.log
396
397   pushd "$TRASHDIR"
398
399   echo "test: clone with lfs.fetchinclude in .lfsconfig"
400   local_reponame="clone_with_config_include"
401   set +x
402   git lfs clone "$GITSERVER/$reponame" "$local_reponame"
403   ok="$?"
404   set -x
405   if [ "0" -ne "$ok" ]; then
406     # TEMP: used to catch transient failure from above `clone` command, as in:
407     # https://github.com/git-lfs/git-lfs/pull/1782#issuecomment-267678319
408     echo >&2 "[!] \`git lfs clone $GITSERVER/$reponame $local_reponame\` failed"
409     git lfs logs last
410
411     exit 1
412   fi
413   pushd "$local_reponame"
414   assert_local_object "$contents_a_oid" 1
415   refute_local_object "$contents_b_oid"
416   assert_hooks "$(dot_git_dir)"
417   popd
418
419   echo "test: clone with lfs.fetchinclude in .lfsconfig, and args"
420   local_reponame="clone_with_config_include_and_args"
421   git lfs clone "$GITSERVER/$reponame" "$local_reponame" -I "b.dat"
422   pushd "$local_reponame"
423   refute_local_object "$contents_a_oid"
424   assert_local_object "$contents_b_oid" 1
425   assert_hooks "$(dot_git_dir)"
426   popd
427
428   popd
429
430   git config -f ".lfsconfig" "lfs.fetchinclude" "b*"
431   git config -f ".lfsconfig" "lfs.fetchexclude" "a*"
432   git add .lfsconfig
433   git commit -m "config lfs.fetchinclude a*" 2>&1 | tee commit.log
434   grep "master" commit.log
435   grep "1 file changed" commit.log
436   git push origin master 2>&1 | tee push.log
437   grep "master -> master" push.log
438
439   pushd "$TRASHDIR"
440
441   echo "test: clone with lfs.fetchexclude in .lfsconfig"
442   local_reponame="clone_with_config_exclude"
443   git lfs clone "$GITSERVER/$reponame" "$local_reponame"
444   pushd "$local_reponame"
445   cat ".lfsconfig"
446   assert_local_object "$contents_b_oid" 1
447   refute_local_object "$contents_a_oid"
448   assert_hooks "$(dot_git_dir)"
449   popd
450
451   echo "test: clone with lfs.fetchexclude in .lfsconfig, and args"
452   local_reponame="clone_with_config_exclude_and_args"
453   git lfs clone "$GITSERVER/$reponame" "$local_reponame" -I "a.dat" -X "b.dat"
454   pushd "$local_reponame"
455   assert_local_object "$contents_a_oid" 1
456   refute_local_object "$contents_b_oid"
457   assert_hooks "$(dot_git_dir)"
458   popd
459
460   popd
461 )
462 end_test
463
464 begin_test "clone (without clean filter)"
465 (
466   set -e
467
468   reponame="clone_with_clean"
469   setup_remote_repo "$reponame"
470   clone_repo "$reponame" "$reponame"
471
472   git lfs track "*.dat" 2>&1 | tee track.log
473   grep "Tracking \"\*.dat\"" track.log
474
475   contents_a="a"
476   contents_a_oid=$(calc_oid "$contents_a")
477   printf "$contents_a" > "a.dat"
478
479   git add *.dat .gitattributes
480   git commit -m "add a.dat, b.dat" 2>&1 | tee commit.log
481   grep "master (root-commit)" commit.log
482
483   git push origin master 2>&1 | tee push.log
484   grep "master -> master" push.log
485   grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
486
487   cd "$TRASHDIR"
488
489   git lfs uninstall
490   git config --list > config.txt
491   grep "filter.lfs.clean" config.txt && {
492     echo "clean filter still configured:"
493     cat config.txt
494     exit 1
495   }
496
497   local_reponame="clone_without_clean"
498   git lfs clone "$GITSERVER/$reponame" "$local_reponame" -I "a*.dat" | tee clone.txt
499   if [ "0" -ne "${PIPESTATUS[0]}" ]; then
500     echo >&2 "fatal: expected clone to succeed ..."
501     exit 1
502   fi
503   grep "Git LFS is not installed" clone.txt
504
505   cd "$local_reponame"
506   assert_local_object "$contents_a_oid" 1
507   [ "$(pointer $contents_a_oid 1)" = "$(cat a.dat)" ]
508 )
509 end_test
510
511 begin_test "clone with submodules"
512 (
513   set -e
514
515   # set up a doubly nested submodule, each with LFS content
516   reponame="submod-root"
517   submodname1="submod-level1"
518   submodname2="submod-level2"
519
520   setup_remote_repo "$reponame"
521   setup_remote_repo "$submodname1"
522   setup_remote_repo "$submodname2"
523
524   clone_repo "$submodname2" submod2
525   git lfs track "*.dat" 2>&1 | tee track.log
526   grep "Tracking \"\*.dat\"" track.log
527
528   contents_sub2="Inception. Now, before you bother telling me it's impossible..."
529   contents_sub2_oid=$(calc_oid "$contents_sub2")
530   printf "$contents_sub2" > "sub2.dat"
531   git add sub2.dat .gitattributes
532   git commit -m "Nested submodule level 2"
533   git push origin master
534
535   clone_repo "$submodname1" submod1
536   git lfs track "*.dat" 2>&1 | tee track.log
537   grep "Tracking \"\*.dat\"" track.log
538
539   contents_sub1="We're dreaming?"
540   contents_sub1_oid=$(calc_oid "$contents_sub1")
541   printf "$contents_sub1" > "sub1.dat"
542   # add submodule2 as submodule of submodule1
543   git submodule add "$GITSERVER/$submodname2" sub2
544   git submodule update
545   git add sub2 sub1.dat .gitattributes
546   git commit -m "Nested submodule level 1"
547   git push origin master
548
549   clone_repo "$reponame" rootrepo
550   git lfs track "*.dat" 2>&1 | tee track.log
551   grep "Tracking \"\*.dat\"" track.log
552
553   contents_root="Downwards is the only way forwards."
554   contents_root_oid=$(calc_oid "$contents_root")
555   printf "$contents_root" > "root.dat"
556   # add submodule1 as submodule of root
557   git submodule add "$GITSERVER/$submodname1" sub1
558   git submodule update
559   git add sub1 root.dat .gitattributes
560   git commit -m "Root repo"
561   git push origin master
562
563   pushd "$TRASHDIR"
564
565   local_reponame="submod-clone"
566   git lfs clone --recursive "$GITSERVER/$reponame" "$local_reponame"
567
568   # check everything is where it should be
569   cd $local_reponame
570   assert_hooks "$(dot_git_dir)"
571   # check LFS store and working copy
572   assert_local_object "$contents_root_oid" "${#contents_root}"
573   [ $(wc -c < "root.dat") -eq ${#contents_root} ]
574   # and so on for nested subs
575   cd sub1
576   assert_local_object "$contents_sub1_oid" "${#contents_sub1}"
577   [ $(wc -c < "sub1.dat") -eq ${#contents_sub1} ]
578   cd sub2
579   assert_local_object "$contents_sub2_oid" "${#contents_sub2}"
580   [ $(wc -c < "sub2.dat") -eq ${#contents_sub2} ]
581
582   popd
583 )
584 end_test
585
586 begin_test "clone in current directory"
587 (
588   set -e
589
590   reponame="clone_in_current_dir"
591   setup_remote_repo "$reponame"
592   clone_repo "$reponame" $reponame
593
594   git lfs track "*.dat" 2>&1 | tee track.log
595   grep "Tracking \"\*.dat\"" track.log
596
597   contents="contents"
598   contents_oid="$(calc_oid "$contents")"
599
600   printf "$contents" > a.dat
601
602   git add .gitattributes a.dat
603
604   git commit -m "initial commit" 2>&1 | tee commit.log
605   grep "master (root-commit)" commit.log
606   grep "2 files changed" commit.log
607   grep "create mode 100644 a.dat" commit.log
608   grep "create mode 100644 .gitattributes" commit.log
609
610   git push origin master 2>&1 | tee push.log
611
612   pushd $TRASHDIR
613     mkdir "$reponame-clone"
614     cd "$reponame-clone"
615
616     git lfs clone $GITSERVER/$reponame "." 2>&1 | grep "Downloading LFS objects: 100% (1/1), 8 B"
617
618     assert_local_object "$contents_oid" 8
619     assert_hooks "$(dot_git_dir)"
620     [ ! -f ./lfs ]
621   popd
622 )
623 end_test
624
625 begin_test "clone empty repository"
626 (
627   set -e
628
629   reponame="clone_empty"
630   setup_remote_repo "$reponame"
631
632   cd "$TRASHDIR"
633   git lfs clone "$GITSERVER/$reponame" "$reponame" 2>&1 | tee clone.log
634   if [ "0" -ne "${PIPESTATUS[0]}" ]; then
635     echo >&2 "fatal: expected clone to succeed ..."
636     exit 1
637   fi
638 )
639 end_test
640
641 begin_test "clone bare empty repository"
642 (
643   set -e
644
645   reponame="clone_bare_empty"
646   setup_remote_repo "$reponame"
647
648   cd "$TRASHDIR"
649   git lfs clone "$GITSERVER/$reponame" "$reponame" --bare 2>&1 | tee clone.log
650   if [ "0" -ne "${PIPESTATUS[0]}" ]; then
651     echo >&2 "fatal: expected clone to succeed ..."
652     exit 1
653   fi
654 )
655 end_test