3 . "$(dirname "$0")/fixtures/migrate.sh"
4 . "$(dirname "$0")/testlib.sh"
6 begin_test "migrate export (default branch)"
10 setup_multiple_local_branches_tracked
12 # Add b.md, a pointer existing only on master
13 base64 < /dev/urandom | head -c 160 > b.md
15 git commit -m "add b.md"
17 md_oid="$(calc_oid "$(cat a.md)")"
18 txt_oid="$(calc_oid "$(cat a.txt)")"
19 b_md_oid="$(calc_oid "$(cat b.md)")"
21 git checkout my-feature
22 md_feature_oid="$(calc_oid "$(cat a.md)")"
25 assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
26 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
27 assert_pointer "refs/heads/master" "b.md" "$b_md_oid" "160"
28 assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
30 git lfs migrate export --include="*.md, *.txt"
32 refute_pointer "refs/heads/master" "a.md"
33 refute_pointer "refs/heads/master" "a.txt"
34 refute_pointer "refs/heads/master" "b.md"
35 assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
37 # b.md should be pruned as no pointer exists to reference it
38 refute_local_object "$b_md_oid" "160"
40 # Other objects should not be pruned as they're still referenced in `feature`
42 assert_local_object "$md_oid" "140"
43 assert_local_object "$txt_oid" "120"
44 assert_local_object "$md_feature_oid" "30"
46 master="$(git rev-parse refs/heads/master)"
47 feature="$(git rev-parse refs/heads/my-feature)"
49 master_attrs="$(git cat-file -p "$master:.gitattributes")"
50 feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
52 echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
53 echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
55 [ ! $(echo "$feature_attrs" | grep -q "*.md text !filter !merge !diff") ]
56 [ ! $(echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff") ]
60 begin_test "migrate export (with remote)"
64 setup_single_remote_branch_tracked
66 git push origin master
68 md_oid="$(calc_oid "$(cat a.md)")"
69 txt_oid="$(calc_oid "$(cat a.txt)")"
71 assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
72 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
74 assert_pointer "refs/remotes/origin/master" "a.md" "$md_oid" "50"
75 assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_oid" "30"
77 # Flush the cache to ensure all objects have to be downloaded
78 rm -rf .git/lfs/objects
80 git lfs migrate export --everything --include="*.md, *.txt"
82 refute_pointer "refs/heads/master" "a.md"
83 refute_pointer "refs/heads/master" "a.txt"
85 # All pointers have been exported, so all objects should be pruned
86 refute_local_object "$md_oid" "50"
87 refute_local_object "$txt_oid" "30"
89 master="$(git rev-parse refs/heads/master)"
90 master_attrs="$(git cat-file -p "$master:.gitattributes")"
92 echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
93 echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
97 begin_test "migrate export (include/exclude args)"
101 setup_single_local_branch_tracked
103 md_oid="$(calc_oid "$(cat a.md)")"
104 txt_oid="$(calc_oid "$(cat a.txt)")"
106 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
107 assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
109 git lfs migrate export --include="*" --exclude="a.md"
111 refute_pointer "refs/heads/master" "a.txt"
112 assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
114 refute_local_object "$txt_oid" "120"
115 assert_local_object "$md_oid" "140"
117 master="$(git rev-parse refs/heads/master)"
119 master_attrs="$(git cat-file -p "$master:.gitattributes")"
121 echo "$master_attrs" | grep -q "* text !filter !merge !diff"
122 echo "$master_attrs" | grep -q "a.md filter=lfs diff=lfs merge=lfs"
126 begin_test "migrate export (bare repository)"
130 setup_single_remote_branch_tracked
131 git push origin master
133 md_oid="$(calc_oid "$(cat a.md)")"
134 txt_oid="$(calc_oid "$(cat a.txt)")"
138 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
139 assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
141 git lfs migrate export --everything --include="*"
143 refute_pointer "refs/heads/master" "a.md"
144 refute_pointer "refs/heads/master" "a.txt"
146 # All pointers have been exported, so all objects should be pruned
147 refute_local_object "$md_oid" "50"
148 refute_local_object "$txt_oid" "30"
152 begin_test "migrate export (given branch)"
156 setup_multiple_local_branches_tracked
158 md_oid="$(calc_oid "$(cat a.md)")"
159 txt_oid="$(calc_oid "$(cat a.txt)")"
161 git checkout my-feature
162 md_feature_oid="$(calc_oid "$(cat a.md)")"
165 assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
166 assert_pointer "refs/heads/my-feature" "a.txt" "$txt_oid" "120"
167 assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
168 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
170 git lfs migrate export --include="*.md,*.txt" my-feature
172 refute_pointer "refs/heads/my-feature" "a.md"
173 refute_pointer "refs/heads/my-feature" "a.txt"
174 refute_pointer "refs/heads/master" "a.md"
175 refute_pointer "refs/heads/master" "a.txt"
177 # No pointers left, so all objects should be pruned
178 refute_local_object "$md_feature_oid" "30"
179 refute_local_object "$txt_oid" "120"
180 refute_local_object "$md_oid" "140"
182 master="$(git rev-parse refs/heads/master)"
183 feature="$(git rev-parse refs/heads/my-feature)"
185 master_attrs="$(git cat-file -p "$master:.gitattributes")"
186 feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
188 echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
189 echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
190 echo "$feature_attrs" | grep -q "*.md text !filter !merge !diff"
191 echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff"
195 begin_test "migrate export (no filter)"
199 setup_multiple_local_branches_tracked
201 git lfs migrate export --yes 2>&1 | tee migrate.log
202 if [ ${PIPESTATUS[0]} -eq 0 ]; then
203 echo >&2 "fatal: expected git lfs migrate export to fail, didn't"
207 grep "fatal: one or more files must be specified with --include" migrate.log
211 begin_test "migrate export (exclude remote refs)"
215 setup_single_remote_branch_tracked
217 md_oid="$(calc_oid "$(cat a.md)")"
218 txt_oid="$(calc_oid "$(cat a.txt)")"
220 git checkout refs/remotes/origin/master
221 md_remote_oid="$(calc_oid "$(cat a.md)")"
222 txt_remote_oid="$(calc_oid "$(cat a.txt)")"
225 assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
226 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
228 assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "140"
229 assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "120"
231 git lfs migrate export --include="*.md,*.txt"
233 refute_pointer "refs/heads/master" "a.md"
234 refute_pointer "refs/heads/master" "a.txt"
236 refute_local_object "$md_oid" "50"
237 refute_local_object "$txt_oid" "30"
239 assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "140"
240 assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "120"
242 # Since these two objects exist on the remote, they should be removed with
243 # our prune operation
244 refute_local_object "$md_remote_oid" "140"
245 refute_local_object "$txt_remote_oid" "120"
247 master="$(git rev-parse refs/heads/master)"
248 remote="$(git rev-parse refs/remotes/origin/master)"
250 master_attrs="$(git cat-file -p "$master:.gitattributes")"
251 remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
253 echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
254 echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
256 [ ! $(echo "$remote_attrs" | grep -q "*.md text !filter !merge !diff") ]
257 [ ! $(echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff") ]
261 begin_test "migrate export (--skip-fetch)"
265 setup_single_remote_branch_tracked
267 md_master_oid="$(calc_oid "$(cat a.md)")"
268 txt_master_oid="$(calc_oid "$(cat a.txt)")"
270 git checkout refs/remotes/origin/master
271 md_remote_oid="$(calc_oid "$(cat a.md)")"
272 txt_remote_oid="$(calc_oid "$(cat a.txt)")"
275 git tag pseudo-remote "$(git rev-parse refs/remotes/origin/master)"
276 # Remove the refs/remotes/origin/master ref, and instruct 'git lfs migrate' to
278 git update-ref -d refs/remotes/origin/master
280 assert_pointer "refs/heads/master" "a.md" "$md_master_oid" "50"
281 assert_pointer "pseudo-remote" "a.md" "$md_remote_oid" "140"
282 assert_pointer "refs/heads/master" "a.txt" "$txt_master_oid" "30"
283 assert_pointer "pseudo-remote" "a.txt" "$txt_remote_oid" "120"
285 git lfs migrate export --skip-fetch --include="*.md,*.txt"
287 refute_pointer "refs/heads/master" "a.md"
288 refute_pointer "pseudo-remote" "a.md"
289 refute_pointer "refs/heads/master" "a.txt"
290 refute_pointer "pseudo-remote" "a.txt"
292 refute_local_object "$md_master_oid" "50"
293 refute_local_object "$md_remote_oid" "140"
294 refute_local_object "$txt_master_oid" "30"
295 refute_local_object "$txt_remote_oid" "120"
297 master="$(git rev-parse refs/heads/master)"
298 remote="$(git rev-parse pseudo-remote)"
300 master_attrs="$(git cat-file -p "$master:.gitattributes")"
301 remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
303 echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
304 echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
305 echo "$remote_attrs" | grep -q "*.md text !filter !merge !diff"
306 echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff"
310 begin_test "migrate export (include/exclude ref)"
314 setup_multiple_remote_branches_gitattrs
316 md_master_oid="$(calc_oid "$(cat a.md)")"
317 txt_master_oid="$(calc_oid "$(cat a.txt)")"
319 git checkout refs/remotes/origin/master
320 md_remote_oid="$(calc_oid "$(cat a.md)")"
321 txt_remote_oid="$(calc_oid "$(cat a.txt)")"
323 git checkout my-feature
324 md_feature_oid="$(calc_oid "$(cat a.md)")"
325 txt_feature_oid="$(calc_oid "$(cat a.txt)")"
329 git lfs migrate export \
331 --include-ref=refs/heads/my-feature \
332 --exclude-ref=refs/heads/master
334 assert_pointer "refs/heads/master" "a.md" "$md_master_oid" "21"
335 assert_pointer "refs/heads/master" "a.txt" "$txt_master_oid" "20"
337 assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "11"
338 assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "10"
340 assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "31"
341 refute_pointer "refs/heads/my-feature" "a.txt"
343 # Master objects should not be pruned as they exist in unpushed commits
344 assert_local_object "$md_master_oid" "21"
345 assert_local_object "$txt_master_oid" "20"
347 # Remote master objects should be pruned as they exist in the remote
348 refute_local_object "$md_remote_oid" "11"
349 refute_local_object "$txt_remote_oid" "10"
351 # txt_feature_oid should be pruned as it's no longer a pointer, but
352 # md_feature_oid should remain as it's still a pointer in unpushed commits
353 assert_local_object "$md_feature_oid" "31"
354 refute_local_object "$txt_feature_oid" "30"
356 master="$(git rev-parse refs/heads/master)"
357 feature="$(git rev-parse refs/heads/my-feature)"
358 remote="$(git rev-parse refs/remotes/origin/master)"
360 master_attrs="$(git cat-file -p "$master:.gitattributes")"
361 remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
362 feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
364 [ ! $(echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff") ]
365 [ ! $(echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff") ]
366 echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff"
370 begin_test "migrate export (--object-map)"
374 setup_multiple_local_branches_tracked
376 output_dir=$(mktemp -d)
378 git log --all --pretty='format:%H' > "${output_dir}/old_sha.txt"
379 git lfs migrate export --everything --include="*" --object-map "${output_dir}/object-map.txt"
380 git log --all --pretty='format:%H' > "${output_dir}/new_sha.txt"
381 paste -d',' "${output_dir}/old_sha.txt" "${output_dir}/new_sha.txt" > "${output_dir}/expected-map.txt"
383 diff -u <(sort "${output_dir}/expected-map.txt") <(sort "${output_dir}/object-map.txt")
387 begin_test "migrate export (--verbose)"
391 setup_multiple_local_branches_tracked
393 git lfs migrate export --everything --include="*" --verbose 2>&1 | grep -q "migrate: commit "
397 begin_test "migrate export (--remote)"
401 setup_single_remote_branch_tracked
403 git push origin master
405 md_oid="$(calc_oid "$(cat a.md)")"
406 txt_oid="$(calc_oid "$(cat a.txt)")"
408 assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
409 assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
411 # Flush the cache to ensure all objects have to be downloaded
412 rm -rf .git/lfs/objects
414 # Setup a new remote and invalidate the default
415 remote_url="$(git config --get remote.origin.url)"
416 git remote add zeta "$remote_url"
417 git remote set-url origin ""
419 git lfs migrate export --everything --remote="zeta" --include="*.md, *.txt"
421 refute_pointer "refs/heads/master" "a.md"
422 refute_pointer "refs/heads/master" "a.txt"
424 refute_local_object "$md_oid" "50"
425 refute_local_object "$txt_oid" "30"
429 begin_test "migrate export (invalid --remote)"
433 setup_single_remote_branch_tracked
435 git lfs migrate export --include="*" --remote="zz" --yes 2>&1 \
437 if [ ${PIPESTATUS[0]} -eq 0 ]; then
438 echo >&2 "fatal: expected git lfs migrate export to fail, didn't"
442 grep "fatal: invalid remote zz provided" migrate.log