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