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