]> git.ipfire.org Git - thirdparty/git.git/blame - t/t1501-worktree.sh
checkout $tree $path: do not clobber local changes in $path not in $tree
[thirdparty/git.git] / t / t1501-worktree.sh
CommitLineData
3ae4a867
ML
1#!/bin/sh
2
3test_description='test separate work tree'
4. ./test-lib.sh
5
fc688759
JN
6test_expect_success 'setup' '
7 EMPTY_TREE=$(git write-tree) &&
8 EMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) &&
9 CHANGED_BLOB=$(echo changed | git hash-object -t blob --stdin) &&
10 ZEROES=0000000000000000000000000000000000000000 &&
11 EMPTY_BLOB7=$(echo $EMPTY_BLOB | sed "s/\(.......\).*/\1/") &&
12 CHANGED_BLOB7=$(echo $CHANGED_BLOB | sed "s/\(.......\).*/\1/") &&
13
14 mkdir -p work/sub/dir &&
15 mkdir -p work2 &&
16 mv .git repo.git
17'
18
19test_expect_success 'setup: helper for testing rev-parse' '
20 test_rev_parse() {
21 echo $1 >expected.bare &&
22 echo $2 >expected.inside-git &&
23 echo $3 >expected.inside-worktree &&
24 if test $# -ge 4
25 then
26 echo $4 >expected.prefix
27 fi &&
28
29 git rev-parse --is-bare-repository >actual.bare &&
30 git rev-parse --is-inside-git-dir >actual.inside-git &&
31 git rev-parse --is-inside-work-tree >actual.inside-worktree &&
32 if test $# -ge 4
33 then
34 git rev-parse --show-prefix >actual.prefix
35 fi &&
36
37 test_cmp expected.bare actual.bare &&
38 test_cmp expected.inside-git actual.inside-git &&
39 test_cmp expected.inside-worktree actual.inside-worktree &&
40 if test $# -ge 4
41 then
42 # rev-parse --show-prefix should output
43 # a single newline when at the top of the work tree,
44 # but we test for that separately.
45 test -z "$4" && ! test -s actual.prefix ||
46 test_cmp expected.prefix actual.prefix
47 fi
48 }
49'
50
51test_expect_success 'setup: core.worktree = relative path' '
52 unset GIT_WORK_TREE;
53 GIT_DIR=repo.git &&
54 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
55 export GIT_DIR GIT_CONFIG &&
56 git config core.worktree ../work
57'
58
59test_expect_success 'outside' '
60 test_rev_parse false false false
61'
62
63test_expect_success 'inside work tree' '
64 (
65 cd work &&
66 GIT_DIR=../repo.git &&
67 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
68 test_rev_parse false false true ""
69 )
70'
71
72test_expect_failure 'empty prefix is actually written out' '
73 echo >expected &&
74 (
75 cd work &&
76 GIT_DIR=../repo.git &&
77 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
78 git rev-parse --show-prefix >../actual
79 ) &&
80 test_cmp expected actual
81'
82
83test_expect_success 'subdir of work tree' '
84 (
85 cd work/sub/dir &&
86 GIT_DIR=../../../repo.git &&
87 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
88 test_rev_parse false false true sub/dir/
89 )
90'
91
92test_expect_success 'setup: core.worktree = absolute path' '
93 unset GIT_WORK_TREE;
94 GIT_DIR=$(pwd)/repo.git &&
95 GIT_CONFIG=$GIT_DIR/config &&
96 export GIT_DIR GIT_CONFIG &&
97 git config core.worktree "$(pwd)/work"
98'
99
100test_expect_success 'outside' '
101 test_rev_parse false false false &&
102 (
103 cd work2 &&
104 test_rev_parse false false false
105 )
106'
107
108test_expect_success 'inside work tree' '
109 (
110 cd work &&
111 test_rev_parse false false true ""
112 )
113'
114
115test_expect_success 'subdir of work tree' '
116 (
117 cd work/sub/dir &&
118 test_rev_parse false false true sub/dir/
119 )
120'
121
122test_expect_success 'setup: GIT_WORK_TREE=relative (override core.worktree)' '
123 GIT_DIR=$(pwd)/repo.git &&
124 GIT_CONFIG=$GIT_DIR/config &&
125 git config core.worktree non-existent &&
126 GIT_WORK_TREE=work &&
127 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
128'
129
130test_expect_success 'outside' '
131 test_rev_parse false false false &&
132 (
133 cd work2 &&
134 test_rev_parse false false false
135 )
136'
137
138test_expect_success 'inside work tree' '
139 (
140 cd work &&
141 GIT_WORK_TREE=. &&
142 test_rev_parse false false true ""
143 )
144'
145
146test_expect_success 'subdir of work tree' '
147 (
148 cd work/sub/dir &&
149 GIT_WORK_TREE=../.. &&
150 test_rev_parse false false true sub/dir/
151 )
152'
153
154test_expect_success 'setup: GIT_WORK_TREE=absolute, below git dir' '
155 mv work repo.git/work &&
156 mv work2 repo.git/work2 &&
157 GIT_DIR=$(pwd)/repo.git &&
158 GIT_CONFIG=$GIT_DIR/config &&
159 GIT_WORK_TREE=$(pwd)/repo.git/work &&
160 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
161'
162
163test_expect_success 'outside' '
164 echo outside &&
165 test_rev_parse false false false
166'
167
168test_expect_success 'in repo.git' '
169 (
170 cd repo.git &&
171 test_rev_parse false true false
172 ) &&
173 (
174 cd repo.git/objects &&
175 test_rev_parse false true false
176 ) &&
177 (
178 cd repo.git/work2 &&
179 test_rev_parse false true false
180 )
181'
182
183test_expect_success 'inside work tree' '
184 (
185 cd repo.git/work &&
186 test_rev_parse false true true ""
187 )
188'
189
190test_expect_success 'subdir of work tree' '
191 (
192 cd repo.git/work/sub/dir &&
193 test_rev_parse false true true sub/dir/
194 )
195'
196
197test_expect_success 'find work tree from repo' '
198 echo sub/dir/untracked >expected &&
199 cat <<-\EOF >repo.git/work/.gitignore &&
200 expected.*
201 actual.*
202 .gitignore
203 EOF
204 >repo.git/work/sub/dir/untracked &&
205 (
206 cd repo.git &&
207 git ls-files --others --exclude-standard >../actual
208 ) &&
209 test_cmp expected actual
210'
211
212test_expect_success 'find work tree from work tree' '
213 echo sub/dir/tracked >expected &&
214 >repo.git/work/sub/dir/tracked &&
215 (
216 cd repo.git/work/sub/dir &&
217 git --git-dir=../../.. add tracked
218 ) &&
219 (
220 cd repo.git &&
221 git ls-files >../actual
222 ) &&
223 test_cmp expected actual
e90fdc39
JS
224'
225
dd5c8af1 226test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
fc688759
JN
227 (
228 cd repo.git/work/sub/dir &&
229 GIT_DIR=../../.. &&
230 GIT_WORK_TREE=../.. &&
231 GIT_PAGER= &&
232 export GIT_DIR GIT_WORK_TREE GIT_PAGER &&
233
dd5c8af1 234 git diff --exit-code tracked &&
fc688759
JN
235 echo changed >tracked &&
236 test_must_fail git diff --exit-code tracked
237 )
238'
239
240test_expect_success 'diff-index respects work tree under .git dir' '
241 cat >diff-index-cached.expected <<-EOF &&
242 :000000 100644 $ZEROES $EMPTY_BLOB A sub/dir/tracked
243 EOF
244 cat >diff-index.expected <<-EOF &&
245 :000000 100644 $ZEROES $ZEROES A sub/dir/tracked
246 EOF
247
248 (
249 GIT_DIR=repo.git &&
250 GIT_WORK_TREE=repo.git/work &&
251 export GIT_DIR GIT_WORK_TREE &&
252 git diff-index $EMPTY_TREE >diff-index.actual &&
253 git diff-index --cached $EMPTY_TREE >diff-index-cached.actual
254 ) &&
255 test_cmp diff-index.expected diff-index.actual &&
256 test_cmp diff-index-cached.expected diff-index-cached.actual
257'
258
259test_expect_success 'diff-files respects work tree under .git dir' '
260 cat >diff-files.expected <<-EOF &&
261 :100644 100644 $EMPTY_BLOB $ZEROES M sub/dir/tracked
262 EOF
263
264 (
265 GIT_DIR=repo.git &&
266 GIT_WORK_TREE=repo.git/work &&
267 export GIT_DIR GIT_WORK_TREE &&
268 git diff-files >diff-files.actual
269 ) &&
270 test_cmp diff-files.expected diff-files.actual
271'
272
273test_expect_success 'git diff respects work tree under .git dir' '
274 cat >diff-TREE.expected <<-EOF &&
275 diff --git a/sub/dir/tracked b/sub/dir/tracked
276 new file mode 100644
277 index 0000000..$CHANGED_BLOB7
278 --- /dev/null
279 +++ b/sub/dir/tracked
280 @@ -0,0 +1 @@
281 +changed
282 EOF
283 cat >diff-TREE-cached.expected <<-EOF &&
284 diff --git a/sub/dir/tracked b/sub/dir/tracked
285 new file mode 100644
286 index 0000000..$EMPTY_BLOB7
287 EOF
288 cat >diff-FILES.expected <<-EOF &&
289 diff --git a/sub/dir/tracked b/sub/dir/tracked
290 index $EMPTY_BLOB7..$CHANGED_BLOB7 100644
291 --- a/sub/dir/tracked
292 +++ b/sub/dir/tracked
293 @@ -0,0 +1 @@
294 +changed
295 EOF
296
297 (
298 GIT_DIR=repo.git &&
299 GIT_WORK_TREE=repo.git/work &&
300 export GIT_DIR GIT_WORK_TREE &&
301 git diff $EMPTY_TREE >diff-TREE.actual &&
302 git diff --cached $EMPTY_TREE >diff-TREE-cached.actual &&
303 git diff >diff-FILES.actual
304 ) &&
305 test_cmp diff-TREE.expected diff-TREE.actual &&
306 test_cmp diff-TREE-cached.expected diff-TREE-cached.actual &&
307 test_cmp diff-FILES.expected diff-FILES.actual
dd5c8af1
JS
308'
309
6577f542 310test_expect_success 'git grep' '
fc688759
JN
311 echo dir/tracked >expected.grep &&
312 (
313 cd repo.git/work/sub &&
314 GIT_DIR=../.. &&
315 GIT_WORK_TREE=.. &&
316 export GIT_DIR GIT_WORK_TREE &&
317 git grep -l changed >../../../actual.grep
318 ) &&
319 test_cmp expected.grep actual.grep
6577f542
NTND
320'
321
b3100fd5
JH
322test_expect_success 'git commit' '
323 (
324 cd repo.git &&
325 GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done
326 )
327'
328
329test_expect_success 'absolute pathspec should fail gracefully' '
330 (
fc688759
JN
331 cd repo.git &&
332 test_might_fail git config --unset core.worktree &&
b3100fd5
JH
333 test_must_fail git log HEAD -- /home
334 )
335'
336
288123f0 337test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
fc688759 338 >dummy_file
288123f0
JH
339 echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file &&
340 git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
341'
342
0ed74813
NTND
343test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
344 GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
345 test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
e6ec2b6a 346 echo "$(pwd)/repo.git/work" >expected &&
0ed74813
NTND
347 test_cmp expected actual
348'
349
3ae4a867 350test_done