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