]>
Commit | Line | Data |
---|---|---|
8bf2c69c AR |
1 | #!/bin/sh |
2 | ||
5be60078 | 3 | test_description='git mv in subdirs' |
8bf2c69c AR |
4 | . ./test-lib.sh |
5 | ||
6 | test_expect_success \ | |
7 | 'prepare reference tree' \ | |
8 | 'mkdir path0 path1 && | |
bfdbee98 | 9 | cp "$TEST_DIRECTORY"/../COPYING path0/COPYING && |
5be60078 | 10 | git add path0/COPYING && |
d592b315 | 11 | git commit -m add -a' |
8bf2c69c AR |
12 | |
13 | test_expect_success \ | |
90924d55 | 14 | 'moving the file out of subdirectory' \ |
5be60078 | 15 | 'cd path0 && git mv COPYING ../path1/COPYING' |
8bf2c69c AR |
16 | |
17 | # in path0 currently | |
18 | test_expect_success \ | |
19 | 'commiting the change' \ | |
d592b315 | 20 | 'cd .. && git commit -m move-out -a' |
8bf2c69c AR |
21 | |
22 | test_expect_success \ | |
23 | 'checking the commit' \ | |
a4d4e32a PK |
24 | 'git diff-tree -r -M --name-status HEAD^ HEAD >actual && |
25 | grep "^R100..*path0/COPYING..*path1/COPYING" actual' | |
8bf2c69c | 26 | |
90924d55 JW |
27 | test_expect_success \ |
28 | 'moving the file back into subdirectory' \ | |
5be60078 | 29 | 'cd path0 && git mv ../path1/COPYING COPYING' |
90924d55 JW |
30 | |
31 | # in path0 currently | |
32 | test_expect_success \ | |
33 | 'commiting the change' \ | |
d592b315 | 34 | 'cd .. && git commit -m move-in -a' |
90924d55 JW |
35 | |
36 | test_expect_success \ | |
37 | 'checking the commit' \ | |
a4d4e32a PK |
38 | 'git diff-tree -r -M --name-status HEAD^ HEAD >actual && |
39 | grep "^R100..*path1/COPYING..*path0/COPYING" actual' | |
90924d55 | 40 | |
36b78cd9 SM |
41 | test_expect_success \ |
42 | 'mv --dry-run does not move file' \ | |
43 | 'git mv -n path0/COPYING MOVED && | |
44 | test -f path0/COPYING && | |
45 | test ! -f MOVED' | |
46 | ||
3772923f MG |
47 | test_expect_success \ |
48 | 'checking -k on non-existing file' \ | |
49 | 'git mv -k idontexist path0' | |
50 | ||
51 | test_expect_success \ | |
52 | 'checking -k on untracked file' \ | |
53 | 'touch untracked1 && | |
54 | git mv -k untracked1 path0 && | |
55 | test -f untracked1 && | |
56 | test ! -f path0/untracked1' | |
57 | ||
be17262d | 58 | test_expect_success \ |
3772923f MG |
59 | 'checking -k on multiple untracked files' \ |
60 | 'touch untracked2 && | |
61 | git mv -k untracked1 untracked2 path0 && | |
62 | test -f untracked1 && | |
63 | test -f untracked2 && | |
720ec6b8 | 64 | test ! -f path0/untracked1 && |
3772923f MG |
65 | test ! -f path0/untracked2' |
66 | ||
5aed3c6a | 67 | test_expect_success \ |
c8ba6b1b MM |
68 | 'checking -f on untracked file with existing target' \ |
69 | 'touch path0/untracked1 && | |
a2b1e53b | 70 | test_must_fail git mv -f untracked1 path0 && |
c8ba6b1b MM |
71 | test ! -f .git/index.lock && |
72 | test -f untracked1 && | |
73 | test -f path0/untracked1' | |
74 | ||
3772923f MG |
75 | # clean up the mess in case bad things happen |
76 | rm -f idontexist untracked1 untracked2 \ | |
77 | path0/idontexist path0/untracked1 path0/untracked2 \ | |
78 | .git/index.lock | |
c57f6281 MM |
79 | rmdir path1 |
80 | ||
81 | test_expect_success \ | |
82 | 'moving to absent target with trailing slash' \ | |
83 | 'test_must_fail git mv path0/COPYING no-such-dir/ && | |
84 | test_must_fail git mv path0/COPYING no-such-dir// && | |
85 | git mv path0/ no-such-dir/ && | |
86 | test_path_is_dir no-such-dir' | |
87 | ||
88 | test_expect_success \ | |
89 | 'clean up' \ | |
90 | 'git reset --hard' | |
91 | ||
92 | test_expect_success \ | |
93 | 'moving to existing untracked target with trailing slash' \ | |
94 | 'mkdir path1 && | |
95 | git mv path0/ path1/ && | |
96 | test_path_is_dir path1/path0/' | |
97 | ||
98 | test_expect_success \ | |
99 | 'moving to existing tracked target with trailing slash' \ | |
100 | 'mkdir path2 && | |
101 | >path2/file && git add path2/file && | |
102 | git mv path1/path0/ path2/ && | |
103 | test_path_is_dir path2/path0/' | |
104 | ||
105 | test_expect_success \ | |
106 | 'clean up' \ | |
107 | 'git reset --hard' | |
3772923f | 108 | |
afd22296 JW |
109 | test_expect_success \ |
110 | 'adding another file' \ | |
4ad21f5d | 111 | 'cp "$TEST_DIRECTORY"/../README.md path0/README && |
5be60078 | 112 | git add path0/README && |
d592b315 | 113 | git commit -m add2 -a' |
afd22296 JW |
114 | |
115 | test_expect_success \ | |
116 | 'moving whole subdirectory' \ | |
5be60078 | 117 | 'git mv path0 path2' |
afd22296 JW |
118 | |
119 | test_expect_success \ | |
120 | 'commiting the change' \ | |
d592b315 | 121 | 'git commit -m dir-move -a' |
afd22296 JW |
122 | |
123 | test_expect_success \ | |
124 | 'checking the commit' \ | |
a4d4e32a PK |
125 | 'git diff-tree -r -M --name-status HEAD^ HEAD >actual && |
126 | grep "^R100..*path0/COPYING..*path2/COPYING" actual && | |
127 | grep "^R100..*path0/README..*path2/README" actual' | |
afd22296 | 128 | |
1d6249e6 JS |
129 | test_expect_success \ |
130 | 'succeed when source is a prefix of destination' \ | |
5be60078 | 131 | 'git mv path2/COPYING path2/COPYING-renamed' |
1d6249e6 | 132 | |
a1dad607 JS |
133 | test_expect_success \ |
134 | 'moving whole subdirectory into subdirectory' \ | |
5be60078 | 135 | 'git mv path2 path1' |
a1dad607 JS |
136 | |
137 | test_expect_success \ | |
138 | 'commiting the change' \ | |
d592b315 | 139 | 'git commit -m dir-move -a' |
a1dad607 JS |
140 | |
141 | test_expect_success \ | |
142 | 'checking the commit' \ | |
a4d4e32a PK |
143 | 'git diff-tree -r -M --name-status HEAD^ HEAD >actual && |
144 | grep "^R100..*path2/COPYING..*path1/path2/COPYING" actual && | |
145 | grep "^R100..*path2/README..*path1/path2/README" actual' | |
a1dad607 | 146 | |
41ac414e | 147 | test_expect_success \ |
ac64a722 | 148 | 'do not move directory over existing directory' \ |
d492b31c | 149 | 'mkdir path0 && mkdir path0/path2 && test_must_fail git mv path2 path0' |
ac64a722 | 150 | |
c5203bdf JS |
151 | test_expect_success \ |
152 | 'move into "."' \ | |
5be60078 | 153 | 'git mv path1/path2/ .' |
c5203bdf | 154 | |
4fddf579 JH |
155 | test_expect_success "Michael Cassar's test case" ' |
156 | rm -fr .git papers partA && | |
5c94f87e | 157 | git init && |
4fddf579 JH |
158 | mkdir -p papers/unsorted papers/all-papers partA && |
159 | echo a > papers/unsorted/Thesis.pdf && | |
160 | echo b > partA/outline.txt && | |
161 | echo c > papers/unsorted/_another && | |
162 | git add papers partA && | |
36b4697f | 163 | T1=$(git write-tree) && |
4fddf579 JH |
164 | |
165 | git mv papers/unsorted/Thesis.pdf papers/all-papers/moo-blah.pdf && | |
166 | ||
36b4697f | 167 | T=$(git write-tree) && |
a167ece0 | 168 | git ls-tree -r $T | verbose grep partA/outline.txt |
4fddf579 JH |
169 | ' |
170 | ||
aca085e5 JS |
171 | rm -fr papers partA path? |
172 | ||
173 | test_expect_success "Sergey Vlasov's test case" ' | |
174 | rm -fr .git && | |
5c94f87e | 175 | git init && |
aca085e5 JS |
176 | mkdir ab && |
177 | date >ab.c && | |
178 | date >ab/d && | |
179 | git add ab.c ab && | |
c76b84a1 | 180 | git commit -m "initial" && |
aca085e5 JS |
181 | git mv ab a |
182 | ' | |
183 | ||
744dacd3 JH |
184 | test_expect_success 'absolute pathname' '( |
185 | ||
186 | rm -fr mine && | |
187 | mkdir mine && | |
188 | cd mine && | |
189 | test_create_repo one && | |
190 | cd one && | |
191 | mkdir sub && | |
192 | >sub/file && | |
193 | git add sub/file && | |
194 | ||
195 | git mv sub "$(pwd)/in" && | |
196 | ! test -d sub && | |
197 | test -d in && | |
198 | git ls-files --error-unmatch in/file | |
199 | ||
200 | ||
201 | )' | |
202 | ||
203 | test_expect_success 'absolute pathname outside should fail' '( | |
204 | ||
205 | rm -fr mine && | |
206 | mkdir mine && | |
207 | cd mine && | |
208 | out=$(pwd) && | |
209 | test_create_repo one && | |
210 | cd one && | |
211 | mkdir sub && | |
212 | >sub/file && | |
213 | git add sub/file && | |
214 | ||
d492b31c | 215 | test_must_fail git mv sub "$out/out" && |
744dacd3 JH |
216 | test -d sub && |
217 | ! test -d ../in && | |
218 | git ls-files --error-unmatch sub/file | |
219 | ||
220 | )' | |
221 | ||
af82559b JH |
222 | test_expect_success 'git mv to move multiple sources into a directory' ' |
223 | rm -fr .git && git init && | |
224 | mkdir dir other && | |
225 | >dir/a.txt && | |
226 | >dir/b.txt && | |
227 | git add dir/?.txt && | |
228 | git mv dir/a.txt dir/b.txt other && | |
229 | git ls-files >actual && | |
230 | { echo other/a.txt; echo other/b.txt; } >expect && | |
231 | test_cmp expect actual | |
232 | ' | |
233 | ||
81dc2307 PB |
234 | test_expect_success 'git mv should not change sha1 of moved cache entry' ' |
235 | ||
236 | rm -fr .git && | |
237 | git init && | |
238 | echo 1 >dirty && | |
239 | git add dirty && | |
2dec68cf | 240 | entry="$(git ls-files --stage dirty | cut -f 1)" && |
81dc2307 PB |
241 | git mv dirty dirty2 && |
242 | [ "$entry" = "$(git ls-files --stage dirty2 | cut -f 1)" ] && | |
243 | echo 2 >dirty2 && | |
244 | git mv dirty2 dirty && | |
245 | [ "$entry" = "$(git ls-files --stage dirty | cut -f 1)" ] | |
246 | ||
247 | ' | |
248 | ||
249 | rm -f dirty dirty2 | |
250 | ||
9b906af6 CT |
251 | # NB: This test is about the error message |
252 | # as well as the failure. | |
253 | test_expect_success 'git mv error on conflicted file' ' | |
254 | rm -fr .git && | |
255 | git init && | |
256 | >conflict && | |
257 | test_when_finished "rm -f conflict" && | |
258 | cfhash=$(git hash-object -w conflict) && | |
259 | q_to_tab <<-EOF | git update-index --index-info && | |
260 | 0 $cfhash 0Qconflict | |
261 | 100644 $cfhash 1Qconflict | |
262 | EOF | |
263 | ||
264 | test_must_fail git mv conflict newname 2>actual && | |
265 | test_i18ngrep "conflicted" actual | |
266 | ' | |
267 | ||
889c6f0e | 268 | test_expect_success 'git mv should overwrite symlink to a file' ' |
81dc2307 PB |
269 | |
270 | rm -fr .git && | |
271 | git init && | |
272 | echo 1 >moved && | |
889c6f0e JS |
273 | test_ln_s_add moved symlink && |
274 | git add moved && | |
81dc2307 PB |
275 | test_must_fail git mv moved symlink && |
276 | git mv -f moved symlink && | |
277 | ! test -e moved && | |
278 | test -f symlink && | |
279 | test "$(cat symlink)" = 1 && | |
65c35b22 | 280 | git update-index --refresh && |
81dc2307 PB |
281 | git diff-files --quiet |
282 | ||
283 | ' | |
284 | ||
285 | rm -f moved symlink | |
286 | ||
889c6f0e | 287 | test_expect_success 'git mv should overwrite file with a symlink' ' |
81dc2307 PB |
288 | |
289 | rm -fr .git && | |
290 | git init && | |
291 | echo 1 >moved && | |
889c6f0e JS |
292 | test_ln_s_add moved symlink && |
293 | git add moved && | |
81dc2307 PB |
294 | test_must_fail git mv symlink moved && |
295 | git mv -f symlink moved && | |
296 | ! test -e symlink && | |
65c35b22 | 297 | git update-index --refresh && |
81dc2307 PB |
298 | git diff-files --quiet |
299 | ||
300 | ' | |
301 | ||
889c6f0e JS |
302 | test_expect_success SYMLINKS 'check moved symlink' ' |
303 | ||
304 | test -h moved | |
305 | ' | |
306 | ||
81dc2307 PB |
307 | rm -f moved symlink |
308 | ||
11502468 JL |
309 | test_expect_success 'setup submodule' ' |
310 | git commit -m initial && | |
311 | git reset --hard && | |
312 | git submodule add ./. sub && | |
313 | echo content >file && | |
314 | git add file && | |
fb8a4e80 | 315 | git commit -m "added sub and file" && |
2e3a16b2 VS |
316 | mkdir -p deep/directory/hierarchy && |
317 | git submodule add ./. deep/directory/hierarchy/sub && | |
a127331c | 318 | git commit -m "added another submodule" && |
fb8a4e80 | 319 | git branch submodule |
11502468 JL |
320 | ' |
321 | ||
322 | test_expect_success 'git mv cannot move a submodule in a file' ' | |
323 | test_must_fail git mv sub file | |
324 | ' | |
325 | ||
326 | test_expect_success 'git mv moves a submodule with a .git directory and no .gitmodules' ' | |
327 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
328 | git rm .gitmodules && | |
329 | ( | |
330 | cd sub && | |
331 | rm -f .git && | |
00764ca1 | 332 | cp -R -P -p ../.git/modules/sub .git && |
11502468 JL |
333 | GIT_WORK_TREE=. git config --unset core.worktree |
334 | ) && | |
335 | mkdir mod && | |
336 | git mv sub mod/sub && | |
337 | ! test -e sub && | |
338 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
339 | ( | |
340 | cd mod/sub && | |
341 | git status | |
342 | ) && | |
343 | git update-index --refresh && | |
344 | git diff-files --quiet | |
345 | ' | |
346 | ||
04c1ee57 JL |
347 | test_expect_success 'git mv moves a submodule with a .git directory and .gitmodules' ' |
348 | rm -rf mod && | |
349 | git reset --hard && | |
350 | git submodule update && | |
351 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
352 | ( | |
353 | cd sub && | |
354 | rm -f .git && | |
00764ca1 | 355 | cp -R -P -p ../.git/modules/sub .git && |
04c1ee57 JL |
356 | GIT_WORK_TREE=. git config --unset core.worktree |
357 | ) && | |
358 | mkdir mod && | |
359 | git mv sub mod/sub && | |
360 | ! test -e sub && | |
361 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
362 | ( | |
363 | cd mod/sub && | |
364 | git status | |
365 | ) && | |
366 | echo mod/sub >expected && | |
367 | git config -f .gitmodules submodule.sub.path >actual && | |
368 | test_cmp expected actual && | |
369 | git update-index --refresh && | |
370 | git diff-files --quiet | |
371 | ' | |
372 | ||
a88c915d | 373 | test_expect_success 'git mv moves a submodule with gitfile' ' |
2b2b1e4d | 374 | rm -rf mod && |
a88c915d JL |
375 | git reset --hard && |
376 | git submodule update && | |
377 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
2b2b1e4d | 378 | mkdir mod && |
a88c915d JL |
379 | ( |
380 | cd mod && | |
381 | git mv ../sub/ . | |
382 | ) && | |
383 | ! test -e sub && | |
384 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
385 | ( | |
386 | cd mod/sub && | |
387 | git status | |
388 | ) && | |
0656781f JL |
389 | echo mod/sub >expected && |
390 | git config -f .gitmodules submodule.sub.path >actual && | |
391 | test_cmp expected actual && | |
a88c915d JL |
392 | git update-index --refresh && |
393 | git diff-files --quiet | |
394 | ' | |
395 | ||
0656781f | 396 | test_expect_success 'mv does not complain when no .gitmodules file is found' ' |
2b2b1e4d | 397 | rm -rf mod && |
0656781f JL |
398 | git reset --hard && |
399 | git submodule update && | |
400 | git rm .gitmodules && | |
401 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
2b2b1e4d | 402 | mkdir mod && |
0656781f | 403 | git mv sub mod/sub 2>actual.err && |
ec10b018 | 404 | test_must_be_empty actual.err && |
0656781f JL |
405 | ! test -e sub && |
406 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
407 | ( | |
408 | cd mod/sub && | |
409 | git status | |
410 | ) && | |
411 | git update-index --refresh && | |
412 | git diff-files --quiet | |
413 | ' | |
414 | ||
415 | test_expect_success 'mv will error out on a modified .gitmodules file unless staged' ' | |
2b2b1e4d | 416 | rm -rf mod && |
0656781f JL |
417 | git reset --hard && |
418 | git submodule update && | |
419 | git config -f .gitmodules foo.bar true && | |
420 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
2b2b1e4d | 421 | mkdir mod && |
0656781f JL |
422 | test_must_fail git mv sub mod/sub 2>actual.err && |
423 | test -s actual.err && | |
424 | test -e sub && | |
425 | git diff-files --quiet -- sub && | |
426 | git add .gitmodules && | |
427 | git mv sub mod/sub 2>actual.err && | |
ec10b018 | 428 | test_must_be_empty actual.err && |
0656781f JL |
429 | ! test -e sub && |
430 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
431 | ( | |
432 | cd mod/sub && | |
433 | git status | |
434 | ) && | |
435 | git update-index --refresh && | |
436 | git diff-files --quiet | |
437 | ' | |
438 | ||
439 | test_expect_success 'mv issues a warning when section is not found in .gitmodules' ' | |
2b2b1e4d | 440 | rm -rf mod && |
0656781f JL |
441 | git reset --hard && |
442 | git submodule update && | |
443 | git config -f .gitmodules --remove-section submodule.sub && | |
444 | git add .gitmodules && | |
445 | entry="$(git ls-files --stage sub | cut -f 1)" && | |
446 | echo "warning: Could not find section in .gitmodules where path=sub" >expect.err && | |
2b2b1e4d | 447 | mkdir mod && |
0656781f | 448 | git mv sub mod/sub 2>actual.err && |
1108cea7 | 449 | test_cmp expect.err actual.err && |
0656781f JL |
450 | ! test -e sub && |
451 | [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && | |
452 | ( | |
453 | cd mod/sub && | |
454 | git status | |
455 | ) && | |
456 | git update-index --refresh && | |
457 | git diff-files --quiet | |
458 | ' | |
459 | ||
460 | test_expect_success 'mv --dry-run does not touch the submodule or .gitmodules' ' | |
2b2b1e4d | 461 | rm -rf mod && |
0656781f JL |
462 | git reset --hard && |
463 | git submodule update && | |
2b2b1e4d | 464 | mkdir mod && |
0656781f JL |
465 | git mv -n sub mod/sub 2>actual.err && |
466 | test -f sub/.git && | |
467 | git diff-index --exit-code HEAD && | |
468 | git update-index --refresh && | |
469 | git diff-files --quiet -- sub .gitmodules | |
470 | ' | |
471 | ||
1cbd1830 JL |
472 | test_expect_success 'checking out a commit before submodule moved needs manual updates' ' |
473 | git mv sub sub2 && | |
474 | git commit -m "moved sub to sub2" && | |
475 | git checkout -q HEAD^ 2>actual && | |
0a288d1e | 476 | test_i18ngrep "^warning: unable to rmdir '\''sub2'\'':" actual && |
1cbd1830 JL |
477 | git status -s sub2 >actual && |
478 | echo "?? sub2/" >expected && | |
479 | test_cmp expected actual && | |
480 | ! test -f sub/.git && | |
481 | test -f sub2/.git && | |
482 | git submodule update && | |
483 | test -f sub/.git && | |
484 | rm -rf sub2 && | |
485 | git diff-index --exit-code HEAD && | |
486 | git update-index --refresh && | |
487 | git diff-files --quiet -- sub .gitmodules && | |
488 | git status -s sub2 >actual && | |
ec10b018 | 489 | test_must_be_empty actual |
1cbd1830 JL |
490 | ' |
491 | ||
fb8a4e80 | 492 | test_expect_success 'mv -k does not accidentally destroy submodules' ' |
493 | git checkout submodule && | |
494 | mkdir dummy dest && | |
495 | git mv -k dummy sub dest && | |
496 | git status --porcelain >actual && | |
497 | grep "^R sub -> dest/sub" actual && | |
498 | git reset --hard && | |
499 | git checkout . | |
500 | ' | |
501 | ||
a127331c SB |
502 | test_expect_success 'moving a submodule in nested directories' ' |
503 | ( | |
504 | cd deep && | |
505 | git mv directory ../ && | |
506 | # git status would fail if the update of linking git dir to | |
507 | # work dir of the submodule failed. | |
508 | git status && | |
2e3a16b2 VS |
509 | git config -f ../.gitmodules submodule.deep/directory/hierarchy/sub.path >../actual && |
510 | echo "directory/hierarchy/sub" >../expect | |
a127331c | 511 | ) && |
9c5b2fab | 512 | test_cmp expect actual |
a127331c SB |
513 | ' |
514 | ||
da62f786 | 515 | test_expect_success 'moving nested submodules' ' |
c514167d HV |
516 | git commit -am "cleanup commit" && |
517 | mkdir sub_nested_nested && | |
518 | (cd sub_nested_nested && | |
519 | touch nested_level2 && | |
520 | git init && | |
521 | git add . && | |
522 | git commit -m "nested level 2" | |
523 | ) && | |
524 | mkdir sub_nested && | |
525 | (cd sub_nested && | |
526 | touch nested_level1 && | |
527 | git init && | |
528 | git add . && | |
e974e06d | 529 | git commit -m "nested level 1" && |
c514167d HV |
530 | git submodule add ../sub_nested_nested && |
531 | git commit -m "add nested level 2" | |
532 | ) && | |
533 | git submodule add ./sub_nested nested_move && | |
534 | git commit -m "add nested_move" && | |
535 | git submodule update --init --recursive && | |
536 | git mv nested_move sub_nested_moved && | |
537 | git status | |
538 | ' | |
539 | ||
8bf2c69c | 540 | test_done |