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