Merge branch 'sb/plug-transport-leak'
[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 '#16d: bareness preserved across alias' '
521         setup_repo 16d unset "" unset &&
522         (
523                 cd 16d/.git &&
524                 test_must_fail git status &&
525                 git config alias.st status &&
526                 test_must_fail git st
527         )
528 '
529
530 test_expect_success '#16e: bareness preserved by --bare' '
531         setup_repo 16e unset "" unset &&
532         (
533                 cd 16e/.git &&
534                 test_must_fail git status &&
535                 test_must_fail git --bare status
536         )
537 '
538
539 test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
540         # Just like #16.
541         setup_repo 17a unset "" true &&
542         setup_repo 17b unset "" true &&
543         mkdir -p 17a/.git/wt/sub &&
544         mkdir -p 17b/.git/wt/sub &&
545
546         try_case 17a/.git "$here/17a" unset \
547                 "$here/17a/.git" "$here/17a" "$here/17a" .git/ \
548                 2>message &&
549         try_case 17a/.git/wt "$here/17a" unset \
550                 "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/ &&
551         try_case 17a/.git/wt/sub "$here/17a" unset \
552                 "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/sub/ &&
553
554         try_case 17b/.git "$here/17b" unset \
555                 "$here/17b/.git" "$here/17b" "$here/17b" .git/ &&
556         try_case 17b/.git/wt "$here/17b" unset \
557                 "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/ &&
558         try_case 17b/.git/wt/sub "$here/17b" unset \
559                 "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/sub/ &&
560
561         try_repo 17c "$here/17c" unset unset "" true \
562                 .git "$here/17c" "$here/17c" "(null)" \
563                 "$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
564         ! test -s message
565 '
566
567 test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
568         try_repo 18 unset .git unset "" true \
569                 .git "(null)" "$here/18" "(null)" \
570                 ../.git "(null)" "$here/18/sub" "(null)" &&
571         try_repo 18b unset "$here/18b/.git" unset "" true \
572                 "$here/18b/.git" "(null)" "$here/18b" "(null)" \
573                 "$here/18b/.git" "(null)" "$here/18b/sub" "(null)"
574 '
575
576 # Case #19: GIT_DIR + GIT_WORK_TREE suppresses bareness.
577 test_expect_success '#19: setup' '
578         setup_repo 19 unset "" true &&
579         mkdir -p 19/sub/sub 19/wt/sub
580 '
581 run_wt_tests 19
582
583 test_expect_success '#20a: core.worktree without GIT_DIR accepted (inside .git)' '
584         # Unlike case #16a.
585         setup_repo 20a "$here/20a" "" unset &&
586         mkdir -p 20a/.git/wt/sub &&
587         try_case 20a/.git unset unset \
588                 "$here/20a/.git" "$here/20a" "$here/20a" .git/ 2>message &&
589         try_case 20a/.git/wt unset unset \
590                 "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
591         try_case 20a/.git/wt/sub unset unset \
592                 "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
593         ! test -s message
594 '
595
596 test_expect_success '#20b/c: core.worktree and core.bare conflict' '
597         setup_repo 20b non-existent "" true &&
598         mkdir -p 20b/.git/wt/sub &&
599         (
600                 cd 20b/.git &&
601                 test_must_fail git symbolic-ref HEAD >/dev/null
602         ) 2>message &&
603         grep "core.bare and core.worktree" message
604 '
605
606 # Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
607 test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
608         setup_repo 21 non-existent "" unset &&
609         mkdir -p 21/.git/wt/sub &&
610         (
611                 cd 21/.git &&
612                 GIT_WORK_TREE="$here/21" &&
613                 export GIT_WORK_TREE &&
614                 git symbolic-ref HEAD >/dev/null
615         ) 2>message &&
616         ! test -s message
617
618 '
619 run_wt_tests 21
620
621 test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
622         # like case #6.
623
624         setup_repo 22a "$here/22a/.git" "" unset &&
625         setup_repo 22ab . "" unset &&
626         mkdir -p 22a/.git/sub 22a/sub &&
627         mkdir -p 22ab/.git/sub 22ab/sub &&
628         try_case 22a/.git unset . \
629                 . "$here/22a/.git" "$here/22a/.git" "(null)" &&
630         try_case 22a/.git unset "$here/22a/.git" \
631                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
632         try_case 22a/.git/sub unset .. \
633                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
634         try_case 22a/.git/sub unset "$here/22a/.git" \
635                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
636
637         try_case 22ab/.git unset . \
638                 . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
639         try_case 22ab/.git unset "$here/22ab/.git" \
640                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
641         try_case 22ab/.git/sub unset .. \
642                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
643         try_case 22ab/.git unset "$here/22ab/.git" \
644                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
645 '
646
647 test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
648         setup_repo 22b "$here/22b/.git/wt" "" unset &&
649         setup_repo 22bb wt "" unset &&
650         mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
651         mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
652
653         try_case 22b/.git unset . \
654                 . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
655         try_case 22b/.git unset "$here/22b/.git" \
656                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
657         try_case 22b/.git/sub unset .. \
658                 .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
659         try_case 22b/.git/sub unset "$here/22b/.git" \
660                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
661
662         try_case 22bb/.git unset . \
663                 . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
664         try_case 22bb/.git unset "$here/22bb/.git" \
665                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
666         try_case 22bb/.git/sub unset .. \
667                 .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
668         try_case 22bb/.git/sub unset "$here/22bb/.git" \
669                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
670 '
671
672 test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
673         setup_repo 22c "$here/22c" "" unset &&
674         setup_repo 22cb .. "" unset &&
675         mkdir -p 22c/.git/sub 22c/sub &&
676         mkdir -p 22cb/.git/sub 22cb/sub &&
677
678         try_case 22c/.git unset . \
679                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
680         try_case 22c/.git unset "$here/22c/.git" \
681                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
682         try_case 22c/.git/sub unset .. \
683                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
684         try_case 22c/.git/sub unset "$here/22c/.git" \
685                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
686
687         try_case 22cb/.git unset . \
688                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
689         try_case 22cb/.git unset "$here/22cb/.git" \
690                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
691         try_case 22cb/.git/sub unset .. \
692                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
693         try_case 22cb/.git/sub unset "$here/22cb/.git" \
694                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
695 '
696
697 test_expect_success '#22.2: core.worktree and core.bare conflict' '
698         setup_repo 22 "$here/22" "" true &&
699         (
700                 cd 22/.git &&
701                 GIT_DIR=. &&
702                 export GIT_DIR &&
703                 test_must_fail git symbolic-ref HEAD 2>result
704         ) &&
705         (
706                 cd 22 &&
707                 GIT_DIR=.git &&
708                 export GIT_DIR &&
709                 test_must_fail git symbolic-ref HEAD 2>result
710         ) &&
711         grep "core.bare and core.worktree" 22/.git/result &&
712         grep "core.bare and core.worktree" 22/result
713 '
714
715 # Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
716 test_expect_success '#23: setup' '
717         setup_repo 23 non-existent "" true &&
718         mkdir -p 23/sub/sub 23/wt/sub
719 '
720 run_wt_tests 23
721
722 test_expect_success '#24: bare repo has no worktree (gitfile case)' '
723         try_repo 24 unset unset unset gitfile true \
724                 "$here/24.git" "(null)" "$here/24" "(null)" \
725                 "$here/24.git" "(null)" "$here/24/sub" "(null)"
726 '
727
728 test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
729         try_repo 25 "$here/25" unset unset gitfile true \
730                 "$here/25.git" "$here/25" "$here/25" "(null)"  \
731                 "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
732         ! test -s message
733 '
734
735 test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
736         try_repo 26 unset "$here/26/.git" unset gitfile true \
737                 "$here/26.git" "(null)" "$here/26" "(null)" \
738                 "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
739         try_repo 26b unset .git unset gitfile true \
740                 "$here/26b.git" "(null)" "$here/26b" "(null)" \
741                 "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
742 '
743
744 # Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
745 test_expect_success '#27: setup' '
746         setup_repo 27 unset gitfile true &&
747         mkdir -p 27/sub/sub 27/wt/sub
748 '
749 run_wt_tests 27 gitfile
750
751 test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
752         setup_repo 28 "$here/28" gitfile true &&
753         (
754                 cd 28 &&
755                 test_must_fail git symbolic-ref HEAD
756         ) 2>message &&
757         ! grep "^warning:" message &&
758         grep "core.bare and core.worktree" message
759 '
760
761 # Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
762 test_expect_success '#29: setup' '
763         setup_repo 29 non-existent gitfile true &&
764         mkdir -p 29/sub/sub 29/wt/sub &&
765         (
766                 cd 29 &&
767                 GIT_WORK_TREE="$here/29" &&
768                 export GIT_WORK_TREE &&
769                 git symbolic-ref HEAD >/dev/null
770         ) 2>message &&
771         ! test -s message
772 '
773 run_wt_tests 29 gitfile
774
775 test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
776         # Just like case #22.
777         setup_repo 30 "$here/30" gitfile true &&
778         (
779                 cd 30 &&
780                 test_must_fail env GIT_DIR=.git git symbolic-ref HEAD 2>result
781         ) &&
782         grep "core.bare and core.worktree" 30/result
783 '
784
785 # Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
786 # bareness (gitfile version).
787 test_expect_success '#31: setup' '
788         setup_repo 31 non-existent gitfile true &&
789         mkdir -p 31/sub/sub 31/wt/sub
790 '
791 run_wt_tests 31 gitfile
792
793 test_done