t / t1510-repo-setup.shon commit git-p4: add tests for non-numeric revision range (eceafff)
   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: git_common_dir: $2
 110        setup: worktree: $3
 111        setup: cwd: $4
 112        setup: prefix: $5
 113        EOF
 114}
 115
 116try_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
 123run_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
 206try_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
 229test_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
 236test_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
 244test_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
 250test_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
 256test_expect_success '#3: setup' '
 257        setup_repo 3 unset "" unset &&
 258        mkdir -p 3/sub/sub 3/wt/sub
 259'
 260run_wt_tests 3
 261
 262test_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
 271test_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
 282test_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
 294test_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
 306test_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
 320test_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
 334test_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
 346test_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.
 359test_expect_success '#7: setup' '
 360        setup_repo 7 non-existent "" unset &&
 361        mkdir -p 7/sub/sub 7/wt/sub
 362'
 363run_wt_tests 7
 364
 365test_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
 371test_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
 379test_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
 385test_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.
 392test_expect_success '#11: setup' '
 393        setup_repo 11 unset gitfile unset &&
 394        mkdir -p 11/sub/sub 11/wt/sub
 395'
 396run_wt_tests 11 gitfile
 397
 398test_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
 405test_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
 416test_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
 462test_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).
 485test_expect_success '#15: setup' '
 486        setup_repo 15 non-existent gitfile unset &&
 487        mkdir -p 15/sub/sub 15/wt/sub
 488'
 489run_wt_tests 15 gitfile
 490
 491test_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
 503test_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
 515test_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
 521test_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
 531test_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
 540test_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
 568test_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.
 578test_expect_success '#19: setup' '
 579        setup_repo 19 unset "" true &&
 580        mkdir -p 19/sub/sub 19/wt/sub
 581'
 582run_wt_tests 19
 583
 584test_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
 597test_expect_success '#20b/c: core.worktree and core.bare conflict' '
 598        setup_repo 20b non-existent "" true &&
 599        mkdir -p 20b/.git/wt/sub &&
 600        (
 601                cd 20b/.git &&
 602                test_must_fail git symbolic-ref HEAD >/dev/null
 603        ) 2>message &&
 604        grep "core.bare and core.worktree" message
 605'
 606
 607# Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
 608test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
 609        setup_repo 21 non-existent "" unset &&
 610        mkdir -p 21/.git/wt/sub &&
 611        (
 612                cd 21/.git &&
 613                GIT_WORK_TREE="$here/21" &&
 614                export GIT_WORK_TREE &&
 615                git symbolic-ref HEAD >/dev/null
 616        ) 2>message &&
 617        ! test -s message
 618
 619'
 620run_wt_tests 21
 621
 622test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
 623        # like case #6.
 624
 625        setup_repo 22a "$here/22a/.git" "" unset &&
 626        setup_repo 22ab . "" unset &&
 627        mkdir -p 22a/.git/sub 22a/sub &&
 628        mkdir -p 22ab/.git/sub 22ab/sub &&
 629        try_case 22a/.git unset . \
 630                . "$here/22a/.git" "$here/22a/.git" "(null)" &&
 631        try_case 22a/.git unset "$here/22a/.git" \
 632                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
 633        try_case 22a/.git/sub unset .. \
 634                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 635        try_case 22a/.git/sub unset "$here/22a/.git" \
 636                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 637
 638        try_case 22ab/.git unset . \
 639                . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 640        try_case 22ab/.git unset "$here/22ab/.git" \
 641                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 642        try_case 22ab/.git/sub unset .. \
 643                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
 644        try_case 22ab/.git unset "$here/22ab/.git" \
 645                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
 646'
 647
 648test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
 649        setup_repo 22b "$here/22b/.git/wt" "" unset &&
 650        setup_repo 22bb wt "" unset &&
 651        mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
 652        mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
 653
 654        try_case 22b/.git unset . \
 655                . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 656        try_case 22b/.git unset "$here/22b/.git" \
 657                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 658        try_case 22b/.git/sub unset .. \
 659                .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 660        try_case 22b/.git/sub unset "$here/22b/.git" \
 661                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 662
 663        try_case 22bb/.git unset . \
 664                . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 665        try_case 22bb/.git unset "$here/22bb/.git" \
 666                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 667        try_case 22bb/.git/sub unset .. \
 668                .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
 669        try_case 22bb/.git/sub unset "$here/22bb/.git" \
 670                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
 671'
 672
 673test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
 674        setup_repo 22c "$here/22c" "" unset &&
 675        setup_repo 22cb .. "" unset &&
 676        mkdir -p 22c/.git/sub 22c/sub &&
 677        mkdir -p 22cb/.git/sub 22cb/sub &&
 678
 679        try_case 22c/.git unset . \
 680                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 681        try_case 22c/.git unset "$here/22c/.git" \
 682                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 683        try_case 22c/.git/sub unset .. \
 684                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 685        try_case 22c/.git/sub unset "$here/22c/.git" \
 686                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 687
 688        try_case 22cb/.git unset . \
 689                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 690        try_case 22cb/.git unset "$here/22cb/.git" \
 691                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 692        try_case 22cb/.git/sub unset .. \
 693                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
 694        try_case 22cb/.git/sub unset "$here/22cb/.git" \
 695                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
 696'
 697
 698test_expect_success '#22.2: core.worktree and core.bare conflict' '
 699        setup_repo 22 "$here/22" "" true &&
 700        (
 701                cd 22/.git &&
 702                GIT_DIR=. &&
 703                export GIT_DIR &&
 704                test_must_fail git symbolic-ref HEAD 2>result
 705        ) &&
 706        (
 707                cd 22 &&
 708                GIT_DIR=.git &&
 709                export GIT_DIR &&
 710                test_must_fail git symbolic-ref HEAD 2>result
 711        ) &&
 712        grep "core.bare and core.worktree" 22/.git/result &&
 713        grep "core.bare and core.worktree" 22/result
 714'
 715
 716# Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
 717test_expect_success '#23: setup' '
 718        setup_repo 23 non-existent "" true &&
 719        mkdir -p 23/sub/sub 23/wt/sub
 720'
 721run_wt_tests 23
 722
 723test_expect_success '#24: bare repo has no worktree (gitfile case)' '
 724        try_repo 24 unset unset unset gitfile true \
 725                "$here/24.git" "(null)" "$here/24" "(null)" \
 726                "$here/24.git" "(null)" "$here/24/sub" "(null)"
 727'
 728
 729test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
 730        try_repo 25 "$here/25" unset unset gitfile true \
 731                "$here/25.git" "$here/25" "$here/25" "(null)"  \
 732                "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
 733        ! test -s message
 734'
 735
 736test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
 737        try_repo 26 unset "$here/26/.git" unset gitfile true \
 738                "$here/26.git" "(null)" "$here/26" "(null)" \
 739                "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
 740        try_repo 26b unset .git unset gitfile true \
 741                "$here/26b.git" "(null)" "$here/26b" "(null)" \
 742                "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
 743'
 744
 745# Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
 746test_expect_success '#27: setup' '
 747        setup_repo 27 unset gitfile true &&
 748        mkdir -p 27/sub/sub 27/wt/sub
 749'
 750run_wt_tests 27 gitfile
 751
 752test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
 753        setup_repo 28 "$here/28" gitfile true &&
 754        (
 755                cd 28 &&
 756                test_must_fail git symbolic-ref HEAD
 757        ) 2>message &&
 758        ! grep "^warning:" message &&
 759        grep "core.bare and core.worktree" message
 760'
 761
 762# Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
 763test_expect_success '#29: setup' '
 764        setup_repo 29 non-existent gitfile true &&
 765        mkdir -p 29/sub/sub 29/wt/sub &&
 766        (
 767                cd 29 &&
 768                GIT_WORK_TREE="$here/29" &&
 769                export GIT_WORK_TREE &&
 770                git symbolic-ref HEAD >/dev/null
 771        ) 2>message &&
 772        ! test -s message
 773'
 774run_wt_tests 29 gitfile
 775
 776test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
 777        # Just like case #22.
 778        setup_repo 30 "$here/30" gitfile true &&
 779        (
 780                cd 30 &&
 781                test_must_fail env GIT_DIR=.git git symbolic-ref HEAD 2>result
 782        ) &&
 783        grep "core.bare and core.worktree" 30/result
 784'
 785
 786# Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
 787# bareness (gitfile version).
 788test_expect_success '#31: setup' '
 789        setup_repo 31 non-existent gitfile true &&
 790        mkdir -p 31/sub/sub 31/wt/sub
 791'
 792run_wt_tests 31 gitfile
 793
 794test_done