t / t1510-repo-setup.shon commit Merge branch 'js/rebase-i-shortopt' (85fcf1c)
   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_must_be_empty message
 238'
 239
 240test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is accepted' '
 241        try_repo 1 "$here" unset unset "" unset \
 242                "$here/1/.git" "$here" "$here" 1/ \
 243                "$here/1/.git" "$here" "$here" 1/sub/ 2>message &&
 244        test_must_be_empty message
 245'
 246
 247test_expect_success '#2: worktree defaults to cwd with explicit GIT_DIR' '
 248        try_repo 2 unset "$here/2/.git" unset "" unset \
 249                "$here/2/.git" "$here/2" "$here/2" "(null)" \
 250                "$here/2/.git" "$here/2/sub" "$here/2/sub" "(null)"
 251'
 252
 253test_expect_success '#2b: relative GIT_DIR' '
 254        try_repo 2b unset ".git" unset "" unset \
 255                ".git" "$here/2b" "$here/2b" "(null)" \
 256                "../.git" "$here/2b/sub" "$here/2b/sub" "(null)"
 257'
 258
 259test_expect_success '#3: setup' '
 260        setup_repo 3 unset "" unset &&
 261        mkdir -p 3/sub/sub 3/wt/sub
 262'
 263run_wt_tests 3
 264
 265test_expect_success '#4: core.worktree without GIT_DIR set is accepted' '
 266        setup_repo 4 ../sub "" unset &&
 267        mkdir -p 4/sub sub &&
 268        try_case 4 unset unset \
 269                .git "$here/4/sub" "$here/4" "(null)" \
 270                "$here/4/.git" "$here/4/sub" "$here/4/sub" "(null)" 2>message &&
 271        test_must_be_empty message
 272'
 273
 274test_expect_success '#5: core.worktree + GIT_WORK_TREE is accepted' '
 275        # or: you cannot intimidate away the lack of GIT_DIR setting
 276        try_repo 5 "$here" unset "$here/5" "" unset \
 277                "$here/5/.git" "$here" "$here" 5/ \
 278                "$here/5/.git" "$here" "$here" 5/sub/ 2>message &&
 279        try_repo 5a .. unset "$here/5a" "" unset \
 280                "$here/5a/.git" "$here" "$here" 5a/ \
 281                "$here/5a/.git" "$here/5a" "$here/5a" sub/ &&
 282        test_must_be_empty message
 283'
 284
 285test_expect_success '#6: setting GIT_DIR brings core.worktree to life' '
 286        setup_repo 6 "$here/6" "" unset &&
 287        try_case 6 unset .git \
 288                .git "$here/6" "$here/6" "(null)" &&
 289        try_case 6 unset "$here/6/.git" \
 290                "$here/6/.git" "$here/6" "$here/6" "(null)" &&
 291        try_case 6/sub/sub unset ../../.git \
 292                "$here/6/.git" "$here/6" "$here/6" sub/sub/ &&
 293        try_case 6/sub/sub unset "$here/6/.git" \
 294                "$here/6/.git" "$here/6" "$here/6" sub/sub/
 295'
 296
 297test_expect_success '#6b: GIT_DIR set, core.worktree relative' '
 298        setup_repo 6b .. "" unset &&
 299        try_case 6b unset .git \
 300                .git "$here/6b" "$here/6b" "(null)" &&
 301        try_case 6b unset "$here/6b/.git" \
 302                "$here/6b/.git" "$here/6b" "$here/6b" "(null)" &&
 303        try_case 6b/sub/sub unset ../../.git \
 304                "$here/6b/.git" "$here/6b" "$here/6b" sub/sub/ &&
 305        try_case 6b/sub/sub unset "$here/6b/.git" \
 306                "$here/6b/.git" "$here/6b" "$here/6b" sub/sub/
 307'
 308
 309test_expect_success '#6c: GIT_DIR set, core.worktree=../wt (absolute)' '
 310        setup_repo 6c "$here/6c/wt" "" unset &&
 311        mkdir -p 6c/wt/sub &&
 312
 313        try_case 6c unset .git \
 314                .git "$here/6c/wt" "$here/6c" "(null)" &&
 315        try_case 6c unset "$here/6c/.git" \
 316                "$here/6c/.git" "$here/6c/wt" "$here/6c" "(null)" &&
 317        try_case 6c/sub/sub unset ../../.git \
 318                ../../.git "$here/6c/wt" "$here/6c/sub/sub" "(null)" &&
 319        try_case 6c/sub/sub unset "$here/6c/.git" \
 320                "$here/6c/.git" "$here/6c/wt" "$here/6c/sub/sub" "(null)"
 321'
 322
 323test_expect_success '#6d: GIT_DIR set, core.worktree=../wt (relative)' '
 324        setup_repo 6d "$here/6d/wt" "" unset &&
 325        mkdir -p 6d/wt/sub &&
 326
 327        try_case 6d unset .git \
 328                .git "$here/6d/wt" "$here/6d" "(null)" &&
 329        try_case 6d unset "$here/6d/.git" \
 330                "$here/6d/.git" "$here/6d/wt" "$here/6d" "(null)" &&
 331        try_case 6d/sub/sub unset ../../.git \
 332                ../../.git "$here/6d/wt" "$here/6d/sub/sub" "(null)" &&
 333        try_case 6d/sub/sub unset "$here/6d/.git" \
 334                "$here/6d/.git" "$here/6d/wt" "$here/6d/sub/sub" "(null)"
 335'
 336
 337test_expect_success '#6e: GIT_DIR set, core.worktree=../.. (absolute)' '
 338        setup_repo 6e "$here" "" unset &&
 339        try_case 6e unset .git \
 340                "$here/6e/.git" "$here" "$here" 6e/ &&
 341        try_case 6e unset "$here/6e/.git" \
 342                "$here/6e/.git" "$here" "$here" 6e/ &&
 343        try_case 6e/sub/sub unset ../../.git \
 344                "$here/6e/.git" "$here" "$here" 6e/sub/sub/ &&
 345        try_case 6e/sub/sub unset "$here/6e/.git" \
 346                "$here/6e/.git" "$here" "$here" 6e/sub/sub/
 347'
 348
 349test_expect_success '#6f: GIT_DIR set, core.worktree=../.. (relative)' '
 350        setup_repo 6f ../../ "" unset &&
 351        try_case 6f unset .git \
 352                "$here/6f/.git" "$here" "$here" 6f/ &&
 353        try_case 6f unset "$here/6f/.git" \
 354                "$here/6f/.git" "$here" "$here" 6f/ &&
 355        try_case 6f/sub/sub unset ../../.git \
 356                "$here/6f/.git" "$here" "$here" 6f/sub/sub/ &&
 357        try_case 6f/sub/sub unset "$here/6f/.git" \
 358                "$here/6f/.git" "$here" "$here" 6f/sub/sub/
 359'
 360
 361# case #7: GIT_WORK_TREE overrides core.worktree.
 362test_expect_success '#7: setup' '
 363        setup_repo 7 non-existent "" unset &&
 364        mkdir -p 7/sub/sub 7/wt/sub
 365'
 366run_wt_tests 7
 367
 368test_expect_success '#8: gitfile, easy case' '
 369        try_repo 8 unset unset unset gitfile unset \
 370                "$here/8.git" "$here/8" "$here/8" "(null)" \
 371                "$here/8.git" "$here/8" "$here/8" sub/
 372'
 373
 374test_expect_success '#9: GIT_WORK_TREE accepted with gitfile' '
 375        mkdir -p 9/wt &&
 376        try_repo 9 wt unset unset gitfile unset \
 377                "$here/9.git" "$here/9/wt" "$here/9" "(null)" \
 378                "$here/9.git" "$here/9/sub/wt" "$here/9/sub" "(null)" 2>message &&
 379        test_must_be_empty message
 380'
 381
 382test_expect_success '#10: GIT_DIR can point to gitfile' '
 383        try_repo 10 unset "$here/10/.git" unset gitfile unset \
 384                "$here/10.git" "$here/10" "$here/10" "(null)" \
 385                "$here/10.git" "$here/10/sub" "$here/10/sub" "(null)"
 386'
 387
 388test_expect_success '#10b: relative GIT_DIR can point to gitfile' '
 389        try_repo 10b unset .git unset gitfile unset \
 390                "$here/10b.git" "$here/10b" "$here/10b" "(null)" \
 391                "$here/10b.git" "$here/10b/sub" "$here/10b/sub" "(null)"
 392'
 393
 394# case #11: GIT_WORK_TREE works, gitfile case.
 395test_expect_success '#11: setup' '
 396        setup_repo 11 unset gitfile unset &&
 397        mkdir -p 11/sub/sub 11/wt/sub
 398'
 399run_wt_tests 11 gitfile
 400
 401test_expect_success '#12: core.worktree with gitfile is accepted' '
 402        try_repo 12 unset unset "$here/12" gitfile unset \
 403                "$here/12.git" "$here/12" "$here/12" "(null)" \
 404                "$here/12.git" "$here/12" "$here/12" sub/ 2>message &&
 405        test_must_be_empty message
 406'
 407
 408test_expect_success '#13: core.worktree+GIT_WORK_TREE accepted (with gitfile)' '
 409        # or: you cannot intimidate away the lack of GIT_DIR setting
 410        try_repo 13 non-existent-too unset non-existent gitfile unset \
 411                "$here/13.git" "$here/13/non-existent-too" "$here/13" "(null)" \
 412                "$here/13.git" "$here/13/sub/non-existent-too" "$here/13/sub" "(null)" 2>message &&
 413        test_must_be_empty message
 414'
 415
 416# case #14.
 417# If this were more table-driven, it could share code with case #6.
 418
 419test_expect_success '#14: core.worktree with GIT_DIR pointing to gitfile' '
 420        setup_repo 14 "$here/14" gitfile unset &&
 421        try_case 14 unset .git \
 422                "$here/14.git" "$here/14" "$here/14" "(null)" &&
 423        try_case 14 unset "$here/14/.git" \
 424                "$here/14.git" "$here/14" "$here/14" "(null)" &&
 425        try_case 14/sub/sub unset ../../.git \
 426                "$here/14.git" "$here/14" "$here/14" sub/sub/ &&
 427        try_case 14/sub/sub unset "$here/14/.git" \
 428                "$here/14.git" "$here/14" "$here/14" sub/sub/ &&
 429
 430        setup_repo 14c "$here/14c/wt" gitfile unset &&
 431        mkdir -p 14c/wt/sub &&
 432
 433        try_case 14c unset .git \
 434                "$here/14c.git" "$here/14c/wt" "$here/14c" "(null)" &&
 435        try_case 14c unset "$here/14c/.git" \
 436                "$here/14c.git" "$here/14c/wt" "$here/14c" "(null)" &&
 437        try_case 14c/sub/sub unset ../../.git \
 438                "$here/14c.git" "$here/14c/wt" "$here/14c/sub/sub" "(null)" &&
 439        try_case 14c/sub/sub unset "$here/14c/.git" \
 440                "$here/14c.git" "$here/14c/wt" "$here/14c/sub/sub" "(null)" &&
 441
 442        setup_repo 14d "$here/14d/wt" gitfile unset &&
 443        mkdir -p 14d/wt/sub &&
 444
 445        try_case 14d unset .git \
 446                "$here/14d.git" "$here/14d/wt" "$here/14d" "(null)" &&
 447        try_case 14d unset "$here/14d/.git" \
 448                "$here/14d.git" "$here/14d/wt" "$here/14d" "(null)" &&
 449        try_case 14d/sub/sub unset ../../.git \
 450                "$here/14d.git" "$here/14d/wt" "$here/14d/sub/sub" "(null)" &&
 451        try_case 14d/sub/sub unset "$here/14d/.git" \
 452                "$here/14d.git" "$here/14d/wt" "$here/14d/sub/sub" "(null)" &&
 453
 454        setup_repo 14e "$here" gitfile unset &&
 455        try_case 14e unset .git \
 456                "$here/14e.git" "$here" "$here" 14e/ &&
 457        try_case 14e unset "$here/14e/.git" \
 458                "$here/14e.git" "$here" "$here" 14e/ &&
 459        try_case 14e/sub/sub unset ../../.git \
 460                "$here/14e.git" "$here" "$here" 14e/sub/sub/ &&
 461        try_case 14e/sub/sub unset "$here/14e/.git" \
 462                "$here/14e.git" "$here" "$here" 14e/sub/sub/
 463'
 464
 465test_expect_success '#14b: core.worktree is relative to actual git dir' '
 466        setup_repo 14b ../14b gitfile unset &&
 467        try_case 14b unset .git \
 468                "$here/14b.git" "$here/14b" "$here/14b" "(null)" &&
 469        try_case 14b unset "$here/14b/.git" \
 470                "$here/14b.git" "$here/14b" "$here/14b" "(null)" &&
 471        try_case 14b/sub/sub unset ../../.git \
 472                "$here/14b.git" "$here/14b" "$here/14b" sub/sub/ &&
 473        try_case 14b/sub/sub unset "$here/14b/.git" \
 474                "$here/14b.git" "$here/14b" "$here/14b" sub/sub/ &&
 475
 476        setup_repo 14f ../ gitfile unset &&
 477        try_case 14f unset .git \
 478                "$here/14f.git" "$here" "$here" 14f/ &&
 479        try_case 14f unset "$here/14f/.git" \
 480                "$here/14f.git" "$here" "$here" 14f/ &&
 481        try_case 14f/sub/sub unset ../../.git \
 482                "$here/14f.git" "$here" "$here" 14f/sub/sub/ &&
 483        try_case 14f/sub/sub unset "$here/14f/.git" \
 484                "$here/14f.git" "$here" "$here" 14f/sub/sub/
 485'
 486
 487# case #15: GIT_WORK_TREE overrides core.worktree (gitfile case).
 488test_expect_success '#15: setup' '
 489        setup_repo 15 non-existent gitfile unset &&
 490        mkdir -p 15/sub/sub 15/wt/sub
 491'
 492run_wt_tests 15 gitfile
 493
 494test_expect_success '#16a: implicitly bare repo (cwd inside .git dir)' '
 495        setup_repo 16a unset "" unset &&
 496        mkdir -p 16a/.git/wt/sub &&
 497
 498        try_case 16a/.git unset unset \
 499                . "(null)" "$here/16a/.git" "(null)" &&
 500        try_case 16a/.git/wt unset unset \
 501                "$here/16a/.git" "(null)" "$here/16a/.git/wt" "(null)" &&
 502        try_case 16a/.git/wt/sub unset unset \
 503                "$here/16a/.git" "(null)" "$here/16a/.git/wt/sub" "(null)"
 504'
 505
 506test_expect_success '#16b: bare .git (cwd inside .git dir)' '
 507        setup_repo 16b unset "" true &&
 508        mkdir -p 16b/.git/wt/sub &&
 509
 510        try_case 16b/.git unset unset \
 511                . "(null)" "$here/16b/.git" "(null)" &&
 512        try_case 16b/.git/wt unset unset \
 513                "$here/16b/.git" "(null)" "$here/16b/.git/wt" "(null)" &&
 514        try_case 16b/.git/wt/sub unset unset \
 515                "$here/16b/.git" "(null)" "$here/16b/.git/wt/sub" "(null)"
 516'
 517
 518test_expect_success '#16c: bare .git has no worktree' '
 519        try_repo 16c unset unset unset "" true \
 520                .git "(null)" "$here/16c" "(null)" \
 521                "$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
 522'
 523
 524test_expect_success '#16d: bareness preserved across alias' '
 525        setup_repo 16d unset "" unset &&
 526        (
 527                cd 16d/.git &&
 528                test_must_fail git status &&
 529                git config alias.st status &&
 530                test_must_fail git st
 531        )
 532'
 533
 534test_expect_success '#16e: bareness preserved by --bare' '
 535        setup_repo 16e unset "" unset &&
 536        (
 537                cd 16e/.git &&
 538                test_must_fail git status &&
 539                test_must_fail git --bare status
 540        )
 541'
 542
 543test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
 544        # Just like #16.
 545        setup_repo 17a unset "" true &&
 546        setup_repo 17b unset "" true &&
 547        mkdir -p 17a/.git/wt/sub &&
 548        mkdir -p 17b/.git/wt/sub &&
 549
 550        try_case 17a/.git "$here/17a" unset \
 551                "$here/17a/.git" "$here/17a" "$here/17a" .git/ \
 552                2>message &&
 553        try_case 17a/.git/wt "$here/17a" unset \
 554                "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/ &&
 555        try_case 17a/.git/wt/sub "$here/17a" unset \
 556                "$here/17a/.git" "$here/17a" "$here/17a" .git/wt/sub/ &&
 557
 558        try_case 17b/.git "$here/17b" unset \
 559                "$here/17b/.git" "$here/17b" "$here/17b" .git/ &&
 560        try_case 17b/.git/wt "$here/17b" unset \
 561                "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/ &&
 562        try_case 17b/.git/wt/sub "$here/17b" unset \
 563                "$here/17b/.git" "$here/17b" "$here/17b" .git/wt/sub/ &&
 564
 565        try_repo 17c "$here/17c" unset unset "" true \
 566                .git "$here/17c" "$here/17c" "(null)" \
 567                "$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
 568        test_must_be_empty message
 569'
 570
 571test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
 572        try_repo 18 unset .git unset "" true \
 573                .git "(null)" "$here/18" "(null)" \
 574                ../.git "(null)" "$here/18/sub" "(null)" &&
 575        try_repo 18b unset "$here/18b/.git" unset "" true \
 576                "$here/18b/.git" "(null)" "$here/18b" "(null)" \
 577                "$here/18b/.git" "(null)" "$here/18b/sub" "(null)"
 578'
 579
 580# Case #19: GIT_DIR + GIT_WORK_TREE suppresses bareness.
 581test_expect_success '#19: setup' '
 582        setup_repo 19 unset "" true &&
 583        mkdir -p 19/sub/sub 19/wt/sub
 584'
 585run_wt_tests 19
 586
 587test_expect_success '#20a: core.worktree without GIT_DIR accepted (inside .git)' '
 588        # Unlike case #16a.
 589        setup_repo 20a "$here/20a" "" unset &&
 590        mkdir -p 20a/.git/wt/sub &&
 591        try_case 20a/.git unset unset \
 592                "$here/20a/.git" "$here/20a" "$here/20a" .git/ 2>message &&
 593        try_case 20a/.git/wt unset unset \
 594                "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
 595        try_case 20a/.git/wt/sub unset unset \
 596                "$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
 597        test_must_be_empty message
 598'
 599
 600test_expect_success '#20b/c: core.worktree and core.bare conflict' '
 601        setup_repo 20b non-existent "" true &&
 602        mkdir -p 20b/.git/wt/sub &&
 603        (
 604                cd 20b/.git &&
 605                test_must_fail git status >/dev/null
 606        ) 2>message &&
 607        grep "core.bare and core.worktree" message
 608'
 609
 610test_expect_success '#20d: core.worktree and core.bare OK when working tree not needed' '
 611        setup_repo 20d non-existent "" true &&
 612        mkdir -p 20d/.git/wt/sub &&
 613        (
 614                cd 20d/.git &&
 615                git config foo.bar value
 616        )
 617'
 618
 619# Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
 620test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
 621        setup_repo 21 non-existent "" unset &&
 622        mkdir -p 21/.git/wt/sub &&
 623        (
 624                cd 21/.git &&
 625                GIT_WORK_TREE="$here/21" &&
 626                export GIT_WORK_TREE &&
 627                git status >/dev/null
 628        ) 2>message &&
 629        test_must_be_empty message
 630
 631'
 632run_wt_tests 21
 633
 634test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
 635        # like case #6.
 636
 637        setup_repo 22a "$here/22a/.git" "" unset &&
 638        setup_repo 22ab . "" unset &&
 639        mkdir -p 22a/.git/sub 22a/sub &&
 640        mkdir -p 22ab/.git/sub 22ab/sub &&
 641        try_case 22a/.git unset . \
 642                . "$here/22a/.git" "$here/22a/.git" "(null)" &&
 643        try_case 22a/.git unset "$here/22a/.git" \
 644                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" "(null)" &&
 645        try_case 22a/.git/sub unset .. \
 646                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 647        try_case 22a/.git/sub unset "$here/22a/.git" \
 648                "$here/22a/.git" "$here/22a/.git" "$here/22a/.git" sub/ &&
 649
 650        try_case 22ab/.git unset . \
 651                . "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 652        try_case 22ab/.git unset "$here/22ab/.git" \
 653                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)" &&
 654        try_case 22ab/.git/sub unset .. \
 655                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" sub/ &&
 656        try_case 22ab/.git unset "$here/22ab/.git" \
 657                "$here/22ab/.git" "$here/22ab/.git" "$here/22ab/.git" "(null)"
 658'
 659
 660test_expect_success '#22b: core.worktree child of .git, GIT_DIR=.git' '
 661        setup_repo 22b "$here/22b/.git/wt" "" unset &&
 662        setup_repo 22bb wt "" unset &&
 663        mkdir -p 22b/.git/sub 22b/sub 22b/.git/wt/sub 22b/wt/sub &&
 664        mkdir -p 22bb/.git/sub 22bb/sub 22bb/.git/wt 22bb/wt &&
 665
 666        try_case 22b/.git unset . \
 667                . "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 668        try_case 22b/.git unset "$here/22b/.git" \
 669                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git" "(null)" &&
 670        try_case 22b/.git/sub unset .. \
 671                .. "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 672        try_case 22b/.git/sub unset "$here/22b/.git" \
 673                "$here/22b/.git" "$here/22b/.git/wt" "$here/22b/.git/sub" "(null)" &&
 674
 675        try_case 22bb/.git unset . \
 676                . "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 677        try_case 22bb/.git unset "$here/22bb/.git" \
 678                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git" "(null)" &&
 679        try_case 22bb/.git/sub unset .. \
 680                .. "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)" &&
 681        try_case 22bb/.git/sub unset "$here/22bb/.git" \
 682                "$here/22bb/.git" "$here/22bb/.git/wt" "$here/22bb/.git/sub" "(null)"
 683'
 684
 685test_expect_success '#22c: core.worktree = .git/.., GIT_DIR=.git' '
 686        setup_repo 22c "$here/22c" "" unset &&
 687        setup_repo 22cb .. "" unset &&
 688        mkdir -p 22c/.git/sub 22c/sub &&
 689        mkdir -p 22cb/.git/sub 22cb/sub &&
 690
 691        try_case 22c/.git unset . \
 692                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 693        try_case 22c/.git unset "$here/22c/.git" \
 694                "$here/22c/.git" "$here/22c" "$here/22c" .git/ &&
 695        try_case 22c/.git/sub unset .. \
 696                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 697        try_case 22c/.git/sub unset "$here/22c/.git" \
 698                "$here/22c/.git" "$here/22c" "$here/22c" .git/sub/ &&
 699
 700        try_case 22cb/.git unset . \
 701                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 702        try_case 22cb/.git unset "$here/22cb/.git" \
 703                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/ &&
 704        try_case 22cb/.git/sub unset .. \
 705                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/ &&
 706        try_case 22cb/.git/sub unset "$here/22cb/.git" \
 707                "$here/22cb/.git" "$here/22cb" "$here/22cb" .git/sub/
 708'
 709
 710test_expect_success '#22.2: core.worktree and core.bare conflict' '
 711        setup_repo 22 "$here/22" "" true &&
 712        (
 713                cd 22/.git &&
 714                GIT_DIR=. &&
 715                export GIT_DIR &&
 716                test_must_fail git status 2>result
 717        ) &&
 718        (
 719                cd 22 &&
 720                GIT_DIR=.git &&
 721                export GIT_DIR &&
 722                test_must_fail git status 2>result
 723        ) &&
 724        grep "core.bare and core.worktree" 22/.git/result &&
 725        grep "core.bare and core.worktree" 22/result
 726'
 727
 728# Case #23: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses bareness.
 729test_expect_success '#23: setup' '
 730        setup_repo 23 non-existent "" true &&
 731        mkdir -p 23/sub/sub 23/wt/sub
 732'
 733run_wt_tests 23
 734
 735test_expect_success '#24: bare repo has no worktree (gitfile case)' '
 736        try_repo 24 unset unset unset gitfile true \
 737                "$here/24.git" "(null)" "$here/24" "(null)" \
 738                "$here/24.git" "(null)" "$here/24/sub" "(null)"
 739'
 740
 741test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
 742        try_repo 25 "$here/25" unset unset gitfile true \
 743                "$here/25.git" "$here/25" "$here/25" "(null)"  \
 744                "$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
 745        test_must_be_empty message
 746'
 747
 748test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
 749        try_repo 26 unset "$here/26/.git" unset gitfile true \
 750                "$here/26.git" "(null)" "$here/26" "(null)" \
 751                "$here/26.git" "(null)" "$here/26/sub" "(null)" &&
 752        try_repo 26b unset .git unset gitfile true \
 753                "$here/26b.git" "(null)" "$here/26b" "(null)" \
 754                "$here/26b.git" "(null)" "$here/26b/sub" "(null)"
 755'
 756
 757# Case #27: GIT_DIR + GIT_WORK_TREE suppresses bareness (with gitfile).
 758test_expect_success '#27: setup' '
 759        setup_repo 27 unset gitfile true &&
 760        mkdir -p 27/sub/sub 27/wt/sub
 761'
 762run_wt_tests 27 gitfile
 763
 764test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
 765        setup_repo 28 "$here/28" gitfile true &&
 766        (
 767                cd 28 &&
 768                test_must_fail git status
 769        ) 2>message &&
 770        grep "core.bare and core.worktree" message
 771'
 772
 773# Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
 774test_expect_success '#29: setup' '
 775        setup_repo 29 non-existent gitfile true &&
 776        mkdir -p 29/sub/sub 29/wt/sub &&
 777        (
 778                cd 29 &&
 779                GIT_WORK_TREE="$here/29" &&
 780                export GIT_WORK_TREE &&
 781                git status
 782        ) 2>message &&
 783        test_must_be_empty message
 784'
 785run_wt_tests 29 gitfile
 786
 787test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
 788        # Just like case #22.
 789        setup_repo 30 "$here/30" gitfile true &&
 790        (
 791                cd 30 &&
 792                test_must_fail env GIT_DIR=.git git status 2>result
 793        ) &&
 794        grep "core.bare and core.worktree" 30/result
 795'
 796
 797# Case #31: GIT_DIR + GIT_WORK_TREE(+core.worktree) suppresses
 798# bareness (gitfile version).
 799test_expect_success '#31: setup' '
 800        setup_repo 31 non-existent gitfile true &&
 801        mkdir -p 31/sub/sub 31/wt/sub
 802'
 803run_wt_tests 31 gitfile
 804
 805test_done