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