]> git.ipfire.org Git - thirdparty/git.git/blob - t/t1501-work-tree.sh
The second batch
[thirdparty/git.git] / t / t1501-work-tree.sh
1 #!/bin/sh
2
3 test_description='test separate work tree'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success 'setup' '
9 EMPTY_TREE=$(git write-tree) &&
10 EMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) &&
11 CHANGED_BLOB=$(echo changed | git hash-object -t blob --stdin) &&
12 EMPTY_BLOB7=$(echo $EMPTY_BLOB | sed "s/\(.......\).*/\1/") &&
13 CHANGED_BLOB7=$(echo $CHANGED_BLOB | sed "s/\(.......\).*/\1/") &&
14
15 mkdir -p work/sub/dir &&
16 mkdir -p work2 &&
17 mv .git repo.git
18 '
19
20 test_expect_success 'setup: helper for testing rev-parse' '
21 test_rev_parse() {
22 echo $1 >expected.bare &&
23 echo $2 >expected.inside-git &&
24 echo $3 >expected.inside-worktree &&
25 if test $# -ge 4
26 then
27 echo $4 >expected.prefix
28 fi &&
29
30 git rev-parse --is-bare-repository >actual.bare &&
31 git rev-parse --is-inside-git-dir >actual.inside-git &&
32 git rev-parse --is-inside-work-tree >actual.inside-worktree &&
33 if test $# -ge 4
34 then
35 git rev-parse --show-prefix >actual.prefix
36 fi &&
37
38 test_cmp expected.bare actual.bare &&
39 test_cmp expected.inside-git actual.inside-git &&
40 test_cmp expected.inside-worktree actual.inside-worktree &&
41 if test $# -ge 4
42 then
43 # rev-parse --show-prefix should output
44 # a single newline when at the top of the work tree,
45 # but we test for that separately.
46 test -z "$4" && test_must_be_empty actual.prefix ||
47 test_cmp expected.prefix actual.prefix
48 fi
49 }
50 '
51
52 test_expect_success 'setup: core.worktree = relative path' '
53 sane_unset GIT_WORK_TREE &&
54 GIT_DIR=repo.git &&
55 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
56 export GIT_DIR GIT_CONFIG &&
57 git config core.worktree ../work
58 '
59
60 test_expect_success 'outside' '
61 test_rev_parse false false false
62 '
63
64 test_expect_success 'inside work tree' '
65 (
66 cd work &&
67 GIT_DIR=../repo.git &&
68 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
69 test_rev_parse false false true ""
70 )
71 '
72
73 test_expect_success 'empty prefix is actually written out' '
74 echo >expected &&
75 (
76 cd work &&
77 GIT_DIR=../repo.git &&
78 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
79 git rev-parse --show-prefix >../actual
80 ) &&
81 test_cmp expected actual
82 '
83
84 test_expect_success 'subdir of work tree' '
85 (
86 cd work/sub/dir &&
87 GIT_DIR=../../../repo.git &&
88 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
89 test_rev_parse false false true sub/dir/
90 )
91 '
92
93 test_expect_success 'setup: core.worktree = absolute path' '
94 sane_unset GIT_WORK_TREE &&
95 GIT_DIR=$(pwd)/repo.git &&
96 GIT_CONFIG=$GIT_DIR/config &&
97 export GIT_DIR GIT_CONFIG &&
98 git config core.worktree "$(pwd)/work"
99 '
100
101 test_expect_success 'outside' '
102 test_rev_parse false false false &&
103 (
104 cd work2 &&
105 test_rev_parse false false false
106 )
107 '
108
109 test_expect_success 'inside work tree' '
110 (
111 cd work &&
112 test_rev_parse false false true ""
113 )
114 '
115
116 test_expect_success 'subdir of work tree' '
117 (
118 cd work/sub/dir &&
119 test_rev_parse false false true sub/dir/
120 )
121 '
122
123 test_expect_success 'setup: GIT_WORK_TREE=relative (override core.worktree)' '
124 GIT_DIR=$(pwd)/repo.git &&
125 GIT_CONFIG=$GIT_DIR/config &&
126 git config core.worktree non-existent &&
127 GIT_WORK_TREE=work &&
128 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
129 '
130
131 test_expect_success 'outside' '
132 test_rev_parse false false false &&
133 (
134 cd work2 &&
135 test_rev_parse false false false
136 )
137 '
138
139 test_expect_success 'inside work tree' '
140 (
141 cd work &&
142 GIT_WORK_TREE=. &&
143 test_rev_parse false false true ""
144 )
145 '
146
147 test_expect_success 'subdir of work tree' '
148 (
149 cd work/sub/dir &&
150 GIT_WORK_TREE=../.. &&
151 test_rev_parse false false true sub/dir/
152 )
153 '
154
155 test_expect_success 'setup: GIT_WORK_TREE=absolute, below git dir' '
156 mv work repo.git/work &&
157 mv work2 repo.git/work2 &&
158 GIT_DIR=$(pwd)/repo.git &&
159 GIT_CONFIG=$GIT_DIR/config &&
160 GIT_WORK_TREE=$(pwd)/repo.git/work &&
161 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
162 '
163
164 test_expect_success 'outside' '
165 echo outside &&
166 test_rev_parse false false false
167 '
168
169 test_expect_success 'in repo.git' '
170 (
171 cd repo.git &&
172 test_rev_parse false true false
173 ) &&
174 (
175 cd repo.git/objects &&
176 test_rev_parse false true false
177 ) &&
178 (
179 cd repo.git/work2 &&
180 test_rev_parse false true false
181 )
182 '
183
184 test_expect_success 'inside work tree' '
185 (
186 cd repo.git/work &&
187 test_rev_parse false true true ""
188 )
189 '
190
191 test_expect_success 'subdir of work tree' '
192 (
193 cd repo.git/work/sub/dir &&
194 test_rev_parse false true true sub/dir/
195 )
196 '
197
198 test_expect_success 'find work tree from repo' '
199 echo sub/dir/untracked >expected &&
200 cat <<-\EOF >repo.git/work/.gitignore &&
201 expected.*
202 actual.*
203 .gitignore
204 EOF
205 >repo.git/work/sub/dir/untracked &&
206 (
207 cd repo.git &&
208 git ls-files --others --exclude-standard >../actual
209 ) &&
210 test_cmp expected actual
211 '
212
213 test_expect_success 'find work tree from work tree' '
214 echo sub/dir/tracked >expected &&
215 >repo.git/work/sub/dir/tracked &&
216 (
217 cd repo.git/work/sub/dir &&
218 git --git-dir=../../.. add tracked
219 ) &&
220 (
221 cd repo.git &&
222 git ls-files >../actual
223 ) &&
224 test_cmp expected actual
225 '
226
227 test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
228 (
229 cd repo.git/work/sub/dir &&
230 GIT_DIR=../../.. &&
231 GIT_WORK_TREE=../.. &&
232 GIT_PAGER= &&
233 export GIT_DIR GIT_WORK_TREE GIT_PAGER &&
234
235 git diff --exit-code tracked &&
236 echo changed >tracked &&
237 test_must_fail git diff --exit-code tracked
238 )
239 '
240
241 test_expect_success 'diff-index respects work tree under .git dir' '
242 cat >diff-index-cached.expected <<-EOF &&
243 :000000 100644 $ZERO_OID $EMPTY_BLOB A sub/dir/tracked
244 EOF
245 cat >diff-index.expected <<-EOF &&
246 :000000 100644 $ZERO_OID $ZERO_OID A sub/dir/tracked
247 EOF
248
249 (
250 GIT_DIR=repo.git &&
251 GIT_WORK_TREE=repo.git/work &&
252 export GIT_DIR GIT_WORK_TREE &&
253 git diff-index $EMPTY_TREE >diff-index.actual &&
254 git diff-index --cached $EMPTY_TREE >diff-index-cached.actual
255 ) &&
256 test_cmp diff-index.expected diff-index.actual &&
257 test_cmp diff-index-cached.expected diff-index-cached.actual
258 '
259
260 test_expect_success 'diff-files respects work tree under .git dir' '
261 cat >diff-files.expected <<-EOF &&
262 :100644 100644 $EMPTY_BLOB $ZERO_OID M sub/dir/tracked
263 EOF
264
265 (
266 GIT_DIR=repo.git &&
267 GIT_WORK_TREE=repo.git/work &&
268 export GIT_DIR GIT_WORK_TREE &&
269 git diff-files >diff-files.actual
270 ) &&
271 test_cmp diff-files.expected diff-files.actual
272 '
273
274 test_expect_success 'git diff respects work tree under .git dir' '
275 cat >diff-TREE.expected <<-EOF &&
276 diff --git a/sub/dir/tracked b/sub/dir/tracked
277 new file mode 100644
278 index 0000000..$CHANGED_BLOB7
279 --- /dev/null
280 +++ b/sub/dir/tracked
281 @@ -0,0 +1 @@
282 +changed
283 EOF
284 cat >diff-TREE-cached.expected <<-EOF &&
285 diff --git a/sub/dir/tracked b/sub/dir/tracked
286 new file mode 100644
287 index 0000000..$EMPTY_BLOB7
288 EOF
289 cat >diff-FILES.expected <<-EOF &&
290 diff --git a/sub/dir/tracked b/sub/dir/tracked
291 index $EMPTY_BLOB7..$CHANGED_BLOB7 100644
292 --- a/sub/dir/tracked
293 +++ b/sub/dir/tracked
294 @@ -0,0 +1 @@
295 +changed
296 EOF
297
298 (
299 GIT_DIR=repo.git &&
300 GIT_WORK_TREE=repo.git/work &&
301 export GIT_DIR GIT_WORK_TREE &&
302 git diff $EMPTY_TREE >diff-TREE.actual &&
303 git diff --cached $EMPTY_TREE >diff-TREE-cached.actual &&
304 git diff >diff-FILES.actual
305 ) &&
306 test_cmp diff-TREE.expected diff-TREE.actual &&
307 test_cmp diff-TREE-cached.expected diff-TREE-cached.actual &&
308 test_cmp diff-FILES.expected diff-FILES.actual
309 '
310
311 test_expect_success 'git grep' '
312 echo dir/tracked >expected.grep &&
313 (
314 cd repo.git/work/sub &&
315 GIT_DIR=../.. &&
316 GIT_WORK_TREE=.. &&
317 export GIT_DIR GIT_WORK_TREE &&
318 git grep -l changed >../../../actual.grep
319 ) &&
320 test_cmp expected.grep actual.grep
321 '
322
323 test_expect_success 'git commit' '
324 (
325 cd repo.git &&
326 GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done
327 )
328 '
329
330 test_expect_success 'absolute pathspec should fail gracefully' '
331 (
332 cd repo.git &&
333 test_might_fail git config --unset core.worktree &&
334 test_must_fail git log HEAD -- /home
335 )
336 '
337
338 test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
339 >dummy_file &&
340 echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file &&
341 git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
342 '
343
344 test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
345 GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
346 test-tool subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
347 echo "$(pwd)/repo.git/work" >expected &&
348 test_cmp expected actual
349 '
350
351 test_expect_success 'Multi-worktree setup' '
352 mkdir work &&
353 mkdir -p repo.git/repos/foo &&
354 cp repo.git/HEAD repo.git/index repo.git/repos/foo &&
355 { cp repo.git/sharedindex.* repo.git/repos/foo || :; } &&
356 sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE
357 '
358
359 test_expect_success 'GIT_DIR set (1)' '
360 echo "gitdir: repo.git/repos/foo" >gitfile &&
361 echo ../.. >repo.git/repos/foo/commondir &&
362 (
363 cd work &&
364 GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
365 test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
366 test_cmp expect actual
367 )
368 '
369
370 test_expect_success 'GIT_DIR set (2)' '
371 echo "gitdir: repo.git/repos/foo" >gitfile &&
372 echo "$(pwd)/repo.git" >repo.git/repos/foo/commondir &&
373 (
374 cd work &&
375 GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
376 test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
377 test_cmp expect actual
378 )
379 '
380
381 test_expect_success 'Auto discovery' '
382 echo "gitdir: repo.git/repos/foo" >.git &&
383 echo ../.. >repo.git/repos/foo/commondir &&
384 (
385 cd work &&
386 git rev-parse --git-common-dir >actual &&
387 test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
388 test_cmp expect actual &&
389 echo haha >data1 &&
390 git add data1 &&
391 git ls-files --full-name :/ | grep data1 >actual &&
392 echo work/data1 >expect &&
393 test_cmp expect actual
394 )
395 '
396
397 test_expect_success '$GIT_DIR/common overrides core.worktree' '
398 mkdir elsewhere &&
399 git --git-dir=repo.git config core.worktree "$TRASH_DIRECTORY/elsewhere" &&
400 echo "gitdir: repo.git/repos/foo" >.git &&
401 echo ../.. >repo.git/repos/foo/commondir &&
402 (
403 cd work &&
404 git rev-parse --git-common-dir >actual &&
405 test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
406 test_cmp expect actual &&
407 echo haha >data2 &&
408 git add data2 &&
409 git ls-files --full-name :/ | grep data2 >actual &&
410 echo work/data2 >expect &&
411 test_cmp expect actual
412 )
413 '
414
415 test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' '
416 echo "gitdir: repo.git/repos/foo" >.git &&
417 echo ../.. >repo.git/repos/foo/commondir &&
418 (
419 cd work &&
420 echo haha >data3 &&
421 git --git-dir=../.git --work-tree=. add data3 &&
422 git ls-files --full-name -- :/ | grep data3 >actual &&
423 echo data3 >expect &&
424 test_cmp expect actual
425 )
426 '
427
428 test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' '
429 (
430 GIT_WORK_TREE=/.invalid/work/tree &&
431 export GIT_WORK_TREE &&
432 test_expect_code 128 git rev-parse
433 )
434 '
435
436 test_expect_success 'refs work with relative gitdir and work tree' '
437 git init relative &&
438 git -C relative commit --allow-empty -m one &&
439 git -C relative commit --allow-empty -m two &&
440
441 GIT_DIR=relative/.git GIT_WORK_TREE=relative git reset HEAD^ &&
442
443 git -C relative log -1 --format=%s >actual &&
444 echo one >expect &&
445 test_cmp expect actual
446 '
447
448 test_done