1#!/bin/sh
   2test_description="Tests of cwd/prefix/worktree/gitdir setup in all cases
   4A few rules for repo setup:
   61. GIT_DIR is relative to user's cwd. --git-dir is equivalent to
   8   GIT_DIR.
   92. .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.
  133. core.worktree is relative to git_dir.
  154. GIT_WORK_TREE is relative to user's cwd. --work-tree is
  17   equivalent to GIT_WORK_TREE.
  185. 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.
  256. Effective GIT_WORK_TREE overrides core.worktree and core.bare
  277. Effective core.worktree conflicts with core.bare
  298. If GIT_DIR is set but neither worktree nor bare setting is given,
  31   original cwd becomes worktree.
  329. 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.
  3510. If no worktree is available, cwd remains unchanged, prefix is
  37    NULL.
  3811. When user's cwd is outside worktree, cwd remains unchanged,
  40    prefix is NULL.
  41"
  42. ./test-lib.sh
  43here=$(pwd)
  45test_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}
  65maybe_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}
  73setup_repo () {
  75        name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
  76        sane_unset GIT_DIR GIT_WORK_TREE &&
  77        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        if test "${gitfile:+set}"
  84        then
  85                mv "$name/.git" "$name.git" &&
  86                echo "gitdir: ../$name.git" >"$name/.git"
  87        fi
  88}
  89maybe_set () {
  91        var=$1 value=$2 &&
  92        if test "$value" != unset
  93        then
  94                eval "$var=\$value" &&
  95                export $var
  96        fi
  97}
  98setup_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}
 105expect () {
 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}
 115try_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}
 122run_wt_tests () {
 124        N=$1 gitfile=$2
 125        absgit="$here/$N/.git"
 127        dotgit=.git
 128        dotdotgit=../../.git
 129        if test "$gitfile"
 131        then
 132                absgit="$here/$N.git"
 133                dotgit=$absgit dotdotgit=$absgit
 134        fi
 135        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        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        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        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        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        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# 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# 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
 228test_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'
 235test_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'
 243test_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'
 249test_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'
 255test_expect_success '#3: setup' '
 257        setup_repo 3 unset "" unset &&
 258        mkdir -p 3/sub/sub 3/wt/sub
 259'
 260run_wt_tests 3
 261test_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'
 270test_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'
 281test_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'
 293test_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'
 305test_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        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'
 319test_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        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'
 333test_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'
 345test_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# 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
 364test_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'
 370test_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'
 378test_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'
 384test_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# 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
 397test_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'
 404test_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# case #14.
 414# If this were more table-driven, it could share code with case #6.
 415test_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        setup_repo 14c "$here/14c/wt" gitfile unset &&
 428        mkdir -p 14c/wt/sub &&
 429        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        setup_repo 14d "$here/14d/wt" gitfile unset &&
 440        mkdir -p 14d/wt/sub &&
 441        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        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'
 461test_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        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# 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
 490test_expect_success '#16a: implicitly bare repo (cwd inside .git dir)' '
 492        setup_repo 16a unset "" unset &&
 493        mkdir -p 16a/.git/wt/sub &&
 494        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'
 502test_expect_success '#16b: bare .git (cwd inside .git dir)' '
 504        setup_repo 16b unset "" true &&
 505        mkdir -p 16b/.git/wt/sub &&
 506        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'
 514test_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'
 520test_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'
 530test_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'
 539test_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        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        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        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'
 567test_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# 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
 583test_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'
 596test_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'
 606test_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# 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'
 629run_wt_tests 21
 630test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
 632        # like case #6.
 633        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        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'
 656test_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        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        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'
 681test_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        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        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'
 706test_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# 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
 731test_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'
 737test_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'
 744test_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# 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
 760test_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# 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
 783test_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# 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
 801test_done