3 . "$(dirname "$0")/testlib.sh"
5 ensure_git_version_isnt $VERSION_LOWER "2.2.0"
11 reponame="$(basename "$0" ".sh")"
12 setup_remote_repo "$reponame"
13 clone_repo "$reponame" repo
15 git lfs track "*.dat" 2>&1 | tee track.log
16 grep "Tracking \"\*.dat\"" track.log
18 # generate some test data & commits with random LFS data
21 \"CommitDate\":\"$(get_date -10d)\",
23 {\"Filename\":\"file1.dat\",\"Size\":100},
24 {\"Filename\":\"file2.dat\",\"Size\":75}]
27 \"CommitDate\":\"$(get_date -7d)\",
29 {\"Filename\":\"file1.dat\",\"Size\":110},
30 {\"Filename\":\"file3.dat\",\"Size\":66},
31 {\"Filename\":\"file4.dat\",\"Size\":23}]
34 \"CommitDate\":\"$(get_date -10d)\",
36 {\"Filename\":\"file5.dat\",\"Size\":120},
37 {\"Filename\":\"file6.dat\",\"Size\":30}]
39 ]" | lfstest-testutils addcommits
41 git push origin master
43 # Now clone again, test specific clone dir
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
56 # check a few file sizes to make sure pulled
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)"
66 # Now check clone with implied dir
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
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)"
93 echo "Skipping SSL tests, Travis has weird behaviour in validating custom certs, test locally only"
97 reponame="test-cloneSSL"
98 setup_remote_repo "$reponame"
99 clone_repo_ssl "$reponame" "$reponame"
101 git lfs track "*.dat" 2>&1 | tee track.log
102 grep "Tracking \"\*.dat\"" track.log
104 # generate some test data & commits with random LFS data
107 \"CommitDate\":\"$(get_date -5d)\",
109 {\"Filename\":\"file1.dat\",\"Size\":100},
110 {\"Filename\":\"file2.dat\",\"Size\":75}]
113 \"CommitDate\":\"$(get_date -1d)\",
115 {\"Filename\":\"file3.dat\",\"Size\":30}]
117 ]" | lfstest-testutils addcommits
119 git push origin master
121 # Now SSL clone again with 'git lfs clone', test specific clone dir
124 newclonedir="testcloneSSL1"
125 git lfs clone "$SSLGITSERVER/$reponame" "$newclonedir" 2>&1 | tee lfsclone.log
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" ]
135 # check a few file sizes to make sure pulled
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)"
144 # Now check SSL clone with standard 'git clone' and smudge download
146 git clone "$SSLGITSERVER/$reponame"
150 begin_test "clone ClientCert"
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"
161 git lfs track "*.dat" 2>&1 | tee track.log
162 grep "Tracking \"\*.dat\"" track.log
164 # generate some test data & commits with random LFS data
167 \"CommitDate\":\"$(get_date -5d)\",
169 {\"Filename\":\"file1.dat\",\"Size\":100},
170 {\"Filename\":\"file2.dat\",\"Size\":75}]
173 \"CommitDate\":\"$(get_date -1d)\",
175 {\"Filename\":\"file3.dat\",\"Size\":30}]
177 ]" | lfstest-testutils addcommits
179 git push origin master
181 # Now clone again with 'git lfs clone', test specific clone dir
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" ]
194 # check a few file sizes to make sure pulled
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)"
204 # Now check SSL clone with standard 'git clone' and smudge download
206 git clone "$CLIENTCERTGITSERVER/$reponame"
211 begin_test "clone with flags"
215 reponame="$(basename "$0" ".sh")-flags"
216 setup_remote_repo "$reponame"
217 clone_repo "$reponame" "$reponame"
219 git lfs track "*.dat" 2>&1 | tee track.log
220 grep "Tracking \"\*.dat\"" track.log
222 # generate some test data & commits with random LFS data
225 \"CommitDate\":\"$(get_date -10d)\",
227 {\"Filename\":\"file1.dat\",\"Size\":100},
228 {\"Filename\":\"file2.dat\",\"Size\":75}]
231 \"CommitDate\":\"$(get_date -7d)\",
232 \"NewBranch\":\"branch2\",
234 {\"Filename\":\"fileonbranch2.dat\",\"Size\":66}]
237 \"CommitDate\":\"$(get_date -3d)\",
238 \"ParentBranches\":[\"master\"],
240 {\"Filename\":\"file3.dat\",\"Size\":120},
241 {\"Filename\":\"file4.dat\",\"Size\":30}]
243 ]" | lfstest-testutils addcommits
245 git push origin master branch2
247 # Now clone again, test specific clone dir
249 mkdir "$TRASHDIR/templatedir"
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"
256 # specific test for --no-checkout
257 git lfs clone --quiet --no-checkout "$GITSERVER/$reponame" "$newclonedir"
258 if [ -e "$newclonedir/file1.dat" ]; then
261 rm -rf "$newclonedir"
263 # specific test for --branch and --origin
264 git lfs clone --branch branch2 --recurse-submodules --origin differentorigin "$GITSERVER/$reponame" "$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)"
272 rm -rf "$newclonedir"
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
281 [ -e "$newclonedir/.git" ]
282 [ -d "$gitdir/objects" ]
283 assert_hooks "$gitdir"
284 rm -rf "$newclonedir"
287 # specific test for --bare
288 git lfs clone --bare "$GITSERVER/$reponame" "$newclonedir"
289 [ -d "$newclonedir/objects" ]
290 rm -rf "$newclonedir"
293 git lfs clone -l -v -n -s -b branch2 "$GITSERVER/$reponame" "$newclonedir"
294 rm -rf "$newclonedir"
298 begin_test "clone (with include/exclude args)"
302 reponame="clone_include_exclude"
303 setup_remote_repo "$reponame"
304 clone_repo "$reponame" "$reponame"
306 git lfs track "*.dat" 2>&1 | tee track.log
307 grep "Tracking \"\*.dat\"" track.log
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"
316 contents_b_oid=$(calc_oid "$contents_b")
317 printf "$contents_b" > "b.dat"
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
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
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)"
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)"
359 begin_test "clone (with .lfsconfig)"
363 reponame="clone_with_lfsconfig"
364 setup_remote_repo "$reponame"
365 clone_repo "$reponame" "$reponame"
367 git lfs track "*.dat" 2>&1 | tee track.log
368 grep "Tracking \"\*.dat\"" track.log
371 contents_a_oid=$(calc_oid "$contents_a")
372 printf "$contents_a" > "a.dat"
375 contents_b_oid=$(calc_oid "$contents_b")
376 printf "$contents_b" > "b.dat"
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
386 git config -f ".lfsconfig" "lfs.fetchinclude" "a*"
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
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
399 echo "test: clone with lfs.fetchinclude in .lfsconfig"
400 local_reponame="clone_with_config_include"
402 git lfs clone "$GITSERVER/$reponame" "$local_reponame"
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"
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)"
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)"
430 git config -f ".lfsconfig" "lfs.fetchinclude" "b*"
431 git config -f ".lfsconfig" "lfs.fetchexclude" "a*"
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
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"
446 assert_local_object "$contents_b_oid" 1
447 refute_local_object "$contents_a_oid"
448 assert_hooks "$(dot_git_dir)"
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)"
464 begin_test "clone (without clean filter)"
468 reponame="clone_with_clean"
469 setup_remote_repo "$reponame"
470 clone_repo "$reponame" "$reponame"
472 git lfs track "*.dat" 2>&1 | tee track.log
473 grep "Tracking \"\*.dat\"" track.log
476 contents_a_oid=$(calc_oid "$contents_a")
477 printf "$contents_a" > "a.dat"
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
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
490 git config --list > config.txt
491 grep "filter.lfs.clean" config.txt && {
492 echo "clean filter still configured:"
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 ..."
503 grep "Git LFS is not installed" clone.txt
506 assert_local_object "$contents_a_oid" 1
507 [ "$(pointer $contents_a_oid 1)" = "$(cat a.dat)" ]
511 begin_test "clone with submodules"
515 # set up a doubly nested submodule, each with LFS content
516 reponame="submod-root"
517 submodname1="submod-level1"
518 submodname2="submod-level2"
520 setup_remote_repo "$reponame"
521 setup_remote_repo "$submodname1"
522 setup_remote_repo "$submodname2"
524 clone_repo "$submodname2" submod2
525 git lfs track "*.dat" 2>&1 | tee track.log
526 grep "Tracking \"\*.dat\"" track.log
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
535 clone_repo "$submodname1" submod1
536 git lfs track "*.dat" 2>&1 | tee track.log
537 grep "Tracking \"\*.dat\"" track.log
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
545 git add sub2 sub1.dat .gitattributes
546 git commit -m "Nested submodule level 1"
547 git push origin master
549 clone_repo "$reponame" rootrepo
550 git lfs track "*.dat" 2>&1 | tee track.log
551 grep "Tracking \"\*.dat\"" track.log
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
559 git add sub1 root.dat .gitattributes
560 git commit -m "Root repo"
561 git push origin master
565 local_reponame="submod-clone"
566 git lfs clone --recursive "$GITSERVER/$reponame" "$local_reponame"
568 # check everything is where it should be
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
576 assert_local_object "$contents_sub1_oid" "${#contents_sub1}"
577 [ $(wc -c < "sub1.dat") -eq ${#contents_sub1} ]
579 assert_local_object "$contents_sub2_oid" "${#contents_sub2}"
580 [ $(wc -c < "sub2.dat") -eq ${#contents_sub2} ]
586 begin_test "clone in current directory"
590 reponame="clone_in_current_dir"
591 setup_remote_repo "$reponame"
592 clone_repo "$reponame" $reponame
594 git lfs track "*.dat" 2>&1 | tee track.log
595 grep "Tracking \"\*.dat\"" track.log
598 contents_oid="$(calc_oid "$contents")"
600 printf "$contents" > a.dat
602 git add .gitattributes a.dat
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
610 git push origin master 2>&1 | tee push.log
613 mkdir "$reponame-clone"
616 git lfs clone $GITSERVER/$reponame "." 2>&1 | grep "Downloading LFS objects: 100% (1/1), 8 B"
618 assert_local_object "$contents_oid" 8
619 assert_hooks "$(dot_git_dir)"
625 begin_test "clone empty repository"
629 reponame="clone_empty"
630 setup_remote_repo "$reponame"
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 ..."
641 begin_test "clone bare empty repository"
645 reponame="clone_bare_empty"
646 setup_remote_repo "$reponame"
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 ..."