Merge branch 'ps/guess-repo-name-at-root'
[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 status >/dev/null
603         ) 2>message &&
604         grep "core.bare and core.worktree" message
605 '
606
607 test_expect_success '#20d: core.worktree and core.bare OK when working tree not needed' '
608         setup_repo 20d non-existent "" true &&
609         mkdir -p 20d/.git/wt/sub &&
610         (
611                 cd 20d/.git &&
612                 git config foo.bar value
613         )
614 '
615
616 # Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
617 test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
618         setup_repo 21 non-existent "" unset &&
619         mkdir -p 21/.git/wt/sub &&
620         (
621                 cd 21/.git &&
622                 GIT_WORK_TREE="$here/21" &&
623                 export GIT_WORK_TREE &&
624                 git status >/dev/null
625         ) 2>message &&
626         ! test -s message
627
628 '
629 run_wt_tests 21
630
631 test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
632         # like case #6.
633
634         setup_repo 22a "$here/22a/.git" "" unset &&
635         setup_repo 22ab . "" unset &&
636         mkdir -p 22a/.git/sub 22a/sub &&
637         mkdir -p 22ab/.git/sub 22ab/sub &&
638         try_case 22a/.git unset . \
639                 . "$here/22a/.git" "$here/22a/.git" "(null)" &&
640         try_case 22a/.git unset "$here/22a/.git" \
641                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
642         try_case 22a/.git/sub unset .. \
643                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
644         try_case 22a/.git/sub unset "$here/22a/.git" \
645                 "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
646
647         try_case 22ab/.git unset . \
648                 . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
649         try_case 22ab/.git unset "$here/22ab/.git" \
650                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
651         try_case 22ab/.git/sub unset .. \
652                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
653         try_case 22ab/.git unset "$here/22ab/.git" \
654                 "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
655 '
656
657 test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
658         setup_repo 22b "$here/22b/.git/wt" "" unset &&
659         setup_repo 22bb wt "" unset &&
660         mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
661         mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
662
663         try_case 22b/.git unset . \
664                 . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
665         try_case 22b/.git unset "$here/22b/.git" \
666                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
667         try_case 22b/.git/sub unset .. \
668                 .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
669         try_case 22b/.git/sub unset "$here/22b/.git" \
670                 "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
671
672         try_case 22bb/.git unset . \
673                 . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
674         try_case 22bb/.git unset "$here/22bb/.git" \
675                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
676         try_case 22bb/.git/sub unset .. \
677                 .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
678         try_case 22bb/.git/sub unset "$here/22bb/.git" \
679                 "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
680 '
681
682 test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
683         setup_repo 22c "$here/22c" "" unset &&
684         setup_repo 22cb .. "" unset &&
685         mkdir -p 22c/.git/sub 22c/sub &&
686         mkdir -p 22cb/.git/sub 22cb/sub &&
687
688         try_case 22c/.git unset . \
689                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
690         try_case 22c/.git unset "$here/22c/.git" \
691                 "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
692         try_case 22c/.git/sub unset .. \
693                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
694         try_case 22c/.git/sub unset "$here/22c/.git" \
695                 "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
696
697         try_case 22cb/.git unset . \
698                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
699         try_case 22cb/.git unset "$here/22cb/.git" \
700                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
701         try_case 22cb/.git/sub unset .. \
702                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
703         try_case 22cb/.git/sub unset "$here/22cb/.git" \
704                 "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
705 '
706
707 test_expect_success '#22.2: core.worktree and core.bare conflict' '
708         setup_repo 22 "$here/22" "" true &&
709         (
710                 cd 22/.git &&
711                 GIT_DIR=. &&
712                 export GIT_DIR &&
713                 test_must_fail git status 2>result
714         ) &&
715         (
716                 cd 22 &&
717                 GIT_DIR=.git &&
718                 export GIT_DIR &&
719                 test_must_fail git status 2>result
720         ) &&
721         grep "core.bare and core.worktree" 22/.git/result &&
722         grep "core.bare and core.worktree" 22/result
723 '
724
725 # Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
726 test_expect_success '#23: setup' '
727         setup_repo 23 non-existent "" true &&
728         mkdir -p 23/sub/sub 23/wt/sub
729 '
730 run_wt_tests 23
731
732 test_expect_success '#24: bare repo has no worktree (gitfile case)' '
733         try_repo 24 unset unset unset gitfile true \
734                 "$here/24.git" "(null)" "$here/24" "(null)" \
735                 "$here/24.git" "(null)" "$here/24/sub" "(null)"
736 '
737
738 test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
739         try_repo 25 "$here/25" unset unset gitfile true \
740                 "$here/25.git" "$here/25" "$here/25" "(null)"  \
741                 "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
742         ! test -s message
743 '
744
745 test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
746         try_repo 26 unset "$here/26/.git" unset gitfile true \
747                 "$here/26.git" "(null)" "$here/26" "(null)" \
748                 "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
749         try_repo 26b unset .git unset gitfile true \
750                 "$here/26b.git" "(null)" "$here/26b" "(null)" \
751                 "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
752 '
753
754 # Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
755 test_expect_success '#27: setup' '
756         setup_repo 27 unset gitfile true &&
757         mkdir -p 27/sub/sub 27/wt/sub
758 '
759 run_wt_tests 27 gitfile
760
761 test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
762         setup_repo 28 "$here/28" gitfile true &&
763         (
764                 cd 28 &&
765                 test_must_fail git status
766         ) 2>message &&
767         grep "core.bare and core.worktree" message
768 '
769
770 # Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
771 test_expect_success '#29: setup' '
772         setup_repo 29 non-existent gitfile true &&
773         mkdir -p 29/sub/sub 29/wt/sub &&
774         (
775                 cd 29 &&
776                 GIT_WORK_TREE="$here/29" &&
777                 export GIT_WORK_TREE &&
778                 git status
779         ) 2>message &&
780         ! test -s message
781 '
782 run_wt_tests 29 gitfile
783
784 test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
785         # Just like case #22.
786         setup_repo 30 "$here/30" gitfile true &&
787         (
788                 cd 30 &&
789                 test_must_fail env GIT_DIR=.git git status 2>result
790         ) &&
791         grep "core.bare and core.worktree" 30/result
792 '
793
794 # Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
795 # bareness (gitfile version).
796 test_expect_success '#31: setup' '
797         setup_repo 31 non-existent gitfile true &&
798         mkdir -p 31/sub/sub 31/wt/sub
799 '
800 run_wt_tests 31 gitfile
801
802 test_done