1#!/bin/sh 2 3test_description='test git worktree move, remove, lock and unlock' 4 5. ./test-lib.sh 6 7test_expect_success 'setup' ' 8 test_commit init && 9 git worktree add source && 10 git worktree list --porcelain >out && 11 grep "^worktree" out >actual && 12 cat <<-EOF >expected && 13 worktree $(pwd) 14 worktree $(pwd)/source 15 EOF 16 test_cmp expected actual 17' 18 19test_expect_success 'lock main worktree' ' 20 test_must_fail git worktree lock . 21' 22 23test_expect_success 'lock linked worktree' ' 24 git worktree lock --reason hahaha source && 25 echo hahaha >expected && 26 test_cmp expected .git/worktrees/source/locked 27' 28 29test_expect_success 'lock linked worktree from another worktree' ' 30 rm .git/worktrees/source/locked && 31 git worktree add elsewhere && 32 git -C elsewhere worktree lock --reason hahaha ../source && 33 echo hahaha >expected && 34 test_cmp expected .git/worktrees/source/locked 35' 36 37test_expect_success 'lock worktree twice' ' 38 test_must_fail git worktree lock source && 39 echo hahaha >expected && 40 test_cmp expected .git/worktrees/source/locked 41' 42 43test_expect_success 'lock worktree twice (from the locked worktree)' ' 44 test_must_fail git -C source worktree lock . && 45 echo hahaha >expected && 46 test_cmp expected .git/worktrees/source/locked 47' 48 49test_expect_success 'unlock main worktree' ' 50 test_must_fail git worktree unlock . 51' 52 53test_expect_success 'unlock linked worktree' ' 54 git worktree unlock source && 55 test_path_is_missing .git/worktrees/source/locked 56' 57 58test_expect_success 'unlock worktree twice' ' 59 test_must_fail git worktree unlock source && 60 test_path_is_missing .git/worktrees/source/locked 61' 62 63test_expect_success 'move non-worktree' ' 64 mkdir abc && 65 test_must_fail git worktree move abc def 66' 67 68test_expect_success 'move locked worktree' ' 69 git worktree lock source && 70 test_when_finished "git worktree unlock source" && 71 test_must_fail git worktree move source destination 72' 73 74test_expect_success 'move worktree' ' 75 git worktree move source destination && 76 test_path_is_missing source && 77 git worktree list --porcelain >out && 78 grep "^worktree.*/destination$" out && 79 ! grep "^worktree.*/source$" out && 80 git -C destination log --format=%s >actual2 && 81 echo init >expected2 && 82 test_cmp expected2 actual2 83' 84 85test_expect_success 'move main worktree' ' 86 test_must_fail git worktree move . def 87' 88 89test_expect_success 'move worktree to another dir' ' 90 mkdir some-dir && 91 git worktree move destination some-dir && 92 test_when_finished "git worktree move some-dir/destination destination" && 93 test_path_is_missing destination && 94 git worktree list --porcelain >out && 95 grep "^worktree.*/some-dir/destination$" out && 96 git -C some-dir/destination log --format=%s >actual2 && 97 echo init >expected2 && 98 test_cmp expected2 actual2 99' 100 101test_expect_success 'move locked worktree (force)' ' 102 test_when_finished " 103 git worktree unlock flump || : 104 git worktree remove flump || : 105 git worktree unlock ploof || : 106 git worktree remove ploof || : 107 " && 108 git worktree add --detach flump && 109 git worktree lock flump && 110 test_must_fail git worktree move flump ploof" && 111 test_must_fail git worktree move --force flump ploof" && 112 git worktree move --force --force flump ploof 113' 114 115test_expect_success 'refuse to move worktree atop existing path' ' 116 >bobble && 117 git worktree add --detach beeble && 118 test_must_fail git worktree move beeble bobble 119' 120 121test_expect_success 'move atop existing but missing worktree' ' 122 git worktree add --detach gnoo && 123 git worktree add --detach pneu && 124 rm -fr pneu && 125 test_must_fail git worktree move gnoo pneu && 126 git worktree move --force gnoo pneu && 127 128 git worktree add --detach nu && 129 git worktree lock nu && 130 rm -fr nu && 131 test_must_fail git worktree move pneu nu && 132 test_must_fail git worktree --force move pneu nu && 133 git worktree move --force --force pneu nu 134' 135 136test_expect_success 'move a repo with uninitialized submodule' ' 137 git init withsub && 138 ( 139 cd withsub && 140 test_commit initial && 141 git submodule add "$PWD"/.git sub && 142 git commit -m withsub && 143 git worktree add second HEAD && 144 git worktree move second third 145 ) 146' 147 148test_expect_success 'not move a repo with initialized submodule' ' 149 ( 150 cd withsub && 151 git -C third submodule update && 152 test_must_fail git worktree move third forth 153 ) 154' 155 156test_expect_success 'remove main worktree' ' 157 test_must_fail git worktree remove . 158' 159 160test_expect_success 'remove locked worktree' ' 161 git worktree lock destination && 162 test_when_finished "git worktree unlock destination" && 163 test_must_fail git worktree remove destination 164' 165 166test_expect_success 'remove worktree with dirty tracked file' ' 167 echo dirty >>destination/init.t && 168 test_when_finished "git -C destination checkout init.t" && 169 test_must_fail git worktree remove destination 170' 171 172test_expect_success 'remove worktree with untracked file' ' 173 : >destination/untracked && 174 test_must_fail git worktree remove destination 175' 176 177test_expect_success 'force remove worktree with untracked file' ' 178 git worktree remove --force destination && 179 test_path_is_missing destination 180' 181 182test_expect_success 'remove missing worktree' ' 183 git worktree add to-be-gone && 184 test -d .git/worktrees/to-be-gone && 185 mv to-be-gone gone && 186 git worktree remove to-be-gone && 187 test_path_is_missing .git/worktrees/to-be-gone 188' 189 190test_expect_success 'NOT remove missing-but-locked worktree' ' 191 git worktree add gone-but-locked && 192 git worktree lock gone-but-locked && 193 test -d .git/worktrees/gone-but-locked && 194 mv gone-but-locked really-gone-now && 195 test_must_fail git worktree remove gone-but-locked && 196 test_path_is_dir .git/worktrees/gone-but-locked 197' 198 199test_expect_success 'proper error when worktree not found' ' 200 for i in noodle noodle/bork 201 do 202 test_must_fail git worktree lock $i 2>err && 203 test_i18ngrep "not a working tree" err || return 1 204 done 205' 206 207test_expect_success 'remove locked worktree (force)' ' 208 git worktree add --detach gumby && 209 test_when_finished "git worktree remove gumby || :" && 210 git worktree lock gumby && 211 test_when_finished "git worktree unlock gumby || :" && 212 test_must_fail git worktree remove gumby && 213 test_must_fail git worktree remove --force gumby && 214 git worktree remove --force --force gumby 215' 216 217test_expect_success 'remove cleans up .git/worktrees when empty' ' 218 git init moog && 219 ( 220 cd moog && 221 test_commit bim && 222 git worktree add --detach goom && 223 test_path_exists .git/worktrees && 224 git worktree remove goom && 225 test_path_is_missing .git/worktrees 226 ) 227' 228 229test_expect_success 'remove a repo with uninitialized submodule' ' 230 ( 231 cd withsub && 232 git worktree add to-remove HEAD && 233 git worktree remove to-remove 234 ) 235' 236 237test_expect_success 'not remove a repo with initialized submodule' ' 238 ( 239 cd withsub && 240 git worktree add to-remove HEAD && 241 git -C to-remove submodule update && 242 test_must_fail git worktree remove to-remove 243 ) 244' 245 246test_done 247