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