t / t1510-repo-setup.shon commit Sync with maint (65da088)
   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 '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
 521        # Just like #16.
 522        setup_repo 17a unset "" true &&
 523        setup_repo 17b unset "" true &&
 524        mkdir -p 17a/.git/wt/sub &&
 525        mkdir -p 17b/.git/wt/sub &&
 526
 527        try_case 17a/.git "$here/17a" unset \
 528                "$here/17a/.git" "$here/17a" "$here/17a" .git/ \
 529                2>message &&
 530        try_case 17a/.git/wt "$here/17a" unset \
 531                "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/ &&
 532        try_case 17a/.git/wt/sub "$here/17a" unset \
 533                "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/sub/ &&
 534
 535        try_case 17b/.git "$here/17b" unset \
 536                "$here/17b/.git" "$here/17b" "$here/17b" .git/ &&
 537        try_case 17b/.git/wt "$here/17b" unset \
 538                "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/ &&
 539        try_case 17b/.git/wt/sub "$here/17b" unset \
 540                "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/sub/ &&
 541
 542        try_repo 17c "$here/17c" unset unset "" true \
 543                .git "$here/17c" "$here/17c" "(null)" \
 544                "$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
 545        ! test -s message
 546'
 547
 548test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
 549        try_repo 18 unset .git unset "" true \
 550                .git "(null)" "$here/18" "(null)" \
 551                ../.git "(null)" "$here/18/sub" "(null)" &&
 552        try_repo 18b unset "$here/18b/.git" unset "" true \
 553                "$here/18b/.git" "(null)" "$here/18b" "(null)" \
 554                "$here/18b/.git" "(null)" "$here/18b/sub" "(null)"
 555'
 556
 557# Case #19: GIT_DIR + GIT_WORK_TREE suppresses bareness.
 558test_expect_success '#19: setup' '
 559        setup_repo 19 unset "" true &&
 560        mkdir -p 19/sub/sub 19/wt/sub
 561'
 562run_wt_tests 19
 563
 564test_expect_success '#20a: core.worktree without GIT_DIR accepted (inside .git)' '
 565        # Unlike case #16a.
 566        setup_repo 20a "$here/20a" "" unset &&
 567        mkdir -p 20a/.git/wt/sub &&
 568        try_case 20a/.git unset unset \
 569                "$here/20a/.git" "$here/20a" "$here/20a" .git/ 2>message &&
 570        try_case 20a/.git/wt unset unset \
 571                "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
 572        try_case 20a/.git/wt/sub unset unset \
 573                "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
 574        ! test -s message
 575'
 576
 577test_expect_success '#20b/c: core.worktree and core.bare conflict' '
 578        setup_repo 20b non-existent "" true &&
 579        mkdir -p 20b/.git/wt/sub &&
 580        (
 581                cd 20b/.git &&
 582                test_must_fail git symbolic-ref HEAD >/dev/null
 583        ) 2>message &&
 584        grep "core.bare and core.worktree" message
 585'
 586
 587# Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
 588test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
 589        setup_repo 21 non-existent "" unset &&
 590        mkdir -p 21/.git/wt/sub &&
 591        (
 592                cd 21/.git &&
 593                GIT_WORK_TREE="$here/21" &&
 594                export GIT_WORK_TREE &&
 595                git symbolic-ref HEAD >/dev/null
 596        ) 2>message &&
 597        ! test -s message
 598
 599'
 600run_wt_tests 21
 601
 602test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
 603        # like case #6.
 604
 605        setup_repo 22a "$here/22a/.git" "" unset &&
 606        setup_repo 22ab . "" unset &&
 607        mkdir -p 22a/.git/sub 22a/sub &&
 608        mkdir -p 22ab/.git/sub 22ab/sub &&
 609        try_case 22a/.git unset . \
 610                . "$here/22a/.git" "$here/22a/.git" "(null)" &&
 611        try_case 22a/.git unset "$here/22a/.git" \
 612                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
 613        try_case 22a/.git/sub unset .. \
 614                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 615        try_case 22a/.git/sub unset "$here/22a/.git" \
 616                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 617
 618        try_case 22ab/.git unset . \
 619                . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 620        try_case 22ab/.git unset "$here/22ab/.git" \
 621                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 622        try_case 22ab/.git/sub unset .. \
 623                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
 624        try_case 22ab/.git unset "$here/22ab/.git" \
 625                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
 626'
 627
 628test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
 629        setup_repo 22b "$here/22b/.git/wt" "" unset &&
 630        setup_repo 22bb wt "" unset &&
 631        mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
 632        mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
 633
 634        try_case 22b/.git unset . \
 635                . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 636        try_case 22b/.git unset "$here/22b/.git" \
 637                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 638        try_case 22b/.git/sub unset .. \
 639                .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 640        try_case 22b/.git/sub unset "$here/22b/.git" \
 641                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 642
 643        try_case 22bb/.git unset . \
 644                . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 645        try_case 22bb/.git unset "$here/22bb/.git" \
 646                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 647        try_case 22bb/.git/sub unset .. \
 648                .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
 649        try_case 22bb/.git/sub unset "$here/22bb/.git" \
 650                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
 651'
 652
 653test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
 654        setup_repo 22c "$here/22c" "" unset &&
 655        setup_repo 22cb .. "" unset &&
 656        mkdir -p 22c/.git/sub 22c/sub &&
 657        mkdir -p 22cb/.git/sub 22cb/sub &&
 658
 659        try_case 22c/.git unset . \
 660                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 661        try_case 22c/.git unset "$here/22c/.git" \
 662                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 663        try_case 22c/.git/sub unset .. \
 664                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 665        try_case 22c/.git/sub unset "$here/22c/.git" \
 666                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 667
 668        try_case 22cb/.git unset . \
 669                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 670        try_case 22cb/.git unset "$here/22cb/.git" \
 671                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 672        try_case 22cb/.git/sub unset .. \
 673                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
 674        try_case 22cb/.git/sub unset "$here/22cb/.git" \
 675                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
 676'
 677
 678test_expect_success '#22.2: core.worktree and core.bare conflict' '
 679        setup_repo 22 "$here/22" "" true &&
 680        (
 681                cd 22/.git &&
 682                GIT_DIR=. &&
 683                export GIT_DIR &&
 684                test_must_fail git symbolic-ref HEAD 2>result
 685        ) &&
 686        (
 687                cd 22 &&
 688                GIT_DIR=.git &&
 689                export GIT_DIR &&
 690                test_must_fail git symbolic-ref HEAD 2>result
 691        ) &&
 692        grep "core.bare and core.worktree" 22/.git/result &&
 693        grep "core.bare and core.worktree" 22/result
 694'
 695
 696# Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
 697test_expect_success '#23: setup' '
 698        setup_repo 23 non-existent "" true &&
 699        mkdir -p 23/sub/sub 23/wt/sub
 700'
 701run_wt_tests 23
 702
 703test_expect_success '#24: bare repo has no worktree (gitfile case)' '
 704        try_repo 24 unset unset unset gitfile true \
 705                "$here/24.git" "(null)" "$here/24" "(null)" \
 706                "$here/24.git" "(null)" "$here/24/sub" "(null)"
 707'
 708
 709test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
 710        try_repo 25 "$here/25" unset unset gitfile true \
 711                "$here/25.git" "$here/25" "$here/25" "(null)"  \
 712                "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
 713        ! test -s message
 714'
 715
 716test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
 717        try_repo 26 unset "$here/26/.git" unset gitfile true \
 718                "$here/26.git" "(null)" "$here/26" "(null)" \
 719                "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
 720        try_repo 26b unset .git unset gitfile true \
 721                "$here/26b.git" "(null)" "$here/26b" "(null)" \
 722                "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
 723'
 724
 725# Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
 726test_expect_success '#27: setup' '
 727        setup_repo 27 unset gitfile true &&
 728        mkdir -p 27/sub/sub 27/wt/sub
 729'
 730run_wt_tests 27 gitfile
 731
 732test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
 733        setup_repo 28 "$here/28" gitfile true &&
 734        (
 735                cd 28 &&
 736                test_must_fail git symbolic-ref HEAD
 737        ) 2>message &&
 738        ! grep "^warning:" message &&
 739        grep "core.bare and core.worktree" message
 740'
 741
 742# Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
 743test_expect_success '#29: setup' '
 744        setup_repo 29 non-existent gitfile true &&
 745        mkdir -p 29/sub/sub 29/wt/sub &&
 746        (
 747                cd 29 &&
 748                GIT_WORK_TREE="$here/29" &&
 749                export GIT_WORK_TREE &&
 750                git symbolic-ref HEAD >/dev/null
 751        ) 2>message &&
 752        ! test -s message
 753'
 754run_wt_tests 29 gitfile
 755
 756test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
 757        # Just like case #22.
 758        setup_repo 30 "$here/30" gitfile true &&
 759        (
 760                cd 30 &&
 761                GIT_DIR=.git &&
 762                export GIT_DIR &&
 763                test_must_fail git symbolic-ref HEAD 2>result
 764        ) &&
 765        grep "core.bare and core.worktree" 30/result
 766'
 767
 768# Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
 769# bareness (gitfile version).
 770test_expect_success '#31: setup' '
 771        setup_repo 31 non-existent gitfile true &&
 772        mkdir -p 31/sub/sub 31/wt/sub
 773'
 774run_wt_tests 31 gitfile
 775
 776test_done