Imported Upstream version 2.6.1
[scm/test.git] / t / t-fetch.sh
1 #!/usr/bin/env bash
2
3 . "$(dirname "$0")/testlib.sh"
4
5 contents="a"
6 contents_oid=$(calc_oid "$contents")
7 b="b"
8 b_oid=$(calc_oid "$b")
9 reponame="$(basename "$0" ".sh")"
10
11 begin_test "init for fetch tests"
12 (
13   set -e
14
15   setup_remote_repo "$reponame"
16
17   clone_repo "$reponame" repo
18
19   git lfs track "*.dat" 2>&1 | tee track.log
20   grep "Tracking \"\*.dat\"" track.log
21
22
23   printf "%s" "$contents" > a.dat
24   git add a.dat
25   git add .gitattributes
26   git commit -m "add a.dat" 2>&1 | tee commit.log
27   grep "master (root-commit)" commit.log
28   grep "2 files changed" commit.log
29   grep "create mode 100644 a.dat" commit.log
30   grep "create mode 100644 .gitattributes" commit.log
31
32   [ "a" = "$(cat a.dat)" ]
33
34   assert_local_object "$contents_oid" 1
35
36   refute_server_object "$reponame" "$contents_oid"
37
38   git push origin master 2>&1 | tee push.log
39   grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
40   grep "master -> master" push.log
41
42   assert_server_object "$reponame" "$contents_oid"
43
44   # Add a file in a different branch
45   git checkout -b newbranch
46   printf "%s" "$b" > b.dat
47   git add b.dat
48   git commit -m "add b.dat"
49   assert_local_object "$b_oid" 1
50
51   git push origin newbranch
52   assert_server_object "$reponame" "$b_oid"
53
54   # These clones are used for subsequent tests
55   clone_repo "$reponame" clone
56   git clone --shared "$TRASHDIR/clone" "$TRASHDIR/shared"
57 )
58 end_test
59
60 begin_test "fetch"
61 (
62   set -e
63   cd clone
64   rm -rf .git/lfs/objects
65
66   git lfs fetch 2>&1 | grep "Downloading LFS objects: 100% (1/1), 1 B"
67   assert_local_object "$contents_oid" 1
68
69   git lfs fsck 2>&1 | tee fsck.log
70   grep "Git LFS fsck OK" fsck.log
71 )
72 end_test
73
74 begin_test "fetch (shared repository)"
75 (
76   set -e
77   cd shared
78   rm -rf .git/lfs/objects
79
80   git lfs fetch 2>&1 | tee fetch.log
81   ! grep "Could not scan" fetch.log
82   assert_local_object "$contents_oid" 1
83
84   git lfs fsck 2>&1 | tee fsck.log
85   grep "Git LFS fsck OK" fsck.log
86 )
87 end_test
88
89 begin_test "fetch with remote"
90 (
91   set -e
92   cd clone
93   rm -rf .git/lfs/objects
94
95   git lfs fetch origin 2>&1 | grep "Downloading LFS objects: 100% (1/1), 1 B"
96   assert_local_object "$contents_oid" 1
97   refute_local_object "$b_oid" 1
98
99   git lfs fsck 2>&1 | tee fsck.log
100   grep "Git LFS fsck OK" fsck.log
101 )
102 end_test
103
104 begin_test "fetch with remote and branches"
105 (
106   set -e
107   cd clone
108
109   git checkout newbranch
110   git checkout master
111
112   rm -rf .git/lfs/objects
113
114   git lfs fetch origin master newbranch
115   assert_local_object "$contents_oid" 1
116   assert_local_object "$b_oid" 1
117
118   git lfs fsck 2>&1 | tee fsck.log
119   grep "Git LFS fsck OK" fsck.log
120 )
121 end_test
122
123 begin_test "fetch with master commit sha1"
124 (
125   set -e
126   cd clone
127   rm -rf .git/lfs/objects
128
129   master_sha1=$(git rev-parse master)
130   git lfs fetch origin "$master_sha1"
131   assert_local_object "$contents_oid" 1
132   refute_local_object "$b_oid" 1
133
134   git lfs fsck 2>&1 | tee fsck.log
135   grep "Git LFS fsck OK" fsck.log
136 )
137 end_test
138
139 begin_test "fetch with newbranch commit sha1"
140 (
141   set -e
142   cd clone
143   rm -rf .git/lfs/objects
144
145   newbranch_sha1=$(git rev-parse newbranch)
146   git lfs fetch origin "$newbranch_sha1"
147   assert_local_object "$contents_oid" 1
148   assert_local_object "$b_oid" 1
149
150   git lfs fsck 2>&1 | tee fsck.log
151   grep "Git LFS fsck OK" fsck.log
152 )
153 end_test
154
155 begin_test "fetch with include filters in gitconfig"
156 (
157   set -e
158   cd clone
159   rm -rf .git/lfs/objects
160
161   git config "lfs.fetchinclude" "a*"
162   git lfs fetch origin master newbranch
163   assert_local_object "$contents_oid" 1
164   refute_local_object "$b_oid"
165
166   git lfs fsck 2>&1 | tee fsck.log
167   grep "Git LFS fsck OK" fsck.log
168 )
169 end_test
170
171 begin_test "fetch with exclude filters in gitconfig"
172 (
173   set -e
174
175   cd clone
176   git config --unset "lfs.fetchinclude"
177   rm -rf .git/lfs/objects
178
179   git config "lfs.fetchexclude" "a*"
180   git lfs fetch origin master newbranch
181   refute_local_object "$contents_oid"
182   assert_local_object "$b_oid" 1
183
184   git lfs fsck 2>&1 | tee fsck.log
185   grep "Git LFS fsck OK" fsck.log
186 )
187 end_test
188
189 begin_test "fetch with include/exclude filters in gitconfig"
190 (
191   set -e
192   cd clone
193   rm -rf .git/lfs/objects
194   git config --unset "lfs.fetchexclude"
195
196   git config "lfs.fetchinclude" "a*,b*"
197   git config "lfs.fetchexclude" "c*,d*"
198   git lfs fetch origin master newbranch
199   assert_local_object "$contents_oid" 1
200   assert_local_object "$b_oid" 1
201
202   rm -rf .git/lfs/objects
203   git config "lfs.fetchinclude" "c*,d*"
204   git config "lfs.fetchexclude" "a*,b*"
205   git lfs fetch origin master newbranch
206   refute_local_object "$contents_oid"
207   refute_local_object "$b_oid"
208 )
209 end_test
210
211 begin_test "fetch with include filter in cli"
212 (
213   set -e
214   cd clone
215   git config --unset "lfs.fetchinclude"
216   git config --unset "lfs.fetchexclude"
217   rm -rf .git/lfs/objects
218
219   git lfs fetch --include="a*" origin master newbranch
220   assert_local_object "$contents_oid" 1
221   refute_local_object "$b_oid"
222 )
223 end_test
224
225 begin_test "fetch with exclude filter in cli"
226 (
227   set -e
228   cd clone
229   rm -rf .git/lfs/objects
230   git lfs fetch --exclude="a*" origin master newbranch
231   refute_local_object "$contents_oid"
232   assert_local_object "$b_oid" 1
233 )
234 end_test
235
236 begin_test "fetch with include/exclude filters in cli"
237 (
238   set -e
239   cd clone
240   rm -rf .git/lfs/objects
241   git lfs fetch -I "a*,b*" -X "c*,d*" origin master newbranch
242   assert_local_object "$contents_oid" 1
243   assert_local_object "$b_oid" 1
244
245   rm -rf .git/lfs/objects
246   git lfs fetch --include="c*,d*" --exclude="a*,b*" origin master newbranch
247   refute_local_object "$contents_oid"
248   refute_local_object "$b_oid"
249 )
250 end_test
251
252 begin_test "fetch with include filter overriding exclude filter"
253 (
254   set -e
255   cd clone
256   rm -rf .git/lfs/objects
257   git config lfs.fetchexclude "b*"
258   git lfs fetch -I "b.dat" -X "" origin master newbranch
259   assert_local_object "$b_oid" "1"
260 )
261 end_test
262
263 begin_test "fetch with missing object"
264 (
265   set -e
266   cd clone
267   git config --unset lfs.fetchexclude
268   rm -rf .git/lfs/objects
269
270   delete_server_object "$reponame" "$b_oid"
271   refute_server_object "$reponame" "$b_oid"
272
273   # should return non-zero, but should also download all the other valid files too
274   set +e
275   git lfs fetch origin master newbranch
276   fetch_exit=$?
277   set -e
278   [ "$fetch_exit" != "0" ]
279   assert_local_object "$contents_oid" 1
280   refute_local_object "$b_oid"
281 )
282 end_test
283
284 begin_test "fetch-all"
285 (
286   set -e
287
288   reponame="fetch-all"
289   setup_remote_repo "$reponame"
290
291   clone_repo "$reponame" "$reponame"
292
293   git lfs track "*.dat" 2>&1 | tee track.log
294   grep "Tracking \"\*.dat\"" track.log
295
296   NUMFILES=12
297   # generate content we'll use
298   for ((a=0; a < NUMFILES ; a++))
299   do
300     content[$a]="filecontent$a"
301     oid[$a]=$(calc_oid "${content[$a]}")
302   done
303
304   echo "[
305   {
306     \"CommitDate\":\"$(get_date -180d)\",
307     \"Files\":[
308       {\"Filename\":\"file1.dat\",\"Size\":${#content[0]}, \"Data\":\"${content[0]}\"},
309       {\"Filename\":\"file2.dat\",\"Size\":${#content[1]}, \"Data\":\"${content[1]}\"}]
310   },
311   {
312     \"NewBranch\":\"branch1\",
313     \"CommitDate\":\"$(get_date -140d)\",
314     \"Files\":[
315       {\"Filename\":\"file3.dat\",\"Size\":${#content[2]}, \"Data\":\"${content[2]}\"}]
316   },
317   {
318     \"ParentBranches\":[\"master\"],
319     \"CommitDate\":\"$(get_date -100d)\",
320     \"Files\":[
321       {\"Filename\":\"file1.dat\",\"Size\":${#content[3]}, \"Data\":\"${content[3]}\"}]
322   },
323   {
324     \"NewBranch\":\"remote_branch_only\",
325     \"CommitDate\":\"$(get_date -80d)\",
326     \"Files\":[
327       {\"Filename\":\"file2.dat\",\"Size\":${#content[4]}, \"Data\":\"${content[4]}\"}]
328   },
329   {
330     \"ParentBranches\":[\"master\"],
331     \"CommitDate\":\"$(get_date -75d)\",
332     \"Files\":[
333       {\"Filename\":\"file4.dat\",\"Size\":${#content[5]}, \"Data\":\"${content[5]}\"}]
334   },
335   {
336     \"NewBranch\":\"tag_only\",
337     \"Tags\":[\"tag1\"],
338     \"CommitDate\":\"$(get_date -70d)\",
339     \"Files\":[
340       {\"Filename\":\"file4.dat\",\"Size\":${#content[6]}, \"Data\":\"${content[6]}\"}]
341   },
342   {
343     \"ParentBranches\":[\"master\"],
344     \"CommitDate\":\"$(get_date -60d)\",
345     \"Files\":[
346       {\"Filename\":\"file1.dat\",\"Size\":${#content[7]}, \"Data\":\"${content[7]}\"}]
347   },
348   {
349     \"NewBranch\":\"branch3\",
350     \"CommitDate\":\"$(get_date -50d)\",
351     \"Files\":[
352       {\"Filename\":\"file4.dat\",\"Size\":${#content[8]}, \"Data\":\"${content[8]}\"}]
353   },
354   {
355     \"CommitDate\":\"$(get_date -40d)\",
356     \"ParentBranches\":[\"master\"],
357     \"Files\":[
358       {\"Filename\":\"file1.dat\",\"Size\":${#content[9]}, \"Data\":\"${content[9]}\"},
359       {\"Filename\":\"file2.dat\",\"Size\":${#content[10]}, \"Data\":\"${content[10]}\"}]
360   },
361   {
362     \"ParentBranches\":[\"master\"],
363     \"CommitDate\":\"$(get_date -30d)\",
364     \"Files\":[
365       {\"Filename\":\"file4.dat\",\"Size\":${#content[11]}, \"Data\":\"${content[11]}\"}]
366   }
367   ]" | lfstest-testutils addcommits
368
369   git push origin master
370   git push origin branch1
371   git push origin branch3
372   git push origin remote_branch_only
373   git push origin tag_only
374   for ((a=0; a < NUMFILES ; a++))
375   do
376     assert_server_object "$reponame" "${oid[$a]}"
377   done
378
379   # delete remote_branch_only and make sure that objects are downloaded even
380   # though not checked out to a local branch (full backup always)
381   git branch -D remote_branch_only
382
383   # delete tag_only to make sure objects are downloaded when only reachable from tag
384   git branch -D tag_only
385
386   rm -rf .git/lfs/objects
387
388   git lfs fetch --all origin
389   for ((a=0; a < NUMFILES ; a++))
390   do
391     assert_local_object "${oid[$a]}" "${#content[$a]}"
392   done
393
394   # Make a bare clone of the repository
395   cd ..
396   git clone --bare "$GITSERVER/$reponame" "$reponame-bare"
397   cd "$reponame-bare"
398
399   # Preform the same assertion as above, on the same data
400   git lfs fetch --all origin
401   for ((a=0; a < NUMFILES ; a++)); do
402     assert_local_object "${oid[$a]}" "${#content[$a]}"
403   done
404 )
405 end_test
406
407 begin_test "fetch: outside git repository"
408 (
409   set +e
410   git lfs fetch 2>&1 > fetch.log
411   res=$?
412
413   set -e
414   if [ "$res" = "0" ]; then
415     echo "Passes because $GIT_LFS_TEST_DIR is unset."
416     exit 0
417   fi
418   [ "$res" = "128" ]
419   grep "Not in a git repository" fetch.log
420 )
421 end_test
422
423 begin_test "fetch with no origin remote"
424 (
425   set -e
426
427   reponame="fetch-no-remote"
428   setup_remote_repo "$reponame"
429
430   clone_repo "$reponame" no-remote-clone
431
432   clone_repo "$reponame" no-remote-repo
433
434   git lfs track "*.dat" 2>&1 | tee track.log
435   grep "Tracking \"\*.dat\"" track.log
436
437   contents="a"
438   contents_oid=$(calc_oid "$contents")
439
440   printf "%s" "$contents" > a.dat
441   git add a.dat
442   git add .gitattributes
443   git commit -m "add a.dat" 2>&1 | tee commit.log
444   grep "master (root-commit)" commit.log
445   grep "2 files changed" commit.log
446   grep "create mode 100644 a.dat" commit.log
447   grep "create mode 100644 .gitattributes" commit.log
448
449   [ "a" = "$(cat a.dat)" ]
450
451   assert_local_object "$contents_oid" 1
452
453   refute_server_object "$reponame" "$contents_oid"
454
455   git push origin master 2>&1 | tee push.log
456   grep "Uploading LFS objects: 100% (1/1), 1 B" push.log
457   grep "master -> master" push.log
458
459
460   # change to the clone's working directory
461   cd ../no-remote-clone
462
463   # pull commits & lfs
464   git pull 2>&1
465   assert_local_object "$contents_oid" 1
466
467   # now checkout detached HEAD so we're not tracking anything on remote
468   git checkout --detach
469
470   # delete lfs
471   rm -rf .git/lfs
472
473   # rename remote from 'origin' to 'something'
474   git remote rename origin something
475
476   # fetch should still pick this remote as in the case of no tracked remote,
477   # and no origin, but only 1 remote, should pick the only one as default
478   git lfs fetch
479   assert_local_object "$contents_oid" 1
480 )
481 end_test
482
483 begin_test "fetch --prune"
484 (
485   set -e
486
487   reponame="fetch_prune"
488   setup_remote_repo "remote_$reponame"
489
490   clone_repo "remote_$reponame" "clone_$reponame"
491
492   git lfs track "*.dat" 2>&1 | tee track.log
493   grep "Tracking \"\*.dat\"" track.log
494
495   content_head="HEAD content"
496   content_commit2="Content for commit 2 (prune)"
497   content_commit1="Content for commit 1 (prune)"
498   oid_head=$(calc_oid "$content_head")
499   oid_commit2=$(calc_oid "$content_commit2")
500   oid_commit1=$(calc_oid "$content_commit1")
501
502   echo "[
503   {
504     \"CommitDate\":\"$(get_date -50d)\",
505     \"Files\":[
506       {\"Filename\":\"file.dat\",\"Size\":${#content_commit1}, \"Data\":\"$content_commit1\"}]
507   },
508   {
509     \"CommitDate\":\"$(get_date -35d)\",
510     \"Files\":[
511       {\"Filename\":\"file.dat\",\"Size\":${#content_commit2}, \"Data\":\"$content_commit2\"}]
512   },
513   {
514     \"CommitDate\":\"$(get_date -25d)\",
515     \"Files\":[
516       {\"Filename\":\"file.dat\",\"Size\":${#content_head}, \"Data\":\"$content_head\"}]
517   }
518   ]" | lfstest-testutils addcommits
519
520   # push all so no unpushed reason to not prune
521   git push origin master
522
523   # set no recents so max ability to prune
524   git config lfs.fetchrecentrefsdays 0
525   git config lfs.fetchrecentcommitsdays 0
526
527   # delete HEAD object to prove that we still download something
528   # also prune at the same time which will remove anything other than HEAD
529   delete_local_object "$oid_head"
530   git lfs fetch --prune
531   assert_local_object "$oid_head" "${#content_head}"
532   refute_local_object "$oid_commit1"
533   refute_local_object "$oid_commit2"
534 )
535 end_test
536
537 begin_test "fetch raw remote url"
538 (
539   set -e
540   mkdir raw
541   cd raw
542   git init
543   git lfs install --local --skip-smudge
544
545   git remote add origin "$GITSERVER/$reponame"
546   git pull origin master
547
548   # LFS object not downloaded, pointer in working directory
549   refute_local_object "$contents_oid"
550   grep "$content_oid" a.dat
551
552   git lfs fetch "$GITSERVER/$reponame"
553
554   # LFS object downloaded, pointer still in working directory
555   assert_local_object "$contents_oid" 1
556   grep "$content_oid" a.dat
557 )
558 end_test
559
560 begin_test "fetch with invalid remote"
561 (
562   set -e
563   cd repo
564   git lfs fetch not-a-remote 2>&1 | tee fetch.log
565   grep "Invalid remote name" fetch.log
566 )
567 end_test