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