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