]>
Commit | Line | Data |
---|---|---|
3ae4a867 ML |
1 | #!/bin/sh |
2 | ||
3 | test_description='test separate work tree' | |
03267e86 ÆAB |
4 | |
5 | TEST_PASSES_SANITIZE_LEAK=true | |
3ae4a867 ML |
6 | . ./test-lib.sh |
7 | ||
fc688759 JN |
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) && | |
fc688759 JN |
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. | |
ec10b018 | 46 | test -z "$4" && test_must_be_empty actual.prefix || |
fc688759 JN |
47 | test_cmp expected.prefix actual.prefix |
48 | fi | |
49 | } | |
50 | ' | |
51 | ||
52 | test_expect_success 'setup: core.worktree = relative path' ' | |
7f9a5fc6 | 53 | sane_unset GIT_WORK_TREE && |
fc688759 JN |
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 | ||
658219f1 | 73 | test_expect_success 'empty prefix is actually written out' ' |
fc688759 JN |
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' ' | |
7f9a5fc6 | 94 | sane_unset GIT_WORK_TREE && |
fc688759 JN |
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 | |
e90fdc39 JS |
225 | ' |
226 | ||
dd5c8af1 | 227 | test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' |
fc688759 JN |
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 | ||
dd5c8af1 | 235 | git diff --exit-code tracked && |
fc688759 JN |
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 && | |
8125a58b | 243 | :000000 100644 $ZERO_OID $EMPTY_BLOB A sub/dir/tracked |
fc688759 JN |
244 | EOF |
245 | cat >diff-index.expected <<-EOF && | |
8125a58b | 246 | :000000 100644 $ZERO_OID $ZERO_OID A sub/dir/tracked |
fc688759 JN |
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 && | |
8125a58b | 262 | :100644 100644 $EMPTY_BLOB $ZERO_OID M sub/dir/tracked |
fc688759 JN |
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 | |
dd5c8af1 JS |
309 | ' |
310 | ||
6577f542 | 311 | test_expect_success 'git grep' ' |
fc688759 JN |
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 | |
6577f542 NTND |
321 | ' |
322 | ||
b3100fd5 JH |
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 | ( | |
fc688759 JN |
332 | cd repo.git && |
333 | test_might_fail git config --unset core.worktree && | |
b3100fd5 JH |
334 | test_must_fail git log HEAD -- /home |
335 | ) | |
336 | ' | |
337 | ||
288123f0 | 338 | test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' |
7f9a5fc6 | 339 | >dummy_file && |
288123f0 JH |
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 | ||
0ed74813 NTND |
344 | test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' |
345 | GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \ | |
112edd6a | 346 | test-tool subprocess --setup-work-tree rev-parse --show-toplevel >actual && |
e6ec2b6a | 347 | echo "$(pwd)/repo.git/work" >expected && |
0ed74813 NTND |
348 | test_cmp expected actual |
349 | ' | |
350 | ||
31e26ebc NTND |
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 && | |
10812c23 | 355 | { cp repo.git/sharedindex.* repo.git/repos/foo || :; } && |
31e26ebc NTND |
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 && | |
b8d5cf4f | 365 | test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && |
31e26ebc NTND |
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 && | |
b8d5cf4f | 376 | test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && |
31e26ebc NTND |
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 && | |
b8d5cf4f | 387 | test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && |
31e26ebc NTND |
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 && | |
b8d5cf4f | 405 | test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && |
31e26ebc NTND |
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 | ||
ce83eadd | 428 | test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' ' |
aac3eaa6 JS |
429 | ( |
430 | GIT_WORK_TREE=/.invalid/work/tree && | |
431 | export GIT_WORK_TREE && | |
432 | test_expect_code 128 git rev-parse | |
433 | ) | |
434 | ' | |
435 | ||
fb9c2d27 JK |
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 | ||
3ae4a867 | 448 | test_done |