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