Merge branch 'maint'
[git] / t / t1510-repo-setup.sh
1 #!/bin/sh
2
3 test_description="Tests of cwd/prefix/worktree/gitdir setup in all cases
4
5 A few rules for repo setup:
6
7 1. GIT_DIR is relative to user's cwd. --git-dir is equivalent to
8    GIT_DIR.
9
10 2. .git file is relative to parent directory. .git file is basically
11    symlink in disguise. The directory where .git file points to will
12    become new git_dir.
13
14 3. core.worktree is relative to git_dir.
15
16 4. GIT_WORK_TREE is relative to user's cwd. --work-tree is
17    equivalent to GIT_WORK_TREE.
18
19 5. GIT_WORK_TREE/core.worktree was originally meant to work only if
20    GIT_DIR is set, but earlier git didn't enforce it, and some scripts
21    depend on the implementation that happened to first discover .git by
22    going up from the users $cwd and then using the specified working tree
23    that may or may not have any relation to where .git was found in.  This
24    historical behaviour must be kept.
25
26 6. Effective GIT_WORK_TREE overrides core.worktree and core.bare
27
28 7. Effective core.worktree conflicts with core.bare
29
30 8. If GIT_DIR is set but neither worktree nor bare setting is given,
31    original cwd becomes worktree.
32
33 9. If .git discovery is done inside a repo, the repo becomes a bare
34    repo. .git discovery is performed if GIT_DIR is not set.
35
36 10. If no worktree is available, cwd remains unchanged, prefix is
37     NULL.
38
39 11. When user's cwd is outside worktree, cwd remains unchanged,
40     prefix is NULL.
41 "
42 . ./test-lib.sh
43
44 here=$(pwd)
45
46 test_repo () {
47         (
48                 cd "$1" &&
49                 if test -n "$2"
50                 then
51                         GIT_DIR="$2" &&
52                         export GIT_DIR
53                 fi &&
54                 if test -n "$3"
55                 then
56                         GIT_WORK_TREE="$3" &&
57                         export GIT_WORK_TREE
58                 fi &&
59                 rm -f trace &&
60                 GIT_TRACE_SETUP="$(pwd)/trace" git symbolic-ref HEAD >/dev/null &&
61                 grep '^setup: ' trace >result &&
62                 test_cmp expected result
63         )
64 }
65
66 maybe_config () {
67         file=$1 var=$2 value=$3 &&
68         if test "$value" != unset
69         then
70                 git config --file="$file" "$var" "$value"
71         fi
72 }
73
74 setup_repo () {
75         name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
76         sane_unset GIT_DIR GIT_WORK_TREE &&
77
78         git init "$name" &&
79         maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
80         maybe_config "$name/.git/config" core.bare "$barecfg" &&
81         mkdir -p "$name/sub/sub" &&
82
83         if test "${gitfile:+set}"
84         then
85                 mv "$name/.git" "$name.git" &&
86                 echo "gitdir: ../$name.git" >"$name/.git"
87         fi
88 }
89
90 maybe_set () {
91         var=$1 value=$2 &&
92         if test "$value" != unset
93         then
94                 eval "$var=\$value" &&
95                 export $var
96         fi
97 }
98
99 setup_env () {
100         worktreenv=$1 gitdirenv=$2 &&
101         sane_unset GIT_DIR GIT_WORK_TREE &&
102         maybe_set GIT_DIR "$gitdirenv" &&
103         maybe_set GIT_WORK_TREE "$worktreeenv"
104 }
105
106 expect () {
107         cat >"$1/expected" <<-EOF
108         setup: git_dir: $2
109         setup: worktree: $3
110         setup: cwd: $4
111         setup: prefix: $5
112         EOF
113 }
114
115 try_case () {
116         name=$1 worktreeenv=$2 gitdirenv=$3 &&
117         setup_env "$worktreeenv" "$gitdirenv" &&
118         expect "$name" "$4" "$5" "$6" "$7" &&
119         test_repo "$name"
120 }
121
122 run_wt_tests () {
123         N=$1 gitfile=$2
124
125         absgit="$here/$N/.git"
126         dotgit=.git
127         dotdotgit=../../.git
128
129         if test "$gitfile"
130         then
131                 absgit="$here/$N.git"
132                 dotgit=$absgit dotdotgit=$absgit
133         fi
134
135         test_expect_success "#$N: explicit GIT_WORK_TREE and GIT_DIR at toplevel" '
136                 try_case $N "$here/$N" .git \
137                         "$dotgit" "$here/$N" "$here/$N" "(null)" &&
138                 try_case $N . .git \
139                         "$dotgit" "$here/$N" "$here/$N" "(null)" &&
140                 try_case $N "$here/$N" "$here/$N/.git" \
141                         "$absgit" "$here/$N" "$here/$N" "(null)" &&
142                 try_case $N . "$here/$N/.git" \
143                         "$absgit" "$here/$N" "$here/$N" "(null)"
144         '
145
146         test_expect_success "#$N: explicit GIT_WORK_TREE and GIT_DIR in subdir" '
147                 try_case $N/sub/sub "$here/$N" ../../.git \
148                         "$absgit" "$here/$N" "$here/$N" sub/sub/ &&
149                 try_case $N/sub/sub ../.. ../../.git \
150                         "$absgit" "$here/$N" "$here/$N" sub/sub/ &&
151                 try_case $N/sub/sub "$here/$N" "$here/$N/.git" \
152                         "$absgit" "$here/$N" "$here/$N" sub/sub/ &&
153                 try_case $N/sub/sub ../.. "$here/$N/.git" \
154                         "$absgit" "$here/$N" "$here/$N" sub/sub/
155         '
156
157         test_expect_success "#$N: explicit GIT_WORK_TREE from parent of worktree" '
158                 try_case $N "$here/$N/wt" .git \
159                         "$dotgit" "$here/$N/wt" "$here/$N" "(null)" &&
160                 try_case $N wt .git \
161                         "$dotgit" "$here/$N/wt" "$here/$N" "(null)" &&
162                 try_case $N wt "$here/$N/.git" \
163                         "$absgit" "$here/$N/wt" "$here/$N" "(null)" &&
164                 try_case $N "$here/$N/wt" "$here/$N/.git" \
165                         "$absgit" "$here/$N/wt" "$here/$N" "(null)"
166         '
167
168         test_expect_success "#$N: explicit GIT_WORK_TREE from nephew of worktree" '
169                 try_case $N/sub/sub "$here/$N/wt" ../../.git \
170                         "$dotdotgit" "$here/$N/wt" "$here/$N/sub/sub" "(null)" &&
171                 try_case $N/sub/sub ../../wt ../../.git \
172                         "$dotdotgit" "$here/$N/wt" "$here/$N/sub/sub" "(null)" &&
173                 try_case $N/sub/sub ../../wt "$here/$N/.git" \
174                         "$absgit" "$here/$N/wt" "$here/$N/sub/sub" "(null)" &&
175                 try_case $N/sub/sub "$here/$N/wt" "$here/$N/.git" \
176                         "$absgit" "$here/$N/wt" "$here/$N/sub/sub" "(null)"
177         '
178
179         test_expect_success "#$N: chdir_to_toplevel uses worktree, not git dir" '
180                 try_case $N "$here" .git \
181                         "$absgit" "$here" "$here" $N/ &&
182                 try_case $N .. .git \
183                         "$absgit" "$here" "$here" $N/ &&
184                 try_case $N .. "$here/$N/.git" \
185                         "$absgit" "$here" "$here" $N/ &&
186                 try_case $N "$here" "$here/$N/.git" \
187                         "$absgit" "$here" "$here" $N/
188         '
189
190         test_expect_success "#$N: chdir_to_toplevel uses worktree (from subdir)" '
191                 try_case $N/sub/sub "$here" ../../.git \
192                         "$absgit" "$here" "$here" $N/sub/sub/ &&
193                 try_case $N/sub/sub ../../.. ../../.git \
194                         "$absgit" "$here" "$here" $N/sub/sub/ &&
195                 try_case $N/sub/sub ../../../ "$here/$N/.git" \
196                         "$absgit" "$here" "$here" $N/sub/sub/ &&
197                 try_case $N/sub/sub "$here" "$here/$N/.git" \
198                         "$absgit" "$here" "$here" $N/sub/sub/
199         '
200 }
201
202 # try_repo #c GIT_WORK_TREE GIT_DIR core.worktree .gitfile? core.bare \
203 #       (git dir) (work tree) (cwd) (prefix) \  <-- at toplevel
204 #       (git dir) (work tree) (cwd) (prefix)    <-- from subdir
205 try_repo () {
206         name=$1 worktreeenv=$2 gitdirenv=$3 &&
207         setup_repo "$name" "$4" "$5" "$6" &&
208         shift 6 &&
209         try_case "$name" "$worktreeenv" "$gitdirenv" \
210                 "$1" "$2" "$3" "$4" &&
211         shift 4 &&
212         case "$gitdirenv" in
213         /* | ?:/* | unset) ;;
214         *)
215                 gitdirenv=../$gitdirenv ;;
216         esac &&
217         try_case "$name/sub" "$worktreeenv" "$gitdirenv" \
218                 "$1" "$2" "$3" "$4"
219 }
220
221 # Bit 0 = GIT_WORK_TREE
222 # Bit 1 = GIT_DIR
223 # Bit 2 = core.worktree
224 # Bit 3 = .git is a file
225 # Bit 4 = bare repo
226 # Case# = encoding of the above 5 bits
227
228 test_expect_success '#0: nonbare repo, no explicit configuration' '
229         try_repo 0 unset unset unset "" unset \
230                 .git "$here/0" "$here/0" "(null)" \
231                 .git "$here/0" "$here/0" sub/ 2>message &&
232         ! test -s message
233 '
234
235 test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is accepted' '
236         mkdir -p wt &&
237         try_repo 1 "$here" unset unset "" unset \
238                 "$here/1/.git" "$here" "$here" 1/ \
239                 "$here/1/.git" "$here" "$here" 1/sub/ 2>message &&
240         ! test -s message
241 '
242
243 test_expect_success '#2: worktree defaults to cwd with explicit GIT_DIR' '
244         try_repo 2 unset "$here/2/.git" unset "" unset \
245                 "$here/2/.git" "$here/2" "$here/2" "(null)" \
246                 "$here/2/.git" "$here/2/sub" "$here/2/sub" "(null)"
247 '
248
249 test_expect_success '#2b: relative GIT_DIR' '
250         try_repo 2b unset ".git" unset "" unset \
251                 ".git" "$here/2b" "$here/2b" "(null)" \
252                 "../.git" "$here/2b/sub" "$here/2b/sub" "(null)"
253 '
254
255 test_expect_success '#3: setup' '
256         setup_repo 3 unset "" unset &&
257         mkdir -p 3/sub/sub 3/wt/sub
258 '
259 run_wt_tests 3
260
261 test_expect_success '#4: core.worktree without GIT_DIR set is accepted' '
262         setup_repo 4 ../sub "" unset &&
263         mkdir -p 4/sub sub &&
264         try_case 4 unset unset \
265                 .git "$here/4/sub" "$here/4" "(null)" \
266                 "$here/4/.git" "$here/4/sub" "$here/4/sub" "(null)" 2>message &&
267         ! test -s message
268 '
269
270 test_expect_success '#5: core.worktree + GIT_WORK_TREE is accepted' '
271         # or: you cannot intimidate away the lack of GIT_DIR setting
272         try_repo 5 "$here" unset "$here/5" "" unset \
273                 "$here/5/.git" "$here" "$here" 5/ \
274                 "$here/5/.git" "$here" "$here" 5/sub/ 2>message &&
275         try_repo 5a .. unset "$here/5a" "" unset \
276                 "$here/5a/.git" "$here" "$here" 5a/ \
277                 "$here/5a/.git" "$here/5a" "$here/5a" sub/ &&
278         ! test -s message
279 '
280
281 test_expect_success '#6: setting GIT_DIR brings core.worktree to life' '
282         setup_repo 6 "$here/6" "" unset &&
283         try_case 6 unset .git \
284                 .git "$here/6" "$here/6" "(null)" &&
285         try_case 6 unset "$here/6/.git" \
286                 "$here/6/.git" "$here/6" "$here/6" "(null)" &&
287         try_case 6/sub/sub unset ../../.git \
288                 "$here/6/.git" "$here/6" "$here/6" sub/sub/ &&
289         try_case 6/sub/sub unset "$here/6/.git" \
290                 "$here/6/.git" "$here/6" "$here/6" sub/sub/
291 '
292
293 test_expect_success '#6b: GIT_DIR set, core.worktree relative' '
294         setup_repo 6b .. "" unset &&
295         try_case 6b unset .git \
296                 .git "$here/6b" "$here/6b" "(null)" &&
297         try_case 6b unset "$here/6b/.git" \
298                 "$here/6b/.git" "$here/6b" "$here/6b" "(null)" &&
299         try_case 6b/sub/sub unset ../../.git \
300                 "$here/6b/.git" "$here/6b" "$here/6b" sub/sub/ &&
301         try_case 6b/sub/sub unset "$here/6b/.git" \
302                 "$here/6b/.git" "$here/6b" "$here/6b" sub/sub/
303 '
304
305 test_expect_success '#6c: GIT_DIR set, core.worktree=../wt (absolute)' '
306         setup_repo 6c "$here/6c/wt" "" unset &&
307         mkdir -p 6c/wt/sub &&
308
309         try_case 6c unset .git \
310                 .git "$here/6c/wt" "$here/6c" "(null)" &&
311         try_case 6c unset "$here/6c/.git" \
312                 "$here/6c/.git" "$here/6c/wt" "$here/6c" "(null)" &&
313         try_case 6c/sub/sub unset ../../.git \
314                 ../../.git "$here/6c/wt" "$here/6c/sub/sub" "(null)" &&
315         try_case 6c/sub/sub unset "$here/6c/.git" \
316                 "$here/6c/.git" "$here/6c/wt" "$here/6c/sub/sub" "(null)"
317 '
318
319 test_expect_success '#6d: GIT_DIR set, core.worktree=../wt (relative)' '
320         setup_repo 6d "$here/6d/wt" "" unset &&
321         mkdir -p 6d/wt/sub &&
322
323         try_case 6d unset .git \
324                 .git "$here/6d/wt" "$here/6d" "(null)" &&
325         try_case 6d unset "$here/6d/.git" \
326                 "$here/6d/.git" "$here/6d/wt" "$here/6d" "(null)" &&
327         try_case 6d/sub/sub unset ../../.git \
328                 ../../.git "$here/6d/wt" "$here/6d/sub/sub" "(null)" &&
329         try_case 6d/sub/sub unset "$here/6d/.git" \
330                 "$here/6d/.git" "$here/6d/wt" "$here/6d/sub/sub" "(null)"
331 '
332
333 test_expect_success '#6e: GIT_DIR set, core.worktree=../.. (absolute)' '
334         setup_repo 6e "$here" "" unset &&
335         try_case 6e unset .git \
336                 "$here/6e/.git" "$here" "$here" 6e/ &&
337         try_case 6e unset "$here/6e/.git" \
338                 "$here/6e/.git" "$here" "$here" 6e/ &&
339         try_case 6e/sub/sub unset ../../.git \
340                 "$here/6e/.git" "$here" "$here" 6e/sub/sub/ &&
341         try_case 6e/sub/sub unset "$here/6e/.git" \
342                 "$here/6e/.git" "$here" "$here" 6e/sub/sub/
343 '
344
345 test_expect_success '#6f: GIT_DIR set, core.worktree=../.. (relative)' '
346         setup_repo 6f ../../ "" unset &&
347         try_case 6f unset .git \
348                 "$here/6f/.git" "$here" "$here" 6f/ &&
349         try_case 6f unset "$here/6f/.git" \
350                 "$here/6f/.git" "$here" "$here" 6f/ &&
351         try_case 6f/sub/sub unset ../../.git \
352                 "$here/6f/.git" "$here" "$here" 6f/sub/sub/ &&
353         try_case 6f/sub/sub unset "$here/6f/.git" \
354                 "$here/6f/.git" "$here" "$here" 6f/sub/sub/
355 '
356
357 # case #7: GIT_WORK_TREE overrides core.worktree.
358 test_expect_success '#7: setup' '
359         setup_repo 7 non-existent "" unset &&
360         mkdir -p 7/sub/sub 7/wt/sub
361 '
362 run_wt_tests 7
363
364 test_expect_success '#8: gitfile, easy case' '
365         try_repo 8 unset unset unset gitfile unset \
366                 "$here/8.git" "$here/8" "$here/8" "(null)" \
367                 "$here/8.git" "$here/8" "$here/8" sub/
368 '
369
370 test_expect_success '#9: GIT_WORK_TREE accepted with gitfile' '
371         mkdir -p 9/wt &&
372         try_repo 9 wt unset unset gitfile unset \
373                 "$here/9.git" "$here/9/wt" "$here/9" "(null)" \
374                 "$here/9.git" "$here/9/sub/wt" "$here/9/sub" "(null)" 2>message &&
375         ! test -s message
376 '
377
378 test_expect_success '#10: GIT_DIR can point to gitfile' '
379         try_repo 10 unset "$here/10/.git" unset gitfile unset \
380                 "$here/10.git" "$here/10" "$here/10" "(null)" \
381                 "$here/10.git" "$here/10/sub" "$here/10/sub" "(null)"
382 '
383
384 test_expect_success '#10b: relative GIT_DIR can point to gitfile' '
385         try_repo 10b unset .git unset gitfile unset \
386                 "$here/10b.git" "$here/10b" "$here/10b" "(null)" \
387                 "$here/10b.git" "$here/10b/sub" "$here/10b/sub" "(null)"
388 '
389
390 # case #11: GIT_WORK_TREE works, gitfile case.
391 test_expect_success '#11: setup' '
392         setup_repo 11 unset gitfile unset &&
393         mkdir -p 11/sub/sub 11/wt/sub
394 '
395 run_wt_tests 11 gitfile
396
397 test_expect_success '#12: core.worktree with gitfile is accepted' '
398         try_repo 12 unset unset "$here/12" gitfile unset \
399                 "$here/12.git" "$here/12" "$here/12" "(null)" \
400                 "$here/12.git" "$here/12" "$here/12" sub/ 2>message &&
401         ! test -s message
402 '
403
404 test_expect_success '#13: core.worktree+GIT_WORK_TREE accepted (with gitfile)' '
405         # or: you cannot intimidate away the lack of GIT_DIR setting
406         try_repo 13 non-existent-too unset non-existent gitfile unset \
407                 "$here/13.git" "$here/13/non-existent-too" "$here/13" "(null)" \
408                 "$here/13.git" "$here/13/sub/non-existent-too" "$here/13/sub" "(null)" 2>message &&
409         ! test -s message
410 '
411
412 # case #14.
413 # If this were more table-driven, it could share code with case #6.
414
415 test_expect_success '#14: core.worktree with GIT_DIR pointing to gitfile' '
416         setup_repo 14 "$here/14" gitfile unset &&
417         try_case 14 unset .git \
418                 "$here/14.git" "$here/14" "$here/14" "(null)" &&
419         try_case 14 unset "$here/14/.git" \
420                 "$here/14.git" "$here/14" "$here/14" "(null)" &&
421         try_case 14/sub/sub unset ../../.git \
422                 "$here/14.git" "$here/14" "$here/14" sub/sub/ &&
423         try_case 14/sub/sub unset "$here/14/.git" \
424                 "$here/14.git" "$here/14" "$here/14" sub/sub/ &&
425
426         setup_repo 14c "$here/14c/wt" gitfile unset &&
427         mkdir -p 14c/wt/sub &&
428
429         try_case 14c unset .git \
430                 "$here/14c.git" "$here/14c/wt" "$here/14c" "(null)" &&
431         try_case 14c unset "$here/14c/.git" \
432                 "$here/14c.git" "$here/14c/wt" "$here/14c" "(null)" &&
433         try_case 14c/sub/sub unset ../../.git \
434                 "$here/14c.git" "$here/14c/wt" "$here/14c/sub/sub" "(null)" &&
435         try_case 14c/sub/sub unset "$here/14c/.git" \
436                 "$here/14c.git" "$here/14c/wt" "$here/14c/sub/sub" "(null)" &&
437
438         setup_repo 14d "$here/14d/wt" gitfile unset &&
439         mkdir -p 14d/wt/sub &&
440
441         try_case 14d unset .git \
442                 "$here/14d.git" "$here/14d/wt" "$here/14d" "(null)" &&
443         try_case 14d unset "$here/14d/.git" \
444                 "$here/14d.git" "$here/14d/wt" "$here/14d" "(null)" &&
445         try_case 14d/sub/sub unset ../../.git \
446                 "$here/14d.git" "$here/14d/wt" "$here/14d/sub/sub" "(null)" &&
447         try_case 14d/sub/sub unset "$here/14d/.git" \
448                 "$here/14d.git" "$here/14d/wt" "$here/14d/sub/sub" "(null)" &&
449
450         setup_repo 14e "$here" gitfile unset &&
451         try_case 14e unset .git \
452                 "$here/14e.git" "$here" "$here" 14e/ &&
453         try_case 14e unset "$here/14e/.git" \
454                 "$here/14e.git" "$here" "$here" 14e/ &&
455         try_case 14e/sub/sub unset ../../.git \
456                 "$here/14e.git" "$here" "$here" 14e/sub/sub/ &&
457         try_case 14e/sub/sub unset "$here/14e/.git" \
458                 "$here/14e.git" "$here" "$here" 14e/sub/sub/
459 '
460
461 test_expect_success '#14b: core.worktree is relative to actual git dir' '
462         setup_repo 14b ../14b gitfile unset &&
463         try_case 14b unset .git \
464                 "$here/14b.git" "$here/14b" "$here/14b" "(null)" &&
465         try_case 14b unset "$here/14b/.git" \
466                 "$here/14b.git" "$here/14b" "$here/14b" "(null)" &&
467         try_case 14b/sub/sub unset ../../.git \
468                 "$here/14b.git" "$here/14b" "$here/14b" sub/sub/ &&
469         try_case 14b/sub/sub unset "$here/14b/.git" \
470                 "$here/14b.git" "$here/14b" "$here/14b" sub/sub/ &&
471
472         setup_repo 14f ../ gitfile unset &&
473         try_case 14f unset .git \
474                 "$here/14f.git" "$here" "$here" 14f/ &&
475         try_case 14f unset "$here/14f/.git" \
476                 "$here/14f.git" "$here" "$here" 14f/ &&
477         try_case 14f/sub/sub unset ../../.git \
478                 "$here/14f.git" "$here" "$here" 14f/sub/sub/ &&
479         try_case 14f/sub/sub unset "$here/14f/.git" \
480                 "$here/14f.git" "$here" "$here" 14f/sub/sub/
481 '
482
483 # case #15: GIT_WORK_TREE overrides core.worktree (gitfile case).
484 test_expect_success '#15: setup' '
485         setup_repo 15 non-existent gitfile unset &&
486         mkdir -p 15/sub/sub 15/wt/sub
487 '
488 run_wt_tests 15 gitfile
489
490 test_expect_success '#16a: implicitly bare repo (cwd inside .git dir)' '
491         setup_repo 16a unset "" unset &&
492         mkdir -p 16a/.git/wt/sub &&
493
494         try_case 16a/.git unset unset \
495                 . "(null)" "$here/16a/.git" "(null)" &&
496         try_case 16a/.git/wt unset unset \
497                 "$here/16a/.git" "(null)" "$here/16a/.git/wt" "(null)" &&
498         try_case 16a/.git/wt/sub unset unset \
499                 "$here/16a/.git" "(null)" "$here/16a/.git/wt/sub" "(null)"
500 '
501
502 test_expect_success '#16b: bare .git (cwd inside .git dir)' '
503         setup_repo 16b unset "" true &&
504         mkdir -p 16b/.git/wt/sub &&
505
506         try_case 16b/.git unset unset \
507                 . "(null)" "$here/16b/.git" "(null)" &&
508         try_case 16b/.git/wt unset unset \
509                 "$here/16b/.git" "(null)" "$here/16b/.git/wt" "(null)" &&
510         try_case 16b/.git/wt/sub unset unset \
511                 "$here/16b/.git" "(null)" "$here/16b/.git/wt/sub" "(null)"
512 '
513
514 test_expect_success '#16c: bare .git has no worktree' '
515         try_repo 16c unset unset unset "" true \
516                 .git "(null)" "$here/16c" "(null)" \
517                 "$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
518 '
519
520 test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
521         # Just like #16.
522         setup_repo 17a unset "" true &&
523         setup_repo 17b unset "" true &&
524         mkdir -p 17a/.git/wt/sub &&
525         mkdir -p 17b/.git/wt/sub &&
526
527         try_case 17a/.git "$here/17a" unset \
528                 "$here/17a/.git" "$here/17a" "$here/17a" .git/ \
529                 2>message &&
530         try_case 17a/.git/wt "$here/17a" unset \
531                 "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/ &&
532         try_case 17a/.git/wt/sub "$here/17a" unset \
533                 "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/sub/ &&
534
535         try_case 17b/.git "$here/17b" unset \
536                 "$here/17b/.git" "$here/17b" "$here/17b" .git/ &&
537         try_case 17b/.git/wt "$here/17b" unset \
538                 "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/ &&
539         try_case 17b/.git/wt/sub "$here/17b" unset \
540                 "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/sub/ &&
541
542         try_repo 17c "$here/17c" unset unset "" true \
543                 .git "$here/17c" "$here/17c" "(null)" \
544                 "$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
545         ! test -s message
546 '
547
548 test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
549         try_repo 18 unset .git unset "" true \
550                 .git "(null)" "$here/18" "(null)" \
551                 ../.git "(null)" "$here/18/sub" "(null)" &&
552         try_repo 18b unset "$here/18b/.git" unset "" true \
553                 "$here/18b/.git" "(null)" "$here/18b" "(null)" \
554                 "$here/18b/.git" "(null)" "$here/18b/sub" "(null)"
555 '
556
557 # Case #19: GIT_DIR + GIT_WORK_TREE suppresses bareness.
558 test_expect_success '#19: setup' '
559         setup_repo 19 unset "" true &&
560         mkdir -p 19/sub/sub 19/wt/sub
561 '
562 run_wt_tests 19
563
564 test_expect_success '#20a: core.worktree without GIT_DIR accepted (inside .git)' '
565         # Unlike case #16a.
566         setup_repo 20a "$here/20a" "" unset &&
567         mkdir -p 20a/.git/wt/sub &&
568         try_case 20a/.git unset unset \
569                 "$here/20a/.git" "$here/20a" "$here/20a" .git/ 2>message &&
570         try_case 20a/.git/wt unset unset \
571                 "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
572         try_case 20a/.git/wt/sub unset unset \
573                 "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
574         ! test -s message
575 '
576
577 test_expect_success '#20b/c: core.worktree and core.bare conflict' '
578         setup_repo 20b non-existent "" true &&
579         mkdir -p 20b/.git/wt/sub &&
580         (
581                 cd 20b/.git &&
582                 test_must_fail git symbolic-ref HEAD >/dev/null
583         ) 2>message &&
584         grep "core.bare and core.worktree" message
585 '
586
587 # Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
588 test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
589         setup_repo 21 non-existent "" unset &&
590         mkdir -p 21/.git/wt/sub &&
591         (
592                 cd 21/.git &&
593                 GIT_WORK_TREE="$here/21" &&
594                 export GIT_WORK_TREE &&
595                 git symbolic-ref HEAD >/dev/null
596         ) 2>message &&
597         ! test -s message
598
599 '
600 run_wt_tests 21
601
602 test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
603         # like case #6.
604
605         setup_repo 22a "$here/22a/.git" "" unset &&
606         setup_repo 22ab . "" unset &&
607         mkdir -p 22a/.git/sub 22a/sub &&
608         mkdir -p 22ab/.git/sub 22ab/sub &&
609         try_case 22a/.git unset . \
610                 . "$here/22a/.git" "$here/22a/.git" "(null)" &&
611         try_case 22a/.git unset "$here/22a/.git" \
612                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
613         try_case 22a/.git/sub unset .. \
614                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
615         try_case 22a/.git/sub unset "$here/22a/.git" \
616                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
617
618         try_case 22ab/.git unset . \
619                 . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
620         try_case 22ab/.git unset "$here/22ab/.git" \
621                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
622         try_case 22ab/.git/sub unset .. \
623                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
624         try_case 22ab/.git unset "$here/22ab/.git" \
625                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
626 '
627
628 test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
629         setup_repo 22b "$here/22b/.git/wt" "" unset &&
630         setup_repo 22bb wt "" unset &&
631         mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
632         mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
633
634         try_case 22b/.git unset . \
635                 . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
636         try_case 22b/.git unset "$here/22b/.git" \
637                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
638         try_case 22b/.git/sub unset .. \
639                 .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
640         try_case 22b/.git/sub unset "$here/22b/.git" \
641                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
642
643         try_case 22bb/.git unset . \
644                 . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
645         try_case 22bb/.git unset "$here/22bb/.git" \
646                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
647         try_case 22bb/.git/sub unset .. \
648                 .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
649         try_case 22bb/.git/sub unset "$here/22bb/.git" \
650                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
651 '
652
653 test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
654         setup_repo 22c "$here/22c" "" unset &&
655         setup_repo 22cb .. "" unset &&
656         mkdir -p 22c/.git/sub 22c/sub &&
657         mkdir -p 22cb/.git/sub 22cb/sub &&
658
659         try_case 22c/.git unset . \
660                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
661         try_case 22c/.git unset "$here/22c/.git" \
662                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
663         try_case 22c/.git/sub unset .. \
664                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
665         try_case 22c/.git/sub unset "$here/22c/.git" \
666                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
667
668         try_case 22cb/.git unset . \
669                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
670         try_case 22cb/.git unset "$here/22cb/.git" \
671                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
672         try_case 22cb/.git/sub unset .. \
673                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
674         try_case 22cb/.git/sub unset "$here/22cb/.git" \
675                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
676 '
677
678 test_expect_success '#22.2: core.worktree and core.bare conflict' '
679         setup_repo 22 "$here/22" "" true &&
680         (
681                 cd 22/.git &&
682                 GIT_DIR=. &&
683                 export GIT_DIR &&
684                 test_must_fail git symbolic-ref HEAD 2>result
685         ) &&
686         (
687                 cd 22 &&
688                 GIT_DIR=.git &&
689                 export GIT_DIR &&
690                 test_must_fail git symbolic-ref HEAD 2>result
691         ) &&
692         grep "core.bare and core.worktree" 22/.git/result &&
693         grep "core.bare and core.worktree" 22/result
694 '
695
696 # Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
697 test_expect_success '#23: setup' '
698         setup_repo 23 non-existent "" true &&
699         mkdir -p 23/sub/sub 23/wt/sub
700 '
701 run_wt_tests 23
702
703 test_expect_success '#24: bare repo has no worktree (gitfile case)' '
704         try_repo 24 unset unset unset gitfile true \
705                 "$here/24.git" "(null)" "$here/24" "(null)" \
706                 "$here/24.git" "(null)" "$here/24/sub" "(null)"
707 '
708
709 test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
710         try_repo 25 "$here/25" unset unset gitfile true \
711                 "$here/25.git" "$here/25" "$here/25" "(null)"  \
712                 "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
713         ! test -s message
714 '
715
716 test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
717         try_repo 26 unset "$here/26/.git" unset gitfile true \
718                 "$here/26.git" "(null)" "$here/26" "(null)" \
719                 "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
720         try_repo 26b unset .git unset gitfile true \
721                 "$here/26b.git" "(null)" "$here/26b" "(null)" \
722                 "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
723 '
724
725 # Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
726 test_expect_success '#27: setup' '
727         setup_repo 27 unset gitfile true &&
728         mkdir -p 27/sub/sub 27/wt/sub
729 '
730 run_wt_tests 27 gitfile
731
732 test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
733         setup_repo 28 "$here/28" gitfile true &&
734         (
735                 cd 28 &&
736                 test_must_fail git symbolic-ref HEAD
737         ) 2>message &&
738         ! grep "^warning:" message &&
739         grep "core.bare and core.worktree" message
740 '
741
742 # Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
743 test_expect_success '#29: setup' '
744         setup_repo 29 non-existent gitfile true &&
745         mkdir -p 29/sub/sub 29/wt/sub &&
746         (
747                 cd 29 &&
748                 GIT_WORK_TREE="$here/29" &&
749                 export GIT_WORK_TREE &&
750                 git symbolic-ref HEAD >/dev/null
751         ) 2>message &&
752         ! test -s message
753 '
754 run_wt_tests 29 gitfile
755
756 test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
757         # Just like case #22.
758         setup_repo 30 "$here/30" gitfile true &&
759         (
760                 cd 30 &&
761                 GIT_DIR=.git &&
762                 export GIT_DIR &&
763                 test_must_fail git symbolic-ref HEAD 2>result
764         ) &&
765         grep "core.bare and core.worktree" 30/result
766 '
767
768 # Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
769 # bareness (gitfile version).
770 test_expect_success '#31: setup' '
771         setup_repo 31 non-existent gitfile true &&
772         mkdir -p 31/sub/sub 31/wt/sub
773 '
774 run_wt_tests 31 gitfile
775
776 test_done