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