summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/lib-git-svn.sh38
-rwxr-xr-xt/t0000-basic.sh36
-rwxr-xr-xt/t0001-init.sh56
-rwxr-xr-xt/t0021-conversion.sh43
-rwxr-xr-xt/t1020-subdirectory.sh8
-rwxr-xr-xt/t1501-worktree.sh7
-rwxr-xr-xt/t1510-repo-setup.sh4532
-rwxr-xr-xt/t3032-merge-recursive-options.sh11
-rwxr-xr-xt/t3301-notes.sh2
-rwxr-xr-xt/t3404-rebase-interactive.sh3
-rwxr-xr-xt/t5407-post-rewrite-hook.sh18
-rwxr-xr-xt/t6038-merge-text-auto.sh2
-rwxr-xr-xt/t7400-submodule-basic.sh38
-rwxr-xr-xt/t9001-send-email.sh14
-rwxr-xr-xt/t9010-svn-fe.sh84
-rwxr-xr-xt/t9157-git-svn-fetch-merge.sh8
-rwxr-xr-xt/t9600-cvsimport.sh7
-rw-r--r--t/test-lib.sh7
18 files changed, 4825 insertions, 89 deletions
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 6a9d975723..199f22c231 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -68,8 +68,7 @@ svn_cmd () {
svn "$orig_svncmd" --config-dir "$svnconf" "$@"
}
-if test -n "$SVN_HTTPD_PORT"
-then
+prepare_httpd () {
for d in \
"$SVN_HTTPD_PATH" \
/usr/sbin/apache2 \
@@ -83,8 +82,8 @@ then
done
if test -z "$SVN_HTTPD_PATH"
then
- skip_all='skipping git svn tests, Apache not found'
- test_done
+ echo >&2 '*** error: Apache not found'
+ return 1
fi
for d in \
"$SVN_HTTPD_MODULE_PATH" \
@@ -99,23 +98,16 @@ then
done
if test -z "$SVN_HTTPD_MODULE_PATH"
then
- skip_all='skipping git svn tests, Apache module dir not found'
- test_done
- fi
-fi
-
-start_httpd () {
- repo_base_path="$1"
- if test -z "$SVN_HTTPD_PORT"
- then
- echo >&2 'SVN_HTTPD_PORT is not defined!'
- return
+ echo >&2 '*** error: Apache module dir not found'
+ return 1
fi
- if test -z "$repo_base_path"
+ if test ! -f "$SVN_HTTPD_MODULE_PATH/mod_dav_svn.so"
then
- repo_base_path=svn
+ echo >&2 '*** error: Apache module "mod_dav_svn" not found'
+ return 1
fi
+ repo_base_path="${1-svn}"
mkdir "$GIT_DIR"/logs
cat > "$GIT_DIR/httpd.conf" <<EOF
@@ -132,12 +124,24 @@ LoadModule dav_svn_module $SVN_HTTPD_MODULE_PATH/mod_dav_svn.so
SVNPath "$rawsvnrepo"
</Location>
EOF
+}
+
+start_httpd () {
+ if test -z "$SVN_HTTPD_PORT"
+ then
+ echo >&2 'SVN_HTTPD_PORT is not defined!'
+ return
+ fi
+
+ prepare_httpd "$1" || return 1
+
"$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k start
svnrepo="http://127.0.0.1:$SVN_HTTPD_PORT/$repo_base_path"
}
stop_httpd () {
test -z "$SVN_HTTPD_PORT" && return
+ test ! -f "$GIT_DIR/httpd.conf" && return
"$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k stop
}
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 2f7002a5e5..8deec75c3a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -80,11 +80,11 @@ EOF
chmod +x passing-todo.sh &&
./passing-todo.sh >out 2>err &&
! test -s err &&
-cat >expect <<EOF &&
-ok 1 - pretend we have fixed a known breakage # TODO known breakage
-# fixed 1 known breakage(s)
-# passed all 1 test(s)
-1..1
+sed -e 's/^> //' >expect <<EOF &&
+> ok 1 - pretend we have fixed a known breakage # TODO known breakage
+> # fixed 1 known breakage(s)
+> # passed all 1 test(s)
+> 1..1
EOF
test_cmp expect out)
"
@@ -164,19 +164,19 @@ EOF
test_must_fail ./failing-cleanup.sh >out 2>err &&
! test -s err &&
! test -f \"trash directory.failing-cleanup/clean-after-failure\" &&
-sed -e 's/Z$//' >expect <<\EOF &&
-not ok - 1 tests clean up even after a failure
-# Z
-# touch clean-after-failure &&
-# test_when_finished rm clean-after-failure &&
-# (exit 1)
-# Z
-not ok - 2 failure to clean up causes the test to fail
-# Z
-# test_when_finished \"(exit 2)\"
-# Z
-# failed 2 among 2 test(s)
-1..2
+sed -e 's/Z$//' -e 's/^> //' >expect <<\EOF &&
+> not ok - 1 tests clean up even after a failure
+> # Z
+> # touch clean-after-failure &&
+> # test_when_finished rm clean-after-failure &&
+> # (exit 1)
+> # Z
+> not ok - 2 failure to clean up causes the test to fail
+> # Z
+> # test_when_finished \"(exit 2)\"
+> # Z
+> # failed 2 among 2 test(s)
+> 1..2
EOF
test_cmp expect out)
"
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index d44194c35f..f684993211 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -33,6 +33,62 @@ test_expect_success 'plain' '
check_config plain/.git false unset
'
+test_expect_success 'plain nested in bare' '
+ (
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ git init --bare bare-ancestor.git &&
+ cd bare-ancestor.git &&
+ mkdir plain-nested &&
+ cd plain-nested &&
+ git init
+ ) &&
+ check_config bare-ancestor.git/plain-nested/.git false unset
+'
+
+test_expect_success 'plain through aliased command, outside any git repo' '
+ (
+ sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG_NOGLOBAL &&
+ HOME=$(pwd)/alias-config &&
+ export HOME &&
+ mkdir alias-config &&
+ echo "[alias] aliasedinit = init" >alias-config/.gitconfig &&
+
+ GIT_CEILING_DIRECTORIES=$(pwd) &&
+ export GIT_CEILING_DIRECTORIES &&
+
+ mkdir plain-aliased &&
+ cd plain-aliased &&
+ git aliasedinit
+ ) &&
+ check_config plain-aliased/.git false unset
+'
+
+test_expect_failure 'plain nested through aliased command' '
+ (
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ git init plain-ancestor-aliased &&
+ cd plain-ancestor-aliased &&
+ echo "[alias] aliasedinit = init" >>.git/config &&
+ mkdir plain-nested &&
+ cd plain-nested &&
+ git aliasedinit
+ ) &&
+ check_config plain-ancestor-aliased/plain-nested/.git false unset
+'
+
+test_expect_failure 'plain nested in bare through aliased command' '
+ (
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ git init --bare bare-ancestor-aliased.git &&
+ cd bare-ancestor-aliased.git &&
+ echo "[alias] aliasedinit = init" >>config &&
+ mkdir plain-nested &&
+ cd plain-nested &&
+ git aliasedinit
+ ) &&
+ check_config bare-ancestor-aliased.git/plain-nested/.git false unset
+'
+
test_expect_success 'plain with GIT_WORK_TREE' '
if (
sane_unset GIT_DIR &&
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index 828e35baf7..9078b84ae6 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -93,4 +93,47 @@ test_expect_success expanded_in_repo '
cmp expanded-keywords expected-output
'
+# The use of %f in a filter definition is expanded to the path to
+# the filename being smudged or cleaned. It must be shell escaped.
+# First, set up some interesting file names and pet them in
+# .gitattributes.
+test_expect_success 'filter shell-escaped filenames' '
+ cat >argc.sh <<-EOF &&
+ #!$SHELL_PATH
+ cat >/dev/null
+ echo argc: \$# "\$@"
+ EOF
+ normal=name-no-magic &&
+ special="name with '\''sq'\'' and \$x" &&
+ echo some test text >"$normal" &&
+ echo some test text >"$special" &&
+ git add "$normal" "$special" &&
+ git commit -q -m "add files" &&
+ echo "name* filter=argc" >.gitattributes &&
+
+ # delete the files and check them out again, using a smudge filter
+ # that will count the args and echo the command-line back to us
+ git config filter.argc.smudge "sh ./argc.sh %f" &&
+ rm "$normal" "$special" &&
+ git checkout -- "$normal" "$special" &&
+
+ # make sure argc.sh counted the right number of args
+ echo "argc: 1 $normal" >expect &&
+ test_cmp expect "$normal" &&
+ echo "argc: 1 $special" >expect &&
+ test_cmp expect "$special" &&
+
+ # do the same thing, but with more args in the filter expression
+ git config filter.argc.smudge "sh ./argc.sh %f --my-extra-arg" &&
+ rm "$normal" "$special" &&
+ git checkout -- "$normal" "$special" &&
+
+ # make sure argc.sh counted the right number of args
+ echo "argc: 2 $normal --my-extra-arg" >expect &&
+ test_cmp expect "$normal" &&
+ echo "argc: 2 $special --my-extra-arg" >expect &&
+ test_cmp expect "$special" &&
+ :
+'
+
test_done
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index a3ac33801a..1fd187c5eb 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -110,6 +110,14 @@ test_expect_success 'read-tree' '
)
'
+test_expect_success 'alias expansion' '
+ (
+ git config alias.ss status &&
+ cd dir &&
+ git status &&
+ git ss
+ )
+'
test_expect_success 'no file/rev ambiguity check inside .git' '
git commit -a -m 1 &&
(
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 2c8f01f668..f072a8ed48 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -340,4 +340,11 @@ test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
'
+test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
+ GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
+ test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
+ echo "$TRASH_DIRECTORY/repo.git/work" >expected &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
new file mode 100755
index 0000000000..c3798ce179
--- /dev/null
+++ b/t/t1510-repo-setup.sh
@@ -0,0 +1,4532 @@
+#!/bin/sh
+
+test_description='Tests of cwd/prefix/worktree/gitdir setup in all cases'
+
+. ./test-lib.sh
+
+#
+# A few rules for repo setup:
+#
+# 1. GIT_DIR is relative to user's cwd. --git-dir is equivalent to
+# GIT_DIR.
+#
+# 2. .git file is relative to parent directory. .git file is basically
+# symlink in disguise. The directory where .git file points to will
+# become new git_dir.
+#
+# 3. core.worktree is relative to git_dir.
+#
+# 4. GIT_WORK_TREE is relative to user's cwd. --work-tree is
+# equivalent to GIT_WORK_TREE.
+#
+# 5. GIT_WORK_TREE/core.worktree is only effective if GIT_DIR is set
+# Uneffective worktree settings should be warned.
+#
+# 6. Effective GIT_WORK_TREE overrides core.worktree and core.bare
+#
+# 7. Effective core.worktree conflicts with core.bare
+#
+# 8. If GIT_DIR is set but neither worktree nor bare setting is given,
+# original cwd becomes worktree.
+#
+# 9. If .git discovery is done inside a repo, the repo becomes a bare
+# repo. .git discovery is performed if GIT_DIR is not set.
+#
+# 10. If no worktree is available, cwd remains unchanged, prefix is
+# NULL.
+#
+# 11. When user's cwd is outside worktree, cwd remains unchanged,
+# prefix is NULL.
+#
+
+test_repo() {
+ (
+ cd "$1" &&
+ if test -n "$2"; then GIT_DIR="$2" && export GIT_DIR; fi &&
+ if test -n "$3"; then GIT_WORK_TREE="$3" && export GIT_WORK_TREE; fi &&
+ rm -f trace &&
+ GIT_TRACE="`pwd`/trace" git symbolic-ref HEAD >/dev/null &&
+ grep '^setup: ' trace >result &&
+ test_cmp expected result
+ )
+}
+
+# Bit 0 = GIT_WORK_TREE
+# Bit 1 = GIT_DIR
+# Bit 2 = core.worktree
+# Bit 3 = .git is a file
+# Bit 4 = bare repo
+# Case# = encoding of the above 5 bits
+
+#
+# Case #0
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# - worktree is .git's parent directory
+# - cwd is at worktree root dir
+# - prefix is calculated
+# - git_dir is set to ".git"
+# - cwd can't be outside worktree
+
+test_expect_success '#0: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 0 0/sub &&
+ cd 0 && git init && cd ..
+'
+
+test_expect_success '#0: at root' '
+ cat >0/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/0
+setup: cwd: $TRASH_DIRECTORY/0
+setup: prefix: (null)
+EOF
+ test_repo 0
+'
+
+test_expect_success '#0: in subdir' '
+ cat >0/sub/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/0
+setup: cwd: $TRASH_DIRECTORY/0
+setup: prefix: sub/
+EOF
+ test_repo 0/sub
+'
+
+#
+# case #1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# GIT_WORK_TREE is ignored -> #0
+
+test_expect_success '#1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 1 1/sub 1.wt 1.wt/sub 1/wt 1/wt/sub &&
+ cd 1 &&
+ git init &&
+ GIT_WORK_TREE=non-existent &&
+ export GIT_WORK_TREE &&
+ cd ..
+'
+
+test_expect_success '#1: at root' '
+ cat >1/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/1
+setup: cwd: $TRASH_DIRECTORY/1
+setup: prefix: (null)
+EOF
+ test_repo 1
+'
+
+test_expect_success '#1: in subdir' '
+ cat >1/sub/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/1
+setup: cwd: $TRASH_DIRECTORY/1
+setup: prefix: sub/
+EOF
+ test_repo 1/sub
+'
+
+#
+# case #2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# - worktree is at original cwd
+# - cwd is unchanged
+# - prefix is NULL
+# - git_dir is set to $GIT_DIR
+# - cwd can't be outside worktree
+
+test_expect_success '#2: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 2 2/sub &&
+ cd 2 && git init && cd ..
+'
+
+test_expect_success '#2: at root' '
+ cat >2/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/2/.git
+setup: worktree: $TRASH_DIRECTORY/2
+setup: cwd: $TRASH_DIRECTORY/2
+setup: prefix: (null)
+EOF
+ test_repo 2 "$TRASH_DIRECTORY/2/.git"
+'
+
+test_expect_success '#2: in subdir' '
+ cat >2/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/2/.git
+setup: worktree: $TRASH_DIRECTORY/2/sub
+setup: cwd: $TRASH_DIRECTORY/2/sub
+setup: prefix: (null)
+EOF
+ test_repo 2/sub "$TRASH_DIRECTORY/2/.git"
+'
+
+test_expect_success '#2: relative GIT_DIR at root' '
+ cat >2/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/2
+setup: cwd: $TRASH_DIRECTORY/2
+setup: prefix: (null)
+EOF
+ test_repo 2 .git
+'
+
+test_expect_success '#2: relative GIT_DIR in subdir' '
+ cat >2/sub/expected <<EOF &&
+setup: git_dir: ../.git
+setup: worktree: $TRASH_DIRECTORY/2/sub
+setup: cwd: $TRASH_DIRECTORY/2/sub
+setup: prefix: (null)
+EOF
+ test_repo 2/sub ../.git
+'
+
+#
+# case #3
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# - worktree is set to $GIT_WORK_TREE
+# - cwd is at worktree root
+# - prefix is calculated
+# - git_dir is set to $GIT_DIR
+# - cwd can be outside worktree
+
+test_expect_success '#3: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 3 3/sub 3/sub/sub 3.wt 3.wt/sub 3/wt 3/wt/sub &&
+ cd 3 && git init && cd ..
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 .git "$TRASH_DIRECTORY/3"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 .git .
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3"
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" .
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: sub/sub/
+EOF
+ test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY/3"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: sub/sub/
+EOF
+ test_repo 3/sub/sub ../../.git ../..
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >3/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: sub/
+EOF
+ test_repo 3/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3"
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: sub/sub/
+EOF
+ test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../..
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 .git "$TRASH_DIRECTORY/3/wt"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 .git wt
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" wt
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3
+setup: prefix: (null)
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3/wt"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY/3/wt"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 3/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../../wt
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY/3/wt
+setup: cwd: $TRASH_DIRECTORY/3/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3/wt"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/
+EOF
+ test_repo 3 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/
+EOF
+ test_repo 3 .git ..
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" ..
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >3/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/
+EOF
+ test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/sub/sub/
+EOF
+ test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/sub/sub/
+EOF
+ test_repo 3/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/sub/sub/
+EOF
+ test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../../../
+'
+
+test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >3/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/3/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 3/sub/sub/
+EOF
+ test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #4
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# core.worktree is ignored -> #0
+
+test_expect_success '#4: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 4 4/sub &&
+ cd 4 &&
+ git init &&
+ git config core.worktree non-existent &&
+ cd ..
+'
+
+test_expect_success '#4: at root' '
+ cat >4/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/4
+setup: cwd: $TRASH_DIRECTORY/4
+setup: prefix: (null)
+EOF
+ test_repo 4
+'
+
+test_expect_success '#4: in subdir' '
+ cat >4/sub/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/4
+setup: cwd: $TRASH_DIRECTORY/4
+setup: prefix: sub/
+EOF
+ test_repo 4/sub
+'
+
+#
+# case #5
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# GIT_WORK_TREE/core.worktree are ignored -> #0
+
+test_expect_success '#5: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 5 5/sub &&
+ cd 5 &&
+ git init &&
+ git config core.worktree non-existent &&
+ GIT_WORK_TREE=non-existent-too &&
+ export GIT_WORK_TREE &&
+ cd ..
+'
+
+test_expect_success '#5: at root' '
+ cat >5/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/5
+setup: cwd: $TRASH_DIRECTORY/5
+setup: prefix: (null)
+EOF
+ test_repo 5
+'
+
+test_expect_success '#5: in subdir' '
+ cat >5/sub/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/5
+setup: cwd: $TRASH_DIRECTORY/5
+setup: prefix: sub/
+EOF
+ test_repo 5/sub
+'
+
+#
+# case #6
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# - worktree is at core.worktree
+# - cwd is at worktree root
+# - prefix is calculated
+# - git_dir is at $GIT_DIR
+# - cwd can be outside worktree
+
+test_expect_success '#6: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 6 6/sub 6/sub/sub 6.wt 6.wt/sub 6/wt 6/wt/sub &&
+ cd 6 && git init && cd ..
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=.. at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=..(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=.. at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=..(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=.. in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=..(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=.. in subdir' '
+ cat >6/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" &&
+ test_repo 6/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=..(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. &&
+ test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../wt(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../wt at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../wt(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt &&
+ test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../wt in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY/6/wt
+setup: cwd: $TRASH_DIRECTORY/6/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" &&
+ test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../.. at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../..(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../../ &&
+ test_repo 6 .git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../..(rel) at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../../ &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../.. at root' '
+ cat >6/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 6 "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../.. in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR(rel), core.worktree=../..(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../.. &&
+ test_repo 6/sub/sub ../../.git
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../..(rel) in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../.. &&
+ test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+test_expect_success '#6: GIT_DIR, core.worktree=../.. in subdir' '
+ cat >6/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/6/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 6/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
+'
+
+#
+# case #7
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# core.worktree is overridden by GIT_WORK_TREE -> #3
+
+test_expect_success '#7: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 7 7/sub 7/sub/sub 7.wt 7.wt/sub 7/wt 7/wt/sub &&
+ cd 7 &&
+ git init &&
+ git config core.worktree non-existent &&
+ cd ..
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 .git "$TRASH_DIRECTORY/7"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 .git .
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7"
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" .
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: sub/sub/
+EOF
+ test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY/7"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: sub/sub/
+EOF
+ test_repo 7/sub/sub ../../.git ../..
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >7/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: sub/
+EOF
+ test_repo 7/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7"
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: sub/sub/
+EOF
+ test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../..
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 .git "$TRASH_DIRECTORY/7/wt"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 .git wt
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" wt
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7
+setup: prefix: (null)
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7/wt"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY/7/wt"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 7/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../../wt
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY/7/wt
+setup: cwd: $TRASH_DIRECTORY/7/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7/wt"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/
+EOF
+ test_repo 7 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/
+EOF
+ test_repo 7 .git ..
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" ..
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >7/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/
+EOF
+ test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/sub/sub/
+EOF
+ test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/sub/sub/
+EOF
+ test_repo 7/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/sub/sub/
+EOF
+ test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../../../
+'
+
+test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >7/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/7/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 7/sub/sub/
+EOF
+ test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #8
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #0 except that git_dir is set by .git file
+
+test_expect_success '#8: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 8 8/sub &&
+ cd 8 &&
+ git init &&
+ mv .git ../8.git &&
+ echo gitdir: ../8.git >.git &&
+ cd ..
+'
+
+test_expect_success '#8: at root' '
+ cat >8/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/8.git
+setup: worktree: $TRASH_DIRECTORY/8
+setup: cwd: $TRASH_DIRECTORY/8
+setup: prefix: (null)
+EOF
+ test_repo 8
+'
+
+test_expect_success '#8: in subdir' '
+ cat >8/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/8.git
+setup: worktree: $TRASH_DIRECTORY/8
+setup: cwd: $TRASH_DIRECTORY/8
+setup: prefix: sub/
+EOF
+ test_repo 8/sub
+'
+
+#
+# case #9
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #1 except that git_dir is set by .git file
+
+test_expect_success '#9: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 9 9/sub 9.wt 9.wt/sub 9/wt 9/wt/sub &&
+ cd 9 &&
+ git init &&
+ mv .git ../9.git &&
+ echo gitdir: ../9.git >.git &&
+ GIT_WORK_TREE=non-existent &&
+ export GIT_WORK_TREE &&
+ cd ..
+'
+
+test_expect_success '#9: at root' '
+ cat >9/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/9.git
+setup: worktree: $TRASH_DIRECTORY/9
+setup: cwd: $TRASH_DIRECTORY/9
+setup: prefix: (null)
+EOF
+ test_repo 9
+'
+
+test_expect_success '#9: in subdir' '
+ cat >9/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/9.git
+setup: worktree: $TRASH_DIRECTORY/9
+setup: cwd: $TRASH_DIRECTORY/9
+setup: prefix: sub/
+EOF
+ test_repo 9/sub
+'
+
+#
+# case #10
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #2 except that git_dir is set by .git file
+
+test_expect_success '#10: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 10 10/sub &&
+ cd 10 &&
+ git init &&
+ mv .git ../10.git &&
+ echo gitdir: ../10.git >.git &&
+ cd ..
+'
+
+test_expect_success '#10: at root' '
+ cat >10/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/10.git
+setup: worktree: $TRASH_DIRECTORY/10
+setup: cwd: $TRASH_DIRECTORY/10
+setup: prefix: (null)
+EOF
+ test_repo 10 "$TRASH_DIRECTORY/10/.git"
+'
+
+test_expect_success '#10: in subdir' '
+ cat >10/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/10.git
+setup: worktree: $TRASH_DIRECTORY/10/sub
+setup: cwd: $TRASH_DIRECTORY/10/sub
+setup: prefix: (null)
+EOF
+ test_repo 10/sub "$TRASH_DIRECTORY/10/.git"
+'
+
+test_expect_success '#10: relative GIT_DIR at root' '
+ cat >10/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/10.git
+setup: worktree: $TRASH_DIRECTORY/10
+setup: cwd: $TRASH_DIRECTORY/10
+setup: prefix: (null)
+EOF
+ test_repo 10 .git
+'
+
+test_expect_success '#10: relative GIT_DIR in subdir' '
+ cat >10/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/10.git
+setup: worktree: $TRASH_DIRECTORY/10/sub
+setup: cwd: $TRASH_DIRECTORY/10/sub
+setup: prefix: (null)
+EOF
+ test_repo 10/sub ../.git
+'
+
+#
+# case #11
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #3 except that git_dir is set by .git file
+
+test_expect_success '#11: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 11 11/sub 11/sub/sub 11.wt 11.wt/sub 11/wt 11/wt/sub &&
+ cd 11 &&
+ git init &&
+ mv .git ../11.git &&
+ echo gitdir: ../11.git >.git &&
+ cd ..
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 .git "$TRASH_DIRECTORY/11"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 .git .
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11"
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" .
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: sub/sub/
+EOF
+ test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: sub/sub/
+EOF
+ test_repo 11/sub/sub ../../.git ../..
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >11/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: sub/
+EOF
+ test_repo 11/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11"
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: sub/sub/
+EOF
+ test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../..
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 .git "$TRASH_DIRECTORY/11/wt"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 .git wt
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" wt
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11
+setup: prefix: (null)
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11/wt"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 11/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../wt
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY/11/wt
+setup: cwd: $TRASH_DIRECTORY/11/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/
+EOF
+ test_repo 11 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/
+EOF
+ test_repo 11 .git ..
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" ..
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >11/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/
+EOF
+ test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/sub/sub/
+EOF
+ test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/sub/sub/
+EOF
+ test_repo 11/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/sub/sub/
+EOF
+ test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../../
+'
+
+test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >11/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/11.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 11/sub/sub/
+EOF
+ test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #12
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #4 except that git_dir is set by .git file
+
+
+test_expect_success '#12: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 12 12/sub 12/sub/sub 12.wt 12.wt/sub 12/wt 12/wt/sub &&
+ cd 12 &&
+ git init &&
+ git config core.worktree non-existent &&
+ mv .git ../12.git &&
+ echo gitdir: ../12.git >.git &&
+ cd ..
+'
+
+test_expect_success '#12: at root' '
+ cat >12/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/12.git
+setup: worktree: $TRASH_DIRECTORY/12
+setup: cwd: $TRASH_DIRECTORY/12
+setup: prefix: (null)
+EOF
+ test_repo 12
+'
+
+test_expect_success '#12: in subdir' '
+ cat >12/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/12.git
+setup: worktree: $TRASH_DIRECTORY/12
+setup: cwd: $TRASH_DIRECTORY/12
+setup: prefix: sub/
+EOF
+ test_repo 12/sub
+'
+
+#
+# case #13
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #5 except that git_dir is set by .git file
+
+test_expect_success '#13: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 13 13/sub 13/sub/sub 13.wt 13.wt/sub 13/wt 13/wt/sub &&
+ cd 13 &&
+ git init &&
+ git config core.worktree non-existent &&
+ GIT_WORK_TREE=non-existent-too &&
+ export GIT_WORK_TREE &&
+ mv .git ../13.git &&
+ echo gitdir: ../13.git >.git &&
+ cd ..
+'
+
+test_expect_success '#13: at root' '
+ cat >13/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/13.git
+setup: worktree: $TRASH_DIRECTORY/13
+setup: cwd: $TRASH_DIRECTORY/13
+setup: prefix: (null)
+EOF
+ test_repo 13
+'
+
+test_expect_success '#13: in subdir' '
+ cat >13/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/13.git
+setup: worktree: $TRASH_DIRECTORY/13
+setup: cwd: $TRASH_DIRECTORY/13
+setup: prefix: sub/
+EOF
+ test_repo 13/sub
+'
+
+#
+# case #14
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #6 except that git_dir is set by .git file
+
+test_expect_success '#14: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 14 14/sub 14/sub/sub 14.wt 14.wt/sub 14/wt 14/wt/sub &&
+ cd 14 &&
+ git init &&
+ mv .git ../14.git &&
+ echo gitdir: ../14.git >.git &&
+ cd ..
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14 at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14 at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14 in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14 in subdir' '
+ cat >14/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" &&
+ test_repo 14/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 &&
+ test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14/wt(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14/wt at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14/wt(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt &&
+ test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=../14/wt in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY/14/wt
+setup: cwd: $TRASH_DIRECTORY/14/sub/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" &&
+ test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=.. at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=..(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. &&
+ test_repo 14 .git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=..(rel) at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=.. at root' '
+ cat >14/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 14 "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=.. in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR(rel), core.worktree=..(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. &&
+ test_repo 14/sub/sub ../../.git
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=..(rel) in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. &&
+ test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+test_expect_success '#14: GIT_DIR, core.worktree=.. in subdir' '
+ cat >14/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/14.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 14/sub/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" &&
+ test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
+'
+
+#
+# case #15
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is not set, cwd is outside .git
+#
+# Output:
+#
+# #7 except that git_dir is set by .git file
+
+test_expect_success '#15: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 15 15/sub 15/sub/sub 15.wt 15.wt/sub 15/wt 15/wt/sub &&
+ cd 15 &&
+ git init &&
+ git config core.worktree non-existent &&
+ mv .git ../15.git &&
+ echo gitdir: ../15.git >.git &&
+ cd ..
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 .git "$TRASH_DIRECTORY/15"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 .git .
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15"
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" .
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: sub/sub/
+EOF
+ test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: sub/sub/
+EOF
+ test_repo 15/sub/sub ../../.git ../..
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >15/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: sub/
+EOF
+ test_repo 15/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15"
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: sub/sub/
+EOF
+ test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../..
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 .git "$TRASH_DIRECTORY/15/wt"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 .git wt
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" wt
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15
+setup: prefix: (null)
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15/wt"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 15/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../wt
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY/15/wt
+setup: cwd: $TRASH_DIRECTORY/15/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/
+EOF
+ test_repo 15 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/
+EOF
+ test_repo 15 .git ..
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" ..
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >15/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/
+EOF
+ test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/sub/sub/
+EOF
+ test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/sub/sub/
+EOF
+ test_repo 15/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/sub/sub/
+EOF
+ test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../../
+'
+
+test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >15/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/15.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 15/sub/sub/
+EOF
+ test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #16.1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - cwd is inside .git
+#
+# Output:
+#
+# - no worktree
+# - cwd is unchanged
+# - prefix is NULL
+# - git_dir is set
+# - cwd can't be outside worktree
+
+test_expect_success '#16.1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 16 16/sub &&
+ cd 16 &&
+ git init &&
+ mkdir .git/wt .git/wt/sub &&
+ cd ..
+'
+
+test_expect_success '#16.1: at .git' '
+ cat >16/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git
+setup: prefix: (null)
+EOF
+ test_repo 16/.git
+'
+
+test_expect_success '#16.1: in .git/wt' '
+ cat >16/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/16/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 16/.git/wt
+'
+
+test_expect_success '#16.1: in .git/wt/sub' '
+ cat >16/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/16/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 16/.git/wt/sub
+'
+
+#
+# case #16.2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# - no worktree
+# - cwd is unchanged
+# - prefix is NULL
+# - git_dir is set
+# - cwd can't be outside worktree
+
+test_expect_success '#16.2: setup' '
+ git config --file="$TRASH_DIRECTORY/16/.git/config" core.bare true
+'
+
+test_expect_success '#16.2: at .git' '
+ cat >16/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git
+setup: prefix: (null)
+EOF
+ test_repo 16/.git
+'
+
+test_expect_success '#16.2: in .git/wt' '
+ cat >16/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/16/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 16/.git/wt
+'
+
+test_expect_success '#16.2: in .git/wt/sub' '
+ cat >16/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/16/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 16/.git/wt/sub
+'
+
+test_expect_success '#16.2: at root' '
+ cat >16/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16
+setup: prefix: (null)
+EOF
+ test_repo 16
+'
+
+test_expect_success '#16.2: in subdir' '
+ cat >16/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/16/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/16/sub
+setup: prefix: (null)
+EOF
+ test_repo 16/sub
+'
+
+#
+# case #17.1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - cwd is inside .git
+#
+# Output:
+#
+# GIT_WORK_TREE is ignored -> #16.1 (with warnings perhaps)
+
+test_expect_success '#17.1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 17 17/sub &&
+ cd 17 &&
+ git init &&
+ mkdir .git/wt .git/wt/sub &&
+ GIT_WORK_TREE=non-existent &&
+ export GIT_WORK_TREE &&
+ cd ..
+'
+
+test_expect_success '#17.1: at .git' '
+ cat >17/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git
+setup: prefix: (null)
+EOF
+ test_repo 17/.git
+'
+
+test_expect_success '#17.1: in .git/wt' '
+ cat >17/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/17/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 17/.git/wt
+'
+
+test_expect_success '#17.1: in .git/wt/sub' '
+ cat >17/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/17/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 17/.git/wt/sub
+'
+
+#
+# case #17.2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# GIT_WORK_TREE is ignored -> #16.2 (with warnings perhaps)
+
+test_expect_success '#17.2: setup' '
+ git config --file="$TRASH_DIRECTORY/17/.git/config" core.bare true
+'
+
+test_expect_success '#17.2: at .git' '
+ cat >17/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git
+setup: prefix: (null)
+EOF
+ test_repo 17/.git
+'
+
+test_expect_success '#17.2: in .git/wt' '
+ cat >17/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/17/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 17/.git/wt
+'
+
+test_expect_success '#17.2: in .git/wt/sub' '
+ cat >17/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/17/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 17/.git/wt/sub
+'
+
+test_expect_success '#17.2: at root' '
+ cat >17/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17
+setup: prefix: (null)
+EOF
+ test_repo 17
+'
+
+test_expect_success '#17.2: in subdir' '
+ cat >17/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/17/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/17/sub
+setup: prefix: (null)
+EOF
+ test_repo 17/sub
+'
+
+#
+# case #18
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# - no worktree (rule #8)
+# - cwd is unchanged
+# - prefix is NULL
+# - git_dir is set to $GIT_DIR
+# - cwd can't be outside worktree
+
+test_expect_success '#18: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 18 18/sub &&
+ cd 18 &&
+ git init &&
+ mkdir .git/wt .git/wt/sub &&
+ git config core.bare true &&
+ cd ..
+'
+
+test_expect_success '#18: (rel) at root' '
+ cat >18/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/18
+setup: prefix: (null)
+EOF
+ test_repo 18 .git
+'
+
+test_expect_success '#18: at root' '
+ cat >18/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/18/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/18
+setup: prefix: (null)
+EOF
+ test_repo 18 "$TRASH_DIRECTORY/18/.git"
+'
+
+test_expect_success '#18: (rel) in subdir' '
+ cat >18/sub/expected <<EOF &&
+setup: git_dir: ../.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/18/sub
+setup: prefix: (null)
+EOF
+ test_repo 18/sub ../.git
+'
+
+test_expect_success '#18: in subdir' '
+ cat >18/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/18/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/18/sub
+setup: prefix: (null)
+EOF
+ test_repo 18/sub "$TRASH_DIRECTORY/18/.git"
+'
+
+#
+# case #19
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - .git is a directory
+# - core.worktree is not set
+# - core.bare is set
+#
+# Output:
+#
+# bare repo is overridden by GIT_WORK_TREE -> #3
+
+test_expect_success '#19: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 19 19/sub 19/sub/sub 19.wt 19.wt/sub 19/wt 19/wt/sub &&
+ cd 19 &&
+ git init &&
+ git config core.bare true &&
+ cd ..
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 .git "$TRASH_DIRECTORY/19"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 .git .
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19"
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" .
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: sub/sub/
+EOF
+ test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY/19"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: sub/sub/
+EOF
+ test_repo 19/sub/sub ../../.git ../..
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >19/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: sub/
+EOF
+ test_repo 19/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19"
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: sub/sub/
+EOF
+ test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../..
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 .git "$TRASH_DIRECTORY/19/wt"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 .git wt
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" wt
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19
+setup: prefix: (null)
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19/wt"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY/19/wt"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 19/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../../wt
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY/19/wt
+setup: cwd: $TRASH_DIRECTORY/19/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19/wt"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/
+EOF
+ test_repo 19 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/
+EOF
+ test_repo 19 .git ..
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" ..
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >19/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/
+EOF
+ test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/sub/sub/
+EOF
+ test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/sub/sub/
+EOF
+ test_repo 19/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/sub/sub/
+EOF
+ test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../../../
+'
+
+test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >19/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/19/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 19/sub/sub/
+EOF
+ test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #20.1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - cwd is inside .git
+#
+# Output:
+#
+# core.worktree is ignored -> #16.1
+
+test_expect_success '#20.1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 20 20/sub &&
+ cd 20 &&
+ git init &&
+ git config core.worktree non-existent &&
+ mkdir .git/wt .git/wt/sub &&
+ cd ..
+'
+
+test_expect_success '#20.1: at .git' '
+ cat >20/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git
+setup: prefix: (null)
+EOF
+ test_repo 20/.git
+'
+
+test_expect_success '#20.1: in .git/wt' '
+ cat >20/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/20/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 20/.git/wt
+'
+
+test_expect_success '#20.1: in .git/wt/sub' '
+ cat >20/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/20/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 20/.git/wt/sub
+'
+
+#
+# case #20.2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# core.worktree is ignored -> #16.2
+
+test_expect_success '#20.2: setup' '
+ git config --file="$TRASH_DIRECTORY/20/.git/config" core.bare true
+'
+
+test_expect_success '#20.2: at .git' '
+ cat >20/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git
+setup: prefix: (null)
+EOF
+ test_repo 20/.git
+'
+
+test_expect_success '#20.2: in .git/wt' '
+ cat >20/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/20/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 20/.git/wt
+'
+
+test_expect_success '#20.2: in .git/wt/sub' '
+ cat >20/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/20/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 20/.git/wt/sub
+'
+
+test_expect_success '#20.2: at root' '
+ cat >20/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20
+setup: prefix: (null)
+EOF
+ test_repo 20
+'
+
+test_expect_success '#20.2: in subdir' '
+ cat >20/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/20/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/20/sub
+setup: prefix: (null)
+EOF
+ test_repo 20/sub
+'
+
+#
+# case #21.1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - cwd is inside .git
+#
+# Output:
+#
+# GIT_WORK_TREE/core.worktree are ignored -> #20.1
+
+test_expect_success '#21.1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 21 21/sub &&
+ cd 21 &&
+ git init &&
+ git config core.worktree non-existent &&
+ GIT_WORK_TREE=non-existent-too &&
+ export GIT_WORK_TREE &&
+ mkdir .git/wt .git/wt/sub &&
+ cd ..
+'
+
+test_expect_success '#21.1: at .git' '
+ cat >21/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git
+setup: prefix: (null)
+EOF
+ test_repo 21/.git
+'
+
+test_expect_success '#21.1: in .git/wt' '
+ cat >21/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/21/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 21/.git/wt
+'
+
+test_expect_success '#21.1: in .git/wt/sub' '
+ cat >21/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/21/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 21/.git/wt/sub
+'
+
+#
+# case #21.2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# GIT_WORK_TREE/core.worktree are ignored -> #20.2
+
+test_expect_success '#21.2: setup' '
+ git config --file="$TRASH_DIRECTORY/21/.git/config" core.bare true
+'
+
+test_expect_success '#21.2: at .git' '
+ cat >21/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git
+setup: prefix: (null)
+EOF
+ test_repo 21/.git
+'
+
+test_expect_success '#21.2: in .git/wt' '
+ cat >21/.git/wt/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/21/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git/wt
+setup: prefix: (null)
+EOF
+ test_repo 21/.git/wt
+'
+
+test_expect_success '#21.2: in .git/wt/sub' '
+ cat >21/.git/wt/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/21/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/.git/wt/sub
+setup: prefix: (null)
+EOF
+ test_repo 21/.git/wt/sub
+'
+
+test_expect_success '#21.2: at root' '
+ cat >21/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21
+setup: prefix: (null)
+EOF
+ test_repo 21
+'
+
+test_expect_success '#21.2: in subdir' '
+ cat >21/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/21/.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/21/sub
+setup: prefix: (null)
+EOF
+ test_repo 21/sub
+'
+
+#
+# case #22.1
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a directory
+# - cwd is inside .git
+#
+# Output:
+#
+# bare attribute is ignored
+#
+# - worktree is at core.worktree
+# - cwd is at worktree root
+# - prefix is calculated
+# - git_dir is at $GIT_DIR
+# - cwd can be outside worktree
+
+test_expect_success '#22.1: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 22 &&
+ cd 22 &&
+ git init &&
+ mkdir .git/sub .git/wt .git/wt/sub &&
+ cd ..
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=. at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.(rel) at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=. at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=.(rel) at root' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=. in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" &&
+ test_repo 22/.git/sub ..
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . &&
+ test_repo 22/.git/sub/ ..
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=. in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=.(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt(rel) at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: .
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=wt(rel) at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=wt at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: ..
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" &&
+ test_repo 22/.git/sub ..
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: ..
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt &&
+ test_repo 22/.git/sub ..
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=wt(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=wt in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22/.git/wt
+setup: cwd: $TRASH_DIRECTORY/22/.git/sub
+setup: prefix: (null)
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.. at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=..(rel) at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. &&
+ test_repo 22/.git .
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=..(rel) at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=.. at .git' '
+ cat >22/.git/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" &&
+ test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.. in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" &&
+ test_repo 22/.git/sub ..
+'
+
+test_expect_success '#22.1: GIT_DIR(rel), core.worktree=..(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. &&
+ test_repo 22/.git/sub ..
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=..(rel) in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+test_expect_success '#22.1: GIT_DIR, core.worktree=.. in .git/sub' '
+ cat >22/.git/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/22/.git
+setup: worktree: $TRASH_DIRECTORY/22
+setup: cwd: $TRASH_DIRECTORY/22
+setup: prefix: .git/sub/
+EOF
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" &&
+ test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
+'
+
+#
+# case #22.2
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# core.worktree and core.bare conflict, won't fly.
+
+test_expect_success '#22.2: setup' '
+ git config --file="$TRASH_DIRECTORY/22/.git/config" core.bare true
+'
+
+test_expect_success '#22.2: at .git' '
+ (
+ cd 22/.git &&
+ GIT_DIR=. &&
+ export GIT_DIR &&
+ test_must_fail git symbolic-ref HEAD 2>result &&
+ grep "core.bare and core.worktree do not make sense" result
+ )
+'
+
+test_expect_success '#22.2: at root' '
+ (
+ cd 22 &&
+ GIT_DIR=.git &&
+ export GIT_DIR &&
+ test_must_fail git symbolic-ref HEAD 2>result &&
+ grep "core.bare and core.worktree do not make sense" result
+ )
+'
+
+#
+# case #23
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a directory
+# - core.bare is set
+#
+# Output:
+#
+# core.worktree is overridden by GIT_WORK_TREE -> #19
+
+test_expect_success '#23: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 23 23/sub 23/sub/sub 23.wt 23.wt/sub 23/wt 23/wt/sub &&
+ cd 23 &&
+ git init &&
+ git config core.bare true &&
+ git config core.worktree non-existent &&
+ cd ..
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 .git "$TRASH_DIRECTORY/23"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 .git .
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23"
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" .
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: sub/sub/
+EOF
+ test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY/23"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: sub/sub/
+EOF
+ test_repo 23/sub/sub ../../.git ../..
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >23/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: sub/
+EOF
+ test_repo 23/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23"
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: sub/sub/
+EOF
+ test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../..
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 .git "$TRASH_DIRECTORY/23/wt"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: .git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 .git wt
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" wt
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23
+setup: prefix: (null)
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23/wt"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY/23/wt"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: ../../.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 23/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../../wt
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY/23/wt
+setup: cwd: $TRASH_DIRECTORY/23/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23/wt"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/
+EOF
+ test_repo 23 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/
+EOF
+ test_repo 23 .git ..
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" ..
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >23/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/
+EOF
+ test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/sub/sub/
+EOF
+ test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/sub/sub/
+EOF
+ test_repo 23/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/sub/sub/
+EOF
+ test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../../../
+'
+
+test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >23/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/23/.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 23/sub/sub/
+EOF
+ test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #24
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# #16.2 except git_dir is set according to .git file
+
+test_expect_success '#24: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 24 24/sub &&
+ cd 24 &&
+ git init &&
+ git config core.bare true &&
+ mv .git ../24.git &&
+ echo gitdir: ../24.git >.git &&
+ cd ..
+'
+
+test_expect_success '#24: at root' '
+ cat >24/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/24.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/24
+setup: prefix: (null)
+EOF
+ test_repo 24
+'
+
+test_expect_success '#24: in subdir' '
+ cat >24/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/24.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/24/sub
+setup: prefix: (null)
+EOF
+ test_repo 24/sub
+'
+
+#
+# case #25
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# #17.2 except git_dir is set according to .git file
+
+test_expect_success '#25: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 25 25/sub &&
+ cd 25 &&
+ git init &&
+ git config core.bare true &&
+ GIT_WORK_TREE=non-existent &&
+ export GIT_WORK_TREE &&
+ mv .git ../25.git &&
+ echo gitdir: ../25.git >.git &&
+ cd ..
+'
+
+test_expect_success '#25: at root' '
+ cat >25/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/25.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/25
+setup: prefix: (null)
+EOF
+ test_repo 25
+'
+
+test_expect_success '#25: in subdir' '
+ cat >25/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/25.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/25/sub
+setup: prefix: (null)
+EOF
+ test_repo 25/sub
+'
+
+#
+# case #26
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is not set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# #18 except git_dir is set according to .git file
+
+test_expect_success '#26: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 26 26/sub &&
+ cd 26 &&
+ git init &&
+ git config core.bare true &&
+ mv .git ../26.git &&
+ echo gitdir: ../26.git >.git &&
+ cd ..
+'
+
+test_expect_success '#26: (rel) at root' '
+ cat >26/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/26.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/26
+setup: prefix: (null)
+EOF
+ test_repo 26 .git
+'
+
+test_expect_success '#26: at root' '
+ cat >26/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/26.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/26
+setup: prefix: (null)
+EOF
+ test_repo 26 "$TRASH_DIRECTORY/26/.git"
+'
+
+test_expect_success '#26: (rel) in subdir' '
+ cat >26/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/26.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/26/sub
+setup: prefix: (null)
+EOF
+ test_repo 26/sub ../.git
+'
+
+test_expect_success '#26: in subdir' '
+ cat >26/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/26.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/26/sub
+setup: prefix: (null)
+EOF
+ test_repo 26/sub "$TRASH_DIRECTORY/26/.git"
+'
+
+#
+# case #27
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - .git is a file
+# - core.worktree is not set
+# - core.bare is set
+#
+# Output:
+#
+# #19 except git_dir is set according to .git file
+
+test_expect_success '#27: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 27 27/sub 27/sub/sub 27.wt 27.wt/sub 27/wt 27/wt/sub &&
+ cd 27 &&
+ git init &&
+ git config core.bare true &&
+ mv .git ../27.git &&
+ echo gitdir: ../27.git >.git &&
+ cd ..
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 .git "$TRASH_DIRECTORY/27"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 .git .
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27"
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" .
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: sub/sub/
+EOF
+ test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: sub/sub/
+EOF
+ test_repo 27/sub/sub ../../.git ../..
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >27/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: sub/
+EOF
+ test_repo 27/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27"
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: sub/sub/
+EOF
+ test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../..
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 .git "$TRASH_DIRECTORY/27/wt"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 .git wt
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" wt
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27
+setup: prefix: (null)
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27/wt"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 27/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../wt
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY/27/wt
+setup: cwd: $TRASH_DIRECTORY/27/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/
+EOF
+ test_repo 27 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/
+EOF
+ test_repo 27 .git ..
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" ..
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >27/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/
+EOF
+ test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/sub/sub/
+EOF
+ test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/sub/sub/
+EOF
+ test_repo 27/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/sub/sub/
+EOF
+ test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../../
+'
+
+test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >27/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/27.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 27/sub/sub/
+EOF
+ test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY"
+'
+
+#
+# case #28
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# core.worktree is ignored -> #24
+
+test_expect_success '#28: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 28 28/sub &&
+ cd 28 &&
+ git init &&
+ git config core.bare true &&
+ git config core.worktree non-existent &&
+ mv .git ../28.git &&
+ echo gitdir: ../28.git >.git &&
+ cd ..
+'
+
+test_expect_success '#28: at root' '
+ cat >28/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/28.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/28
+setup: prefix: (null)
+EOF
+ test_repo 28
+'
+
+test_expect_success '#28: in subdir' '
+ cat >28/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/28.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/28/sub
+setup: prefix: (null)
+EOF
+ test_repo 28/sub
+'
+
+#
+# case #29
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is not set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# GIT_WORK_TREE/core.worktree are ignored -> #28
+
+test_expect_success '#29: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 29 29/sub &&
+ cd 29 &&
+ git init &&
+ git config core.bare true &&
+ GIT_WORK_TREE=non-existent &&
+ export GIT_WORK_TREE &&
+ mv .git ../29.git &&
+ echo gitdir: ../29.git >.git &&
+ cd ..
+'
+
+test_expect_success '#29: at root' '
+ cat >29/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/29.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/29
+setup: prefix: (null)
+EOF
+ test_repo 29
+'
+
+test_expect_success '#29: in subdir' '
+ cat >29/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/29.git
+setup: worktree: (null)
+setup: cwd: $TRASH_DIRECTORY/29/sub
+setup: prefix: (null)
+EOF
+ test_repo 29/sub
+'
+
+#
+# case #30
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is not set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# core.worktree and core.bare conflict, won't fly.
+
+test_expect_success '#30: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 30 &&
+ cd 30 &&
+ git init &&
+ git config core.bare true &&
+ git config core.worktree non-existent &&
+ mv .git ../30.git &&
+ echo gitdir: ../30.git >.git &&
+ cd ..
+'
+
+test_expect_success '#30: at root' '
+ (
+ cd 30 &&
+ GIT_DIR=.git &&
+ export GIT_DIR &&
+ test_must_fail git symbolic-ref HEAD 2>result &&
+ grep "core.bare and core.worktree do not make sense" result
+ )
+'
+
+#
+# case #31
+#
+############################################################
+#
+# Input:
+#
+# - GIT_WORK_TREE is set
+# - GIT_DIR is set
+# - core.worktree is set
+# - .git is a file
+# - core.bare is set
+#
+# Output:
+#
+# #23 except git_dir is set according to .git file
+
+test_expect_success '#31: setup' '
+ sane_unset GIT_DIR GIT_WORK_TREE &&
+ mkdir 31 31/sub 31/sub/sub 31.wt 31.wt/sub 31/wt 31/wt/sub &&
+ cd 31 &&
+ git init &&
+ git config core.bare true &&
+ git config core.worktree non-existent &&
+ mv .git ../31.git &&
+ echo gitdir: ../31.git >.git &&
+ cd ..
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 .git "$TRASH_DIRECTORY/31"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 .git .
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=root at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31"
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" .
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: sub/sub/
+EOF
+ test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: sub/sub/
+EOF
+ test_repo 31/sub/sub ../../.git ../..
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORKTREE=root in subdir' '
+ cat >31/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: sub/
+EOF
+ test_repo 31/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31"
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: sub/sub/
+EOF
+ test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../..
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 .git "$TRASH_DIRECTORY/31/wt"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 .git wt
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" wt
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31
+setup: prefix: (null)
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31/wt"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 31/sub/sub ../../.git ../../wt
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../wt
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY/31/wt
+setup: cwd: $TRASH_DIRECTORY/31/sub/sub
+setup: prefix: (null)
+EOF
+ test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/
+EOF
+ test_repo 31 .git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/
+EOF
+ test_repo 31 .git ..
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" ..
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=.. at root' '
+ cat >31/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/
+EOF
+ test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/sub/sub/
+EOF
+ test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY"
+'
+
+test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/sub/sub/
+EOF
+ test_repo 31/sub/sub ../../.git ../../..
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/sub/sub/
+EOF
+ test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../../
+'
+
+test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+ cat >31/sub/sub/expected <<EOF &&
+setup: git_dir: $TRASH_DIRECTORY/31.git
+setup: worktree: $TRASH_DIRECTORY
+setup: cwd: $TRASH_DIRECTORY
+setup: prefix: 31/sub/sub/
+EOF
+ test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY"
+'
+
+test_done
diff --git a/t/t3032-merge-recursive-options.sh b/t/t3032-merge-recursive-options.sh
index 2293797553..44f5421be4 100755
--- a/t/t3032-merge-recursive-options.sh
+++ b/t/t3032-merge-recursive-options.sh
@@ -13,16 +13,19 @@ test_description='merge-recursive options
. ./test-lib.sh
+test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b
+test_have_prereq MINGW && export GREP_OPTIONS=-U
+
test_expect_success 'setup' '
conflict_hunks () {
- sed -n -e "
- /^<<<</ b inconflict
+ sed $SED_OPTIONS -n -e "
+ /^<<<</ b conflict
b
- : inconflict
+ : conflict
p
/^>>>>/ b
n
- b inconflict
+ b conflict
" "$@"
} &&
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index dc2e04a016..1921ca3a73 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -1067,7 +1067,7 @@ test_expect_success 'git notes copy diagnoses too many or too few parameters' '
test_expect_success 'git notes get-ref (no overrides)' '
git config --unset core.notesRef &&
- unset GIT_NOTES_REF &&
+ sane_unset GIT_NOTES_REF &&
test "$(git notes get-ref)" = "refs/notes/commits"
'
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index d3a3bd2679..7d8147bb93 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -71,8 +71,9 @@ test_expect_success 'setup' '
# "exec" commands are ran with the user shell by default, but this may
# be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work
# to create a file. Unseting SHELL avoids such non-portable behavior
-# in tests.
+# in tests. It must be exported for it to take effect where needed.
SHELL=
+export SHELL
test_expect_success 'rebase -i with the exec command' '
git checkout master &&
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index 552da65a61..baa670cea5 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -10,7 +10,11 @@ test_expect_success 'setup' '
test_commit A foo A &&
test_commit B foo B &&
test_commit C foo C &&
- test_commit D foo D
+ test_commit D foo D &&
+ git checkout A^0 &&
+ test_commit E bar E &&
+ test_commit F foo F &&
+ git checkout master
'
mkdir .git/hooks
@@ -79,6 +83,18 @@ EOF
verify_hook_input
'
+test_expect_success 'git rebase --skip the last one' '
+ git reset --hard F &&
+ clear_hook_input &&
+ test_must_fail git rebase --onto D A &&
+ git rebase --skip &&
+ echo rebase >expected.args &&
+ cat >expected.data <<EOF &&
+$(git rev-parse E) $(git rev-parse HEAD)
+EOF
+ verify_hook_input
+'
+
test_expect_success 'git rebase -m' '
git reset --hard D &&
clear_hook_input &&
diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh
index 460bf741b5..d9c2d386dd 100755
--- a/t/t6038-merge-text-auto.sh
+++ b/t/t6038-merge-text-auto.sh
@@ -14,7 +14,7 @@ test_description='CRLF merge conflict across text=auto change
. ./test-lib.sh
-test_have_prereq MINGW && SED_OPTIONS=-b
+test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b
test_expect_success setup '
git config core.autocrlf false &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 2c49db9f62..874279e32d 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -446,4 +446,42 @@ test_expect_success 'add should fail when path is used by an existing directory'
)
'
+test_expect_success 'set up for relative path tests' '
+ mkdir reltest &&
+ (
+ cd reltest &&
+ git init &&
+ mkdir sub &&
+ (
+ cd sub &&
+ git init &&
+ test_commit foo
+ ) &&
+ git add sub &&
+ git config -f .gitmodules submodule.sub.path sub &&
+ git config -f .gitmodules submodule.sub.url ../subrepo &&
+ cp .git/config pristine-.git-config
+ )
+'
+
+test_expect_success 'relative path works with URL' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ git config remote.origin.url ssh://hostname/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
+ )
+'
+
+test_expect_success 'relative path works with user@host:path' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ git config remote.origin.url user@host:repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = user@host:subrepo
+ )
+'
+
test_done
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 5e48318013..579ddb7572 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -265,7 +265,7 @@ test_expect_success $PREREQ 'Author From: in message body' '
--to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
$patches &&
- sed "1,/^\$/d" < msgtxt1 > msgbody1
+ sed "1,/^\$/d" < msgtxt1 > msgbody1 &&
grep "From: A <author@example.com>" msgbody1
'
@@ -276,7 +276,7 @@ test_expect_success $PREREQ 'Author From: not in message body' '
--to=nobody@example.com \
--smtp-server="$(pwd)/fake.sendmail" \
$patches &&
- sed "1,/^\$/d" < msgtxt1 > msgbody1
+ sed "1,/^\$/d" < msgtxt1 > msgbody1 &&
! grep "From: A <author@example.com>" msgbody1
'
@@ -298,7 +298,7 @@ test_expect_success $PREREQ 'Invalid In-Reply-To' '
--in-reply-to=" " \
--smtp-server="$(pwd)/fake.sendmail" \
$patches \
- 2>errors
+ 2>errors &&
! grep "^In-Reply-To: < *>" msgtxt1
'
@@ -319,7 +319,7 @@ test_expect_success $PREREQ 'In-Reply-To without --chain-reply-to' '
git send-email \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
- --no-chain-reply-to \
+ --nochain-reply-to \
--in-reply-to="$(cat expect)" \
--smtp-server="$(pwd)/fake.sendmail" \
$patches $patches $patches \
@@ -617,7 +617,7 @@ EOF
"
test_expect_success $PREREQ '--suppress-cc=sob' '
- git config --unset sendemail.cccmd
+ test_might_fail git config --unset sendemail.cccmd &&
test_suppression sob
'
@@ -1135,7 +1135,7 @@ test_expect_success $PREREQ '--8bit-encoding also treats subject' '
# Note that the patches in this test are deliberately out of order; we
# want to make sure it works even if the cover-letter is not in the
# first mail.
-test_expect_success 'refusing to send cover letter template' '
+test_expect_success $PREREQ 'refusing to send cover letter template' '
clean_fake_sendmail &&
rm -fr outdir &&
git format-patch --cover-letter -2 -o outdir &&
@@ -1151,7 +1151,7 @@ test_expect_success 'refusing to send cover letter template' '
test -z "$(ls msgtxt*)"
'
-test_expect_success '--force sends cover letter template anyway' '
+test_expect_success $PREREQ '--force sends cover letter template anyway' '
clean_fake_sendmail &&
rm -fr outdir &&
git format-patch --cover-letter -2 -o outdir &&
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index faf9092967..88a9751dd3 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -4,45 +4,55 @@ test_description='check svn dumpfile importer'
. ./test-lib.sh
-if ! svnadmin -h >/dev/null 2>&1
-then
- skip_all='skipping svn-fe tests, svn not available'
- test_done
-fi
-
-svnconf=$PWD/svnconf
-export svnconf
-
-svn_cmd () {
- subcommand=$1 &&
- shift &&
- mkdir -p "$svnconf" &&
- svn "$subcommand" --config-dir "$svnconf" "$@"
+reinit_git () {
+ rm -fr .git &&
+ git init
}
-test_dump () {
- label=$1
- dump=$2
- test_expect_success "$dump" '
- svnadmin create "$label-svn" &&
- svnadmin load "$label-svn" < "$TEST_DIRECTORY/$dump" &&
- svn_cmd export "file://$PWD/$label-svn" "$label-svnco" &&
- git init "$label-git" &&
- test-svn-fe "$TEST_DIRECTORY/$dump" >"$label.fe" &&
- (
- cd "$label-git" &&
- git fast-import < ../"$label.fe"
- ) &&
- (
- cd "$label-svnco" &&
- git init &&
- git add . &&
- git fetch "../$label-git" master &&
- git diff --exit-code FETCH_HEAD
- )
- '
-}
+>empty
+
+test_expect_success 'empty dump' '
+ reinit_git &&
+ echo "SVN-fs-dump-format-version: 2" >input &&
+ test-svn-fe input >stream &&
+ git fast-import <stream
+'
+
+test_expect_success 'v3 dumps not supported' '
+ reinit_git &&
+ echo "SVN-fs-dump-format-version: 3" >input &&
+ test_must_fail test-svn-fe input >stream &&
+ test_cmp empty stream
+'
+
+test_expect_success 'set up svn repo' '
+ svnconf=$PWD/svnconf &&
+ mkdir -p "$svnconf" &&
-test_dump simple t9135/svn.dump
+ if
+ svnadmin -h >/dev/null 2>&1 &&
+ svnadmin create simple-svn &&
+ svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
+ svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
+ then
+ test_set_prereq SVNREPO
+ fi
+'
+
+test_expect_success SVNREPO 't9135/svn.dump' '
+ git init simple-git &&
+ test-svn-fe "$TEST_DIRECTORY/t9135/svn.dump" >simple.fe &&
+ (
+ cd simple-git &&
+ git fast-import <../simple.fe
+ ) &&
+ (
+ cd simple-svnco &&
+ git init &&
+ git add . &&
+ git fetch ../simple-git master &&
+ git diff --exit-code FETCH_HEAD
+ )
+'
test_done
diff --git a/t/t9157-git-svn-fetch-merge.sh b/t/t9157-git-svn-fetch-merge.sh
index da582c5382..991d2aa1be 100755
--- a/t/t9157-git-svn-fetch-merge.sh
+++ b/t/t9157-git-svn-fetch-merge.sh
@@ -6,6 +6,14 @@
test_description='git svn merge detection'
. ./lib-git-svn.sh
+svn_ver="$(svn --version --quiet)"
+case $svn_ver in
+0.* | 1.[0-4].*)
+ skip_all="skipping git-svn test - SVN too old ($svn_ver)"
+ test_done
+ ;;
+esac
+
test_expect_success 'initialize source svn repo' '
svn_cmd mkdir -m x "$svnrepo"/trunk &&
svn_cmd mkdir -m x "$svnrepo"/branches &&
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index 432b82e3d5..4c384ff023 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -89,7 +89,8 @@ EOF
test_expect_success PERL 'update git module' '
(cd module-git &&
- git cvsimport -a -R -z 0 module &&
+ git config cvsimport.trackRevisions true &&
+ git cvsimport -a -z 0 module &&
git merge origin
) &&
test_cmp module-cvs/o_fortuna module-git/o_fortuna
@@ -117,7 +118,8 @@ test_expect_success PERL 'cvsimport.module config works' '
(cd module-git &&
git config cvsimport.module module &&
- git cvsimport -a -R -z0 &&
+ git config cvsimport.trackRevisions true &&
+ git cvsimport -a -z0 &&
git merge origin
) &&
test_cmp module-cvs/tick module-git/tick
@@ -137,6 +139,7 @@ test_expect_success PERL 'import from a CVS working tree' '
$CVS co -d import-from-wt module &&
(cd import-from-wt &&
+ git config cvsimport.trackRevisions false &&
git cvsimport -a -z0 &&
echo 1 >expect &&
git log -1 --pretty=format:%s%n >actual &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cb1ca973aa..42f2f14496 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1057,6 +1057,13 @@ case $(uname -s) in
# backslashes in pathspec are converted to '/'
# exec does not inherit the PID
test_set_prereq MINGW
+ test_set_prereq SED_STRIPS_CR
+ ;;
+*CYGWIN*)
+ test_set_prereq POSIXPERM
+ test_set_prereq EXECKEEPSPID
+ test_set_prereq NOT_MINGW
+ test_set_prereq SED_STRIPS_CR
;;
*)
test_set_prereq POSIXPERM