# [PATCH 00/47] nd/setup updates on pu

87 messages from 2010-11-26 to 2011-01-26. Participants: Nguyễn Thái Ngọc Duy, Junio C Hamano, Nguyen Thai Ngoc Duy, Jonathan Nieder, Maaartin, Sverre Rabbelier, Jeff King.
Thread: https://gitlist.dev/t/25845

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:31

Subject: [PATCH 00/47] nd/setup updates on pu
Message-ID: <1290785563-15339-1-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-1-git-send-email-pclouds%40gmail.com

```
Only tests are updated to eliminate bashisms. Tested on busybox ash.

Jonathan Nieder (2):
  git-rev-parse.txt: clarify --git-dir
  t0001: test git init when run via an alias

Michael J Gruber (1):
  t1020-subdirectory: test alias expansion in a subdirectory

Nguyễn Thái Ngọc Duy (44):
  builtins: print setup info if repo is found
  Add t1510 and basic rules that run repo setup
  t1510: setup case #0
  t1510: setup case #1
  t1510: setup case #2
  t1510: setup case #3
  t1510: setup case #4
  t1510: setup case #5
  t1510: setup case #6
  t1510: setup case #7
  t1510: setup case #8
  t1510: setup case #9
  t1510: setup case #10
  t1510: setup case #11
  t1510: setup case #12
  t1510: setup case #13
  t1510: setup case #14
  t1510: setup case #15
  t1510: setup case #16
  t1510: setup case #17
  t1510: setup case #18
  t1510: setup case #19
  t1510: setup case #20
  t1510: setup case #21
  t1510: setup case #22
  t1510: setup case #23
  t1510: setup case #24
  t1510: setup case #25
  t1510: setup case #26
  t1510: setup case #27
  t1510: setup case #28
  t1510: setup case #29
  t1510: setup case #30
  t1510: setup case #31
  rev-parse: prints --git-dir relative to user's cwd
  Add git_config_early()
  Use git_config_early() instead of git_config() during repo setup
  setup: limit get_git_work_tree()'s to explicit setup case only
  setup: clean up setup_bare_git_dir()
  setup: clean up setup_discovered_git_dir()
  setup: rework setup_explicit_git_dir()
  Remove all logic from get_git_work_tree()
  Revert "Documentation: always respect core.worktree if set"
  git.txt: correct where --work-tree path is relative to

 Documentation/config.txt        |   23 +-
 Documentation/git-rev-parse.txt |    7 +-
 Documentation/git.txt           |    2 +-
 builtin/init-db.c               |   13 +-
 builtin/rev-parse.c             |    6 +-
 cache.h                         |    2 +
 config.c                        |   19 +-
 environment.c                   |   26 +-
 git.c                           |    4 +
 setup.c                         |  230 ++-
 t/t0001-init.sh                 |   56 +
 t/t1020-subdirectory.sh         |    8 +
 t/t1510-repo-setup.sh           | 4532 +++++++++++++++++++++++++++++++++++++++
 trace.c                         |   42 +
 14 files changed, 4835 insertions(+), 135 deletions(-)
 create mode 100755 t/t1510-repo-setup.sh

-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:31

Subject: [PATCH 01/47] builtins: print setup info if repo is found
Message-ID: <1290785563-15339-2-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-2-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache.h |    1 +
 git.c   |    4 ++++
 trace.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/cache.h b/cache.h
index 33decd9..d1bee5d 100644
--- a/cache.h
+++ b/cache.h
@@ -1062,6 +1062,7 @@ __attribute__((format (printf, 1, 2)))
 extern void trace_printf(const char *format, ...);
 __attribute__((format (printf, 2, 3)))
 extern void trace_argv_printf(const char **argv, const char *format, ...);
+extern void trace_repo_setup(const char *prefix);
 
 /* convert.c */
 /* returns 1 if *dst was used */
diff --git a/git.c b/git.c
index 0409ac9..6793178 100644
--- a/git.c
+++ b/git.c
@@ -264,6 +264,10 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 			use_pager = check_pager_config(p->cmd);
 		if (use_pager == -1 && p->option & USE_PAGER)
 			use_pager = 1;
+
+		if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
+		    startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
+			trace_repo_setup(prefix);
 	}
 	commit_pager_choice();
 
diff --git a/trace.c b/trace.c
index 1e560cb..bdb5d2f 100644
--- a/trace.c
+++ b/trace.c
@@ -131,3 +131,45 @@ void trace_argv_printf(const char **argv, const char *fmt, ...)
 	if (need_close)
 		close(fd);
 }
+
+static const char *quote_crnl(const char *path)
+{
+	static char new_path[PATH_MAX];
+	const char *p2 = path;
+	char *p1 = new_path;
+
+	if (!path)
+		return NULL;
+
+	while (*p2) {
+		switch (*p2) {
+		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
+		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
+		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
+		default:
+			*p1++ = *p2;
+		}
+		p2++;
+	}
+	*p1 = '\0';
+	return new_path;
+}
+
+/* FIXME: move prefix to startup_info struct and get rid of this arg */
+void trace_repo_setup(const char *prefix)
+{
+	char cwd[PATH_MAX];
+	char *trace = getenv("GIT_TRACE");
+
+	if (!trace || !strcmp(trace, "") ||
+	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
+		return;
+
+	if (!getcwd(cwd, PATH_MAX))
+		die("Unable to get current working directory");
+
+	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+	trace_printf("setup: worktree: %s\n", quote_crnl(get_git_work_tree()));
+	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
+	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
+}
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:31

Subject: [PATCH 02/47] Add t1510 and basic rules that run repo setup
Message-ID: <1290785563-15339-3-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-3-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   59 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+), 0 deletions(-)
 create mode 100755 t/t1510-repo-setup.sh

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
new file mode 100755
index 0000000..623807d
--- /dev/null
+++ b/t/t1510-repo-setup.sh
@@ -0,0 +1,59 @@
+#!/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() {
+	(
+	if [ -n "$1" ]; then cd "$1"; fi &&
+	if [ -f trace ]; then rm trace; fi &&
+	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
+
+test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:31

Subject: [PATCH 03/47] t1510: setup case #0
Message-ID: <1290785563-15339-4-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-4-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   53 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 623807d..641731c 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -41,8 +41,10 @@ test_description='Tests of cwd/prefix/worktree/gitdir setup in all cases'
 
 test_repo() {
 	(
-	if [ -n "$1" ]; then cd "$1"; fi &&
-	if [ -f trace ]; then rm trace; fi &&
+	cd "$1" &&
+	if [ -n "$2" ]; then GIT_DIR="$2" && export GIT_DIR; fi &&
+	if [ -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
@@ -56,4 +58,51 @@ test_repo() {
 # 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' '
+	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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 04/47] t1510: setup case #1
Message-ID: <1290785563-15339-5-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-5-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 641731c..4e9c425 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -105,4 +105,51 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 05/47] t1510: setup case #2
Message-ID: <1290785563-15339-6-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-6-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   67 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 4e9c425..febf9c4 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -152,4 +152,71 @@ 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' '
+	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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 06/47] t1510: setup case #3
Message-ID: <1290785563-15339-7-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-7-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  267 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 267 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index febf9c4..9fff0b6 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -219,4 +219,271 @@ 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' '
+	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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 07/47] t1510: setup case #4
Message-ID: <1290785563-15339-8-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-8-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9fff0b6..655f603 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -486,4 +486,50 @@ 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' '
+	unset GIT_DIR GIT_WORK_TREE &&
+	mkdir 4 4/sub &&
+	cd 4 &&
+	git init &&
+	git config core.worktree non-existent &&
+	cd ..
+'
+
+test_expect_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 08/47] t1510: setup case #5
Message-ID: <1290785563-15339-9-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-9-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 655f603..369f237 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -532,4 +532,52 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 09/47] t1510: setup case #6
Message-ID: <1290785563-15339-10-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-10-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |  291 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 291 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 369f237..4b2e60e 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -580,4 +580,295 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 10/47] t1510: setup case #7
Message-ID: <1290785563-15339-11-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-11-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  266 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 266 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 4b2e60e..ccd7036 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -871,4 +871,270 @@ EOF
 	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' '
+	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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 11/47] t1510: setup case #8
Message-ID: <1290785563-15339-12-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-12-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index ccd7036..d1601e8 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1137,4 +1137,51 @@ 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' '
+	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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 12/47] t1510: setup case #9
Message-ID: <1290785563-15339-13-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-13-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index d1601e8..e258869 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1184,4 +1184,53 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 13/47] t1510: setup case #10
Message-ID: <1290785563-15339-14-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-14-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   67 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index e258869..3f19ff1 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1233,4 +1233,71 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 14/47] t1510: setup case #11
Message-ID: <1290785563-15339-15-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-15-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  267 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 267 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 3f19ff1..ac95808 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1300,4 +1300,271 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 15/47] t1510: setup case #12
Message-ID: <1290785563-15339-16-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-16-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index ac95808..b86895f 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1567,4 +1567,53 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 16/47] t1510: setup case #13
Message-ID: <1290785563-15339-17-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-17-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index b86895f..c2cc504 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1616,4 +1616,54 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 17/47] t1510: setup case #14
Message-ID: <1290785563-15339-18-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-18-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  291 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 291 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index c2cc504..617a14d 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1666,4 +1666,295 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 18/47] t1510: setup case #15
Message-ID: <1290785563-15339-19-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-19-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  268 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 617a14d..732053d 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1957,4 +1957,272 @@ EOF
 	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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 19/47] t1510: setup case #16
Message-ID: <1290785563-15339-20-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-20-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |  135 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 135 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 732053d..0f7a2d9 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2225,4 +2225,139 @@ 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' '
+	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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 20/47] t1510: setup case #17
Message-ID: <1290785563-15339-21-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-21-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  129 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 0f7a2d9..e298a16 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2360,4 +2360,133 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 21/47] t1510: setup case #18
Message-ID: <1290785563-15339-22-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-22-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   71 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index e298a16..069af70 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2489,4 +2489,75 @@ 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' '
+	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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 22/47] t1510: setup case #19
Message-ID: <1290785563-15339-23-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-23-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  266 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 266 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 069af70..954e7fe 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2560,4 +2560,270 @@ 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' '
+	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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 23/47] t1510: setup case #20
Message-ID: <1290785563-15339-24-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-24-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |  128 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 954e7fe..db52f36 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2826,4 +2826,132 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 24/47] t1510: setup case #21
Message-ID: <1290785563-15339-25-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-25-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  130 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index db52f36..47d6c4b 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2954,4 +2954,134 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 25/47] t1510: setup case #22
Message-ID: <1290785563-15339-26-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-26-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  337 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 337 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 47d6c4b..0027274 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3084,4 +3084,341 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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
+	)
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 26/47] t1510: setup case #23
Message-ID: <1290785563-15339-27-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-27-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  267 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 267 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 0027274..07af3cc 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3421,4 +3421,271 @@ test_expect_failure '#22.2: at root' '
 	)
 '
 
+#
+# 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' '
+	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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 27/47] t1510: setup case #24
Message-ID: <1290785563-15339-28-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-28-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 07af3cc..1c89366 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3688,4 +3688,52 @@ 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' '
+	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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 28/47] t1510: setup case #25
Message-ID: <1290785563-15339-29-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-29-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 1c89366..fa1ffac 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3736,4 +3736,54 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 29/47] t1510: setup case #26
Message-ID: <1290785563-15339-30-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-30-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   68 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index fa1ffac..0ad5e81 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3786,4 +3786,72 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 30/47] t1510: setup case #27
Message-ID: <1290785563-15339-31-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-31-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  268 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 0ad5e81..5c831d1 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -3854,4 +3854,272 @@ 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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"
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 31/47] t1510: setup case #28
Message-ID: <1290785563-15339-32-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-32-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1510-repo-setup.sh |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 5c831d1..d845758 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -4122,4 +4122,53 @@ 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' '
+	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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 32/47] t1510: setup case #29
Message-ID: <1290785563-15339-33-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-33-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index d845758..2d1982f 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -4171,4 +4171,54 @@ 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' '
+	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_failure '#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_failure '#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
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 33/47] t1510: setup case #30
Message-ID: <1290785563-15339-34-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-34-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 2d1982f..96f7485 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -4221,4 +4221,43 @@ 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' '
+	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_failure '#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
+	)
+'
+
 test_done
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 34/47] t1510: setup case #31
Message-ID: <1290785563-15339-35-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-35-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1510-repo-setup.sh |  269 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 269 insertions(+), 0 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 96f7485..d8c181d 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -4260,4 +4260,273 @@ test_expect_failure '#30: at root' '
 	)
 '
 
+#
+# 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' '
+	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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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_failure '#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
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 35/47] git-rev-parse.txt: clarify --git-dir
Message-ID: <1290785563-15339-36-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-36-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
From: Jonathan Nieder <jrnieder@gmail.com>

The current behavior is often to print an absolute path rather than
a ../../etc string, but callers must be ready to accept a relative
path, too. The most common output is ".git" (from the toplevel of
an ordinary work tree).

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-rev-parse.txt |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 4a27643..ff23cb0 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -136,7 +136,12 @@ appending `/{asterisk}`.
 	directory (typically a sequence of "../", or an empty string).
 
 --git-dir::
-	Show `$GIT_DIR` if defined else show the path to the .git directory.
+	Show `$GIT_DIR` if defined. Otherwise show the path to
+	the .git directory, relative to the current directory.
++
+If `$GIT_DIR` is not defined and the current directory
+is not detected to lie in a git repository or work tree
+print a message to stderr and exit with nonzero status.
 
 --is-inside-git-dir::
 	When the current working directory is below the repository
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 36/47] rev-parse: prints --git-dir relative to user's cwd
Message-ID: <1290785563-15339-37-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-37-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
git_dir variable in environment.c is relative to git's cwd, not user's
cwd. Convert the relative path (actualy by making it absolute path)
before printing out.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/rev-parse.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index a5a1c86..65c287b 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -647,7 +647,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				static char cwd[PATH_MAX];
 				int len;
 				if (gitdir) {
-					puts(gitdir);
+					if (is_absolute_path(gitdir) || !prefix) {
+						puts(gitdir);
+						continue;
+					}
+					puts(make_absolute_path(gitdir));
 					continue;
 				}
 				if (!prefix) {
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 37/47] Add git_config_early()
Message-ID: <1290785563-15339-38-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-38-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
This version of git_config() will be used during repository setup.
As a repository is being set up, $GIT_DIR is not nailed down yet,
git_pathdup() should not be used to get $GIT_DIR/config.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache.h  |    1 +
 config.c |   19 ++++++++++++++-----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/cache.h b/cache.h
index d1bee5d..123dd4b 100644
--- a/cache.h
+++ b/cache.h
@@ -986,6 +986,7 @@ extern int git_config_parse_parameter(const char *text);
 extern int git_config_parse_environment(void);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
 extern int git_config(config_fn_t fn, void *);
+extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
 extern int git_parse_ulong(const char *, unsigned long *);
 extern int git_config_int(const char *, const char *);
 extern unsigned long git_config_ulong(const char *, const char *);
diff --git a/config.c b/config.c
index 4b0a820..c431f41 100644
--- a/config.c
+++ b/config.c
@@ -835,10 +835,9 @@ int git_config_from_parameters(config_fn_t fn, void *data)
 	return 0;
 }
 
-int git_config(config_fn_t fn, void *data)
+int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 {
 	int ret = 0, found = 0;
-	char *repo_config = NULL;
 	const char *home = NULL;
 
 	/* Setting $GIT_CONFIG makes git read _only_ the given config file. */
@@ -860,12 +859,10 @@ int git_config(config_fn_t fn, void *data)
 		free(user_config);
 	}
 
-	repo_config = git_pathdup("config");
-	if (!access(repo_config, R_OK)) {
+	if (repo_config && !access(repo_config, R_OK)) {
 		ret += git_config_from_file(fn, repo_config, data);
 		found += 1;
 	}
-	free(repo_config);
 
 	ret += git_config_from_parameters(fn, data);
 	if (config_parameters)
@@ -876,6 +873,18 @@ int git_config(config_fn_t fn, void *data)
 	return ret;
 }
 
+int git_config(config_fn_t fn, void *data)
+{
+	char *repo_config = NULL;
+	int ret;
+
+	repo_config = git_pathdup("config");
+	ret = git_config_early(fn, data, repo_config);
+	if (repo_config)
+		free(repo_config);
+	return ret;
+}
+
 /*
  * Find all the stuff for git_config_set() below.
  */
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 38/47] Use git_config_early() instead of git_config() during repo setup
Message-ID: <1290785563-15339-39-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-39-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
When git_config() is called, either git_dir has already been set (by
$GIT_DIR env or set_git_dir()), or it will default git_dir to ".git".

git_config_early() gives setup functions more freedom because it does
not require git_dir. Give it a config path, it will happily examine
it.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c |   47 +++++++++++++++++++++++++++++++++++------------
 1 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/setup.c b/setup.c
index a3b76de..49a1a25 100644
--- a/setup.c
+++ b/setup.c
@@ -243,9 +243,21 @@ void setup_work_tree(void)
 	initialized = 1;
 }
 
-static int check_repository_format_gently(int *nongit_ok)
+static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
 {
-	git_config(check_repository_format_version, NULL);
+	char repo_config[PATH_MAX+1];
+
+	/*
+	 * git_config() can't be used here because it calls git_pathdup()
+	 * to get $GIT_CONFIG/config. That call will make setup_git_env()
+	 * set git_dir to ".git".
+	 *
+	 * We are in gitdir setup, no git dir has been found useable yet.
+	 * Use a gentler version of git_config() to check if this repo
+	 * is a good one.
+	 */
+	snprintf(repo_config, PATH_MAX, "%s/config", gitdir);
+	git_config_early(check_repository_format_version, NULL, repo_config);
 	if (GIT_REPO_VERSION < repository_format_version) {
 		if (!nongit_ok)
 			die ("Expected git repo version <= %d, found %d",
@@ -331,11 +343,11 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	if (!work_tree_env) {
 		retval = set_work_tree(gitdirenv);
 		/* config may override worktree */
-		if (check_repository_format_gently(nongit_ok))
+		if (check_repository_format_gently(gitdirenv, nongit_ok))
 			return NULL;
 		return retval;
 	}
-	if (check_repository_format_gently(nongit_ok))
+	if (check_repository_format_gently(gitdirenv, nongit_ok))
 		return NULL;
 	retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
 			get_git_work_tree());
@@ -357,11 +369,17 @@ static int cwd_contains_git_dir(const char **gitfile_dirp)
 			die("Repository setup failed");
 		return 1;
 	}
-	return is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT);
+	if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT)) {
+		*gitfile_dirp = DEFAULT_GIT_DIR_ENVIRONMENT;
+		return 1;
+	}
+	return 0;
 }
 
 static const char *setup_discovered_git_dir(const char *work_tree_env,
-		int offset, int len, char *cwd, int *nongit_ok)
+					    const char *gitdir,
+					    int offset, int len,
+					    char *cwd, int *nongit_ok)
 {
 	int root_len;
 
@@ -370,7 +388,7 @@ static const char *setup_discovered_git_dir(const char *work_tree_env,
 		inside_work_tree = 1;
 	root_len = offset_1st_component(cwd);
 	git_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len);
-	if (check_repository_format_gently(nongit_ok))
+	if (check_repository_format_gently(gitdir, nongit_ok))
 		return NULL;
 	if (offset == len)
 		return NULL;
@@ -396,9 +414,12 @@ static const char *setup_bare_git_dir(const char *work_tree_env,
 		root_len = offset_1st_component(cwd);
 		cwd[offset > root_len ? offset : root_len] = '\0';
 		set_git_dir(cwd);
-	} else
+		check_repository_format_gently(cwd, nongit_ok);
+	}
+	else {
 		set_git_dir(".");
-	check_repository_format_gently(nongit_ok);
+		check_repository_format_gently(".", nongit_ok);
+	}
 	return NULL;
 }
 
@@ -478,8 +499,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 		current_device = get_device_or_die(".", NULL);
 	for (;;) {
 		if (cwd_contains_git_dir(&gitfile_dir))
-			return setup_discovered_git_dir(work_tree_env, offset,
-							len, cwd, nongit_ok);
+			return setup_discovered_git_dir(work_tree_env,
+							gitfile_dir,
+							offset, len,
+							cwd, nongit_ok);
 		if (is_git_directory("."))
 			return setup_bare_git_dir(work_tree_env, offset,
 							len, cwd, nongit_ok);
@@ -590,7 +613,7 @@ int check_repository_format_version(const char *var, const char *value, void *cb
 
 int check_repository_format(void)
 {
-	return check_repository_format_gently(NULL);
+	return check_repository_format_gently(get_git_dir(), NULL);
 }
 
 /*
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 39/47] setup: limit get_git_work_tree()'s to explicit setup case only
Message-ID: <1290785563-15339-40-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-40-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
get_git_work_tree() takes input as core.worktree, core.bare,
GIT_WORK_TREE and decides correct worktree setting.

Unfortunately it does not do its job well. core.worktree and
GIT_WORK_TREE should only be taken into account, if GIT_DIR is set
(which is handled by setup_explicit_git_dir). For other setup cases,
only core.bare matters.

Add a temporary variable setup_explicit to adjust get_git_work_tree()
behavior as such. This variable will be gone once setup_* rework is
done.

Also remove is_bare_repository_cfg check in set_git_work_tree() to
ease the rework. We are going to check for core.bare and core.worktree
early before setting worktree. For example, if core.bare is true, no
need to set worktree.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/init-db.c     |    1 +
 cache.h               |    1 +
 environment.c         |   10 ++++++-
 setup.c               |   10 ++++++-
 t/t1510-repo-setup.sh |   66 ++++++++++++++++++++++++------------------------
 5 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index 9d4886c..ea06478 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -496,6 +496,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	if (is_bare_repository_cfg < 0)
 		is_bare_repository_cfg = guess_repository_type(git_dir);
 
+	startup_info->setup_explicit = 1;
 	if (!is_bare_repository_cfg) {
 		if (git_dir) {
 			const char *git_dir_parent = strrchr(git_dir, '/');
diff --git a/cache.h b/cache.h
index 123dd4b..b2cdda7 100644
--- a/cache.h
+++ b/cache.h
@@ -1119,6 +1119,7 @@ const char *split_cmdline_strerror(int cmdline_errno);
 /* git.c */
 struct startup_info {
 	int have_repository;
+	int setup_explicit;
 };
 extern struct startup_info *startup_info;
 
diff --git a/environment.c b/environment.c
index de5581f..d811049 100644
--- a/environment.c
+++ b/environment.c
@@ -137,8 +137,6 @@ static int git_work_tree_initialized;
  */
 void set_git_work_tree(const char *new_work_tree)
 {
-	if (is_bare_repository_cfg >= 0)
-		die("cannot set work tree after initialization");
 	git_work_tree_initialized = 1;
 	free(work_tree);
 	work_tree = xstrdup(make_absolute_path(new_work_tree));
@@ -147,6 +145,14 @@ void set_git_work_tree(const char *new_work_tree)
 
 const char *get_git_work_tree(void)
 {
+	if (startup_info && !startup_info->setup_explicit) {
+		if (is_bare_repository_cfg == 1)
+			return NULL;
+		if (work_tree)
+			is_bare_repository_cfg = 0;
+		return work_tree;
+	}
+
 	if (!git_work_tree_initialized) {
 		work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
 		/* core.bare = true overrides implicit and config work tree */
diff --git a/setup.c b/setup.c
index 49a1a25..c7d7198 100644
--- a/setup.c
+++ b/setup.c
@@ -331,6 +331,8 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	static char buffer[1024 + 1];
 	const char *retval;
 
+	if (startup_info)
+		startup_info->setup_explicit = 1;
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
 	if (!is_git_directory(gitdirenv)) {
@@ -382,12 +384,15 @@ static const char *setup_discovered_git_dir(const char *work_tree_env,
 					    char *cwd, int *nongit_ok)
 {
 	int root_len;
+	char *work_tree;
 
 	inside_git_dir = 0;
 	if (!work_tree_env)
 		inside_work_tree = 1;
 	root_len = offset_1st_component(cwd);
-	git_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len);
+	work_tree = xstrndup(cwd, offset > root_len ? offset : root_len);
+	set_git_work_tree(work_tree);
+	free(work_tree);
 	if (check_repository_format_gently(gitdir, nongit_ok))
 		return NULL;
 	if (offset == len)
@@ -627,7 +632,8 @@ const char *setup_git_directory(void)
 	const char *retval = setup_git_directory_gently(NULL);
 
 	/* If the work tree is not the default one, recompute prefix */
-	if (inside_work_tree < 0) {
+	if ((!startup_info || startup_info->setup_explicit) &&
+	    inside_work_tree < 0) {
 		static char buffer[PATH_MAX + 1];
 		char *rel;
 		if (retval && chdir(retval))
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index d8c181d..45feb80 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -132,7 +132,7 @@ test_expect_success '#1: setup' '
 	cd ..
 '
 
-test_expect_failure '#1: at root' '
+test_expect_success '#1: at root' '
 	cat >1/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/1
@@ -142,7 +142,7 @@ EOF
 	test_repo 1
 '
 
-test_expect_failure '#1: in subdir' '
+test_expect_success '#1: in subdir' '
 	cat >1/sub/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/1
@@ -512,7 +512,7 @@ test_expect_success '#4: setup' '
 	cd ..
 '
 
-test_expect_failure '#4: at root' '
+test_expect_success '#4: at root' '
 	cat >4/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/4
@@ -522,7 +522,7 @@ EOF
 	test_repo 4
 '
 
-test_expect_failure '#4: in subdir' '
+test_expect_success '#4: in subdir' '
 	cat >4/sub/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/4
@@ -560,7 +560,7 @@ test_expect_success '#5: setup' '
 	cd ..
 '
 
-test_expect_failure '#5: at root' '
+test_expect_success '#5: at root' '
 	cat >5/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/5
@@ -570,7 +570,7 @@ EOF
 	test_repo 5
 '
 
-test_expect_failure '#5: in subdir' '
+test_expect_success '#5: in subdir' '
 	cat >5/sub/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: $TRASH_DIRECTORY/5
@@ -1213,7 +1213,7 @@ test_expect_success '#9: setup' '
 	cd ..
 '
 
-test_expect_failure '#9: at root' '
+test_expect_success '#9: at root' '
 	cat >9/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/9.git
 setup: worktree: $TRASH_DIRECTORY/9
@@ -1223,7 +1223,7 @@ EOF
 	test_repo 9
 '
 
-test_expect_failure '#9: in subdir' '
+test_expect_success '#9: in subdir' '
 	cat >9/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/9.git
 setup: worktree: $TRASH_DIRECTORY/9
@@ -1596,7 +1596,7 @@ test_expect_success '#12: setup' '
 	cd ..
 '
 
-test_expect_failure '#12: at root' '
+test_expect_success '#12: at root' '
 	cat >12/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/12.git
 setup: worktree: $TRASH_DIRECTORY/12
@@ -1606,7 +1606,7 @@ EOF
 	test_repo 12
 '
 
-test_expect_failure '#12: in subdir' '
+test_expect_success '#12: in subdir' '
 	cat >12/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/12.git
 setup: worktree: $TRASH_DIRECTORY/12
@@ -1646,7 +1646,7 @@ test_expect_success '#13: setup' '
 	cd ..
 '
 
-test_expect_failure '#13: at root' '
+test_expect_success '#13: at root' '
 	cat >13/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/13.git
 setup: worktree: $TRASH_DIRECTORY/13
@@ -1656,7 +1656,7 @@ EOF
 	test_repo 13
 '
 
-test_expect_failure '#13: in subdir' '
+test_expect_success '#13: in subdir' '
 	cat >13/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/13.git
 setup: worktree: $TRASH_DIRECTORY/13
@@ -2388,7 +2388,7 @@ test_expect_success '#17.1: setup' '
 	cd ..
 '
 
-test_expect_failure '#17.1: at .git' '
+test_expect_success '#17.1: at .git' '
 	cat >17/.git/expected <<EOF &&
 setup: git_dir: .
 setup: worktree: (null)
@@ -2398,7 +2398,7 @@ EOF
 	test_repo 17/.git
 '
 
-test_expect_failure '#17.1: in .git/wt' '
+test_expect_success '#17.1: in .git/wt' '
 	cat >17/.git/wt/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/17/.git
 setup: worktree: (null)
@@ -2408,7 +2408,7 @@ EOF
 	test_repo 17/.git/wt
 '
 
-test_expect_failure '#17.1: in .git/wt/sub' '
+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)
@@ -2439,7 +2439,7 @@ test_expect_success '#17.2: setup' '
 	git config --file="$TRASH_DIRECTORY/17/.git/config" core.bare true
 '
 
-test_expect_failure '#17.2: at .git' '
+test_expect_success '#17.2: at .git' '
 	cat >17/.git/expected <<EOF &&
 setup: git_dir: .
 setup: worktree: (null)
@@ -2449,7 +2449,7 @@ EOF
 	test_repo 17/.git
 '
 
-test_expect_failure '#17.2: in .git/wt' '
+test_expect_success '#17.2: in .git/wt' '
 	cat >17/.git/wt/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/17/.git
 setup: worktree: (null)
@@ -2459,7 +2459,7 @@ EOF
 	test_repo 17/.git/wt
 '
 
-test_expect_failure '#17.2: in .git/wt/sub' '
+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)
@@ -2469,7 +2469,7 @@ EOF
 	test_repo 17/.git/wt/sub
 '
 
-test_expect_failure '#17.2: at root' '
+test_expect_success '#17.2: at root' '
 	cat >17/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: (null)
@@ -2853,7 +2853,7 @@ test_expect_success '#20.1: setup' '
 	cd ..
 '
 
-test_expect_failure '#20.1: at .git' '
+test_expect_success '#20.1: at .git' '
 	cat >20/.git/expected <<EOF &&
 setup: git_dir: .
 setup: worktree: (null)
@@ -2863,7 +2863,7 @@ EOF
 	test_repo 20/.git
 '
 
-test_expect_failure '#20.1: in .git/wt' '
+test_expect_success '#20.1: in .git/wt' '
 	cat >20/.git/wt/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/20/.git
 setup: worktree: (null)
@@ -2873,7 +2873,7 @@ EOF
 	test_repo 20/.git/wt
 '
 
-test_expect_failure '#20.1: in .git/wt/sub' '
+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)
@@ -2983,7 +2983,7 @@ test_expect_success '#21.1: setup' '
 	cd ..
 '
 
-test_expect_failure '#21.1: at .git' '
+test_expect_success '#21.1: at .git' '
 	cat >21/.git/expected <<EOF &&
 setup: git_dir: .
 setup: worktree: (null)
@@ -2993,7 +2993,7 @@ EOF
 	test_repo 21/.git
 '
 
-test_expect_failure '#21.1: in .git/wt' '
+test_expect_success '#21.1: in .git/wt' '
 	cat >21/.git/wt/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/21/.git
 setup: worktree: (null)
@@ -3003,7 +3003,7 @@ EOF
 	test_repo 21/.git/wt
 '
 
-test_expect_failure '#21.1: in .git/wt/sub' '
+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)
@@ -3034,7 +3034,7 @@ test_expect_success '#21.2: setup' '
 	git config --file="$TRASH_DIRECTORY/21/.git/config" core.bare true
 '
 
-test_expect_failure '#21.2: at .git' '
+test_expect_success '#21.2: at .git' '
 	cat >21/.git/expected <<EOF &&
 setup: git_dir: .
 setup: worktree: (null)
@@ -3044,7 +3044,7 @@ EOF
 	test_repo 21/.git
 '
 
-test_expect_failure '#21.2: in .git/wt' '
+test_expect_success '#21.2: in .git/wt' '
 	cat >21/.git/wt/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/21/.git
 setup: worktree: (null)
@@ -3054,7 +3054,7 @@ EOF
 	test_repo 21/.git/wt
 '
 
-test_expect_failure '#21.2: in .git/wt/sub' '
+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)
@@ -3064,7 +3064,7 @@ EOF
 	test_repo 21/.git/wt/sub
 '
 
-test_expect_failure '#21.2: at root' '
+test_expect_success '#21.2: at root' '
 	cat >21/expected <<EOF &&
 setup: git_dir: .git
 setup: worktree: (null)
@@ -3716,7 +3716,7 @@ test_expect_success '#24: setup' '
 	cd ..
 '
 
-test_expect_success '#24: at root' '
+test_expect_failure '#24: at root' '
 	cat >24/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/24.git
 setup: worktree: (null)
@@ -3726,7 +3726,7 @@ EOF
 	test_repo 24
 '
 
-test_expect_success '#24: in subdir' '
+test_expect_failure '#24: in subdir' '
 	cat >24/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/24.git
 setup: worktree: (null)
@@ -4151,7 +4151,7 @@ test_expect_success '#28: setup' '
 	cd ..
 '
 
-test_expect_success '#28: at root' '
+test_expect_failure '#28: at root' '
 	cat >28/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/28.git
 setup: worktree: (null)
@@ -4161,7 +4161,7 @@ EOF
 	test_repo 28
 '
 
-test_expect_success '#28: in subdir' '
+test_expect_failure '#28: in subdir' '
 	cat >28/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/28.git
 setup: worktree: (null)
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 40/47] setup: clean up setup_bare_git_dir()
Message-ID: <1290785563-15339-41-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-41-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
work_tree_env argument is removed because this function does not need
it. GIT_WORK_TREE is only effective inside setup_explicit_git_dir.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c |   19 +++++++++----------
 1 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/setup.c b/setup.c
index c7d7198..a6cc044 100644
--- a/setup.c
+++ b/setup.c
@@ -405,26 +405,25 @@ static const char *setup_discovered_git_dir(const char *work_tree_env,
 	return cwd + offset;
 }
 
-static const char *setup_bare_git_dir(const char *work_tree_env,
-		int offset, int len, char *cwd, int *nongit_ok)
+/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
+static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongit_ok)
 {
 	int root_len;
 
+	if (check_repository_format_gently(".", nongit_ok))
+		return NULL;
+
 	inside_git_dir = 1;
-	if (!work_tree_env)
-		inside_work_tree = 0;
+	inside_work_tree = 0;
 	if (offset != len) {
 		if (chdir(cwd))
 			die_errno("Cannot come back to cwd");
 		root_len = offset_1st_component(cwd);
 		cwd[offset > root_len ? offset : root_len] = '\0';
 		set_git_dir(cwd);
-		check_repository_format_gently(cwd, nongit_ok);
 	}
-	else {
+	else
 		set_git_dir(".");
-		check_repository_format_gently(".", nongit_ok);
-	}
 	return NULL;
 }
 
@@ -509,8 +508,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 							offset, len,
 							cwd, nongit_ok);
 		if (is_git_directory("."))
-			return setup_bare_git_dir(work_tree_env, offset,
-							len, cwd, nongit_ok);
+			return setup_bare_git_dir(cwd, offset, len, nongit_ok);
+
 		while (--offset > ceil_offset && cwd[offset] != '/');
 		if (offset <= ceil_offset)
 			return setup_nongit(cwd, nongit_ok);
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 41/47] t1020-subdirectory: test alias expansion in a subdirectory
Message-ID: <1290785563-15339-42-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-42-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
From: Michael J Gruber <git@drmicha.warpmail.net>

Add a test for alias expansion in a subdirectory of the worktree.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t1020-subdirectory.sh |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index a3ac338..1fd187c 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 &&
 	(
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 42/47] setup: clean up setup_discovered_git_dir()
Message-ID: <1290785563-15339-43-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-43-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
If core.bare is true, discard the discovered worktree, move back to
original cwd.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c               |   72 ++++++++++++++++++++++++------------------------
 t/t1510-repo-setup.sh |   24 ++++++++--------
 2 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/setup.c b/setup.c
index a6cc044..3ee9c2e 100644
--- a/setup.c
+++ b/setup.c
@@ -362,39 +362,27 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	return retval;
 }
 
-static int cwd_contains_git_dir(const char **gitfile_dirp)
+static const char *setup_discovered_git_dir(const char *gitdir,
+					    char *cwd, int offset, int len,
+					    int *nongit_ok)
 {
-	const char *gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
-	*gitfile_dirp = gitfile_dir;
-	if (gitfile_dir) {
-		if (set_git_dir(gitfile_dir))
-			die("Repository setup failed");
-		return 1;
-	}
-	if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT)) {
-		*gitfile_dirp = DEFAULT_GIT_DIR_ENVIRONMENT;
-		return 1;
-	}
-	return 0;
-}
+	if (check_repository_format_gently(gitdir, nongit_ok))
+		return NULL;
 
-static const char *setup_discovered_git_dir(const char *work_tree_env,
-					    const char *gitdir,
-					    int offset, int len,
-					    char *cwd, int *nongit_ok)
-{
-	int root_len;
-	char *work_tree;
+	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
+	if (is_bare_repository_cfg > 0) {
+		set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir));
+		if (chdir(cwd))
+			die_errno("Could not come back to cwd");
+		return NULL;
+	}
 
+	/* #0, #1, #5, #8, #9, #12, #13 */
+	set_git_work_tree(".");
+	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
+		set_git_dir(gitdir);
 	inside_git_dir = 0;
-	if (!work_tree_env)
-		inside_work_tree = 1;
-	root_len = offset_1st_component(cwd);
-	work_tree = xstrndup(cwd, offset > root_len ? offset : root_len);
-	set_git_work_tree(work_tree);
-	free(work_tree);
-	if (check_repository_format_gently(gitdir, nongit_ok))
-		return NULL;
+	inside_work_tree = 1;
 	if (offset == len)
 		return NULL;
 
@@ -456,8 +444,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
 	static char cwd[PATH_MAX+1];
-	const char *gitdirenv;
-	const char *gitfile_dir;
+	const char *gitdirenv, *ret;
+	char *gitfile;
 	int len, offset, ceil_offset;
 	dev_t current_device = 0;
 	int one_filesystem = 1;
@@ -502,11 +490,23 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL);
 	for (;;) {
-		if (cwd_contains_git_dir(&gitfile_dir))
-			return setup_discovered_git_dir(work_tree_env,
-							gitfile_dir,
-							offset, len,
-							cwd, nongit_ok);
+		gitfile = (char*)read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		if (gitfile)
+			gitdirenv = gitfile = xstrdup(gitfile);
+		else {
+			if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
+				gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
+		}
+
+		if (gitdirenv) {
+			ret = setup_discovered_git_dir(gitdirenv,
+						       cwd, offset, len,
+						       nongit_ok);
+			free(gitfile);
+			return ret;
+		}
+		free(gitfile);
+
 		if (is_git_directory("."))
 			return setup_bare_git_dir(cwd, offset, len, nongit_ok);
 
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 45feb80..5ae02ee 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -2350,7 +2350,7 @@ EOF
 	test_repo 16
 '
 
-test_expect_failure '#16.2: in subdir' '
+test_expect_success '#16.2: in subdir' '
 	cat >16/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/16/.git
 setup: worktree: (null)
@@ -2479,7 +2479,7 @@ EOF
 	test_repo 17
 '
 
-test_expect_failure '#17.2: in subdir' '
+test_expect_success '#17.2: in subdir' '
 	cat >17/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/17/.git
 setup: worktree: (null)
@@ -2944,7 +2944,7 @@ EOF
 	test_repo 20
 '
 
-test_expect_failure '#20.2: in subdir' '
+test_expect_success '#20.2: in subdir' '
 	cat >20/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/20/.git
 setup: worktree: (null)
@@ -3074,7 +3074,7 @@ EOF
 	test_repo 21
 '
 
-test_expect_failure '#21.2: in subdir' '
+test_expect_success '#21.2: in subdir' '
 	cat >21/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/21/.git
 setup: worktree: (null)
@@ -3716,7 +3716,7 @@ test_expect_success '#24: setup' '
 	cd ..
 '
 
-test_expect_failure '#24: at root' '
+test_expect_success '#24: at root' '
 	cat >24/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/24.git
 setup: worktree: (null)
@@ -3726,7 +3726,7 @@ EOF
 	test_repo 24
 '
 
-test_expect_failure '#24: in subdir' '
+test_expect_success '#24: in subdir' '
 	cat >24/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/24.git
 setup: worktree: (null)
@@ -3766,7 +3766,7 @@ test_expect_success '#25: setup' '
 	cd ..
 '
 
-test_expect_failure '#25: at root' '
+test_expect_success '#25: at root' '
 	cat >25/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/25.git
 setup: worktree: (null)
@@ -3776,7 +3776,7 @@ EOF
 	test_repo 25
 '
 
-test_expect_failure '#25: in subdir' '
+test_expect_success '#25: in subdir' '
 	cat >25/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/25.git
 setup: worktree: (null)
@@ -4151,7 +4151,7 @@ test_expect_success '#28: setup' '
 	cd ..
 '
 
-test_expect_failure '#28: at root' '
+test_expect_success '#28: at root' '
 	cat >28/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/28.git
 setup: worktree: (null)
@@ -4161,7 +4161,7 @@ EOF
 	test_repo 28
 '
 
-test_expect_failure '#28: in subdir' '
+test_expect_success '#28: in subdir' '
 	cat >28/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/28.git
 setup: worktree: (null)
@@ -4201,7 +4201,7 @@ test_expect_success '#29: setup' '
 	cd ..
 '
 
-test_expect_failure '#29: at root' '
+test_expect_success '#29: at root' '
 	cat >29/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/29.git
 setup: worktree: (null)
@@ -4211,7 +4211,7 @@ EOF
 	test_repo 29
 '
 
-test_expect_failure '#29: in subdir' '
+test_expect_success '#29: in subdir' '
 	cat >29/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/29.git
 setup: worktree: (null)
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 43/47] setup: rework setup_explicit_git_dir()
Message-ID: <1290785563-15339-44-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-44-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
This function is the most complex one among the three setup_*
functions because all GIT_DIR, GIT_WORK_TREE, core.worktree and
core.bare are involved.

Because core.worktree is only effective inside
setup_explicit_git_dir() and the extra code in setup_git_directory()
is to handle that. The extra code can now be retired.

Also note that setup_explicit assignment is removed, worktree setting
is no longer decided by get_git_work_tree(). get_git_work_tree() will
be simplified in the next commit.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c               |  138 +++++++++++++----------
 t/t1510-repo-setup.sh |  286 ++++++++++++++++++++++++------------------------
 2 files changed, 221 insertions(+), 203 deletions(-)

diff --git a/setup.c b/setup.c
index 3ee9c2e..2e2865c 100644
--- a/setup.c
+++ b/setup.c
@@ -208,24 +208,6 @@ int is_inside_work_tree(void)
 	return inside_work_tree;
 }
 
-/*
- * set_work_tree() is only ever called if you set GIT_DIR explicitly.
- * The old behaviour (which we retain here) is to set the work tree root
- * to the cwd, unless overridden by the config, the command line, or
- * GIT_WORK_TREE.
- */
-static const char *set_work_tree(const char *dir)
-{
-	char buffer[PATH_MAX + 1];
-
-	if (!getcwd(buffer, sizeof(buffer)))
-		die ("Could not get the current working directory");
-	git_work_tree_cfg = xstrdup(buffer);
-	inside_work_tree = 1;
-
-	return NULL;
-}
-
 void setup_work_tree(void)
 {
 	const char *work_tree, *git_dir;
@@ -326,40 +308,92 @@ const char *read_gitfile_gently(const char *path)
 }
 
 static const char *setup_explicit_git_dir(const char *gitdirenv,
-				const char *work_tree_env, int *nongit_ok)
+					  char *cwd, int len,
+					  int *nongit_ok)
 {
-	static char buffer[1024 + 1];
-	const char *retval;
+	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
+	const char *worktree;
+	char *gitfile;
 
-	if (startup_info)
-		startup_info->setup_explicit = 1;
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
+
+	gitfile = (char*)read_gitfile_gently(gitdirenv);
+	if (gitfile) {
+		gitfile = xstrdup(gitfile);
+		gitdirenv = gitfile;
+	}
+
 	if (!is_git_directory(gitdirenv)) {
 		if (nongit_ok) {
 			*nongit_ok = 1;
+			free(gitfile);
 			return NULL;
 		}
 		die("Not a git repository: '%s'", gitdirenv);
 	}
-	if (!work_tree_env) {
-		retval = set_work_tree(gitdirenv);
-		/* config may override worktree */
-		if (check_repository_format_gently(gitdirenv, nongit_ok))
-			return NULL;
-		return retval;
+
+	if (check_repository_format_gently(gitdirenv, nongit_ok)) {
+		free(gitfile);
+		return NULL;
 	}
-	if (check_repository_format_gently(gitdirenv, nongit_ok))
+
+	/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
+	if (work_tree_env)
+		set_git_work_tree(work_tree_env);
+	else if (is_bare_repository_cfg > 0) {
+		if (git_work_tree_cfg) /* #22.2, #30 */
+			die("core.bare and core.worktree do not make sense");
+
+		/* #18, #26 */
+		set_git_dir(gitdirenv);
+		free(gitfile);
 		return NULL;
-	retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
-			get_git_work_tree());
-	if (!retval || !*retval)
+	}
+	else if (git_work_tree_cfg) { /* #6, #14 */
+		if (is_absolute_path(git_work_tree_cfg))
+			set_git_work_tree(git_work_tree_cfg);
+		else {
+			char core_worktree[PATH_MAX];
+			if (chdir(gitdirenv))
+				die_errno("Could not chdir to '%s'", gitdirenv);
+			if (chdir(git_work_tree_cfg))
+				die_errno("Could not chdir to '%s'", git_work_tree_cfg);
+			if (!getcwd(core_worktree, PATH_MAX))
+				die_errno("Could not get directory '%s'", git_work_tree_cfg);
+			if (chdir(cwd))
+				die_errno("Could not come back to cwd");
+			set_git_work_tree(core_worktree);
+		}
+	}
+	else /* #2, #10 */
+		set_git_work_tree(".");
+
+	/* set_git_work_tree() must have been called by now */
+	worktree = get_git_work_tree();
+
+	/* both get_git_work_tree() and cwd are already normalized */
+	if (!strcmp(cwd, worktree)) { /* cwd == worktree */
+		set_git_dir(gitdirenv);
+		free(gitfile);
 		return NULL;
-	set_git_dir(make_absolute_path(gitdirenv));
-	if (chdir(work_tree_env) < 0)
-		die_errno ("Could not chdir to '%s'", work_tree_env);
-	strcat(buffer, "/");
-	return retval;
+	}
+
+	if (!prefixcmp(cwd, worktree) &&
+	    cwd[strlen(worktree)] == '/') { /* cwd inside worktree */
+		set_git_dir(make_absolute_path(gitdirenv));
+		if (chdir(worktree))
+			die_errno("Could not chdir to '%s'", worktree);
+		cwd[len++] = '/';
+		cwd[len] = '\0';
+		free(gitfile);
+		return cwd + strlen(worktree) + 1;
+	}
+
+	/* cwd outside worktree */
+	set_git_dir(gitdirenv);
+	free(gitfile);
+	return NULL;
 }
 
 static const char *setup_discovered_git_dir(const char *gitdir,
@@ -441,7 +475,6 @@ static dev_t get_device_or_die(const char *path, const char *prefix)
  */
 static const char *setup_git_directory_gently_1(int *nongit_ok)
 {
-	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
 	static char cwd[PATH_MAX+1];
 	const char *gitdirenv, *ret;
@@ -458,6 +491,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	if (nongit_ok)
 		*nongit_ok = 0;
 
+	if (!getcwd(cwd, sizeof(cwd)-1))
+		die_errno("Unable to read current working directory");
+	offset = len = strlen(cwd);
+
 	/*
 	 * If GIT_DIR is set explicitly, we're not going
 	 * to do any discovery, but we still do repository
@@ -465,10 +502,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
 	if (gitdirenv)
-		return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok);
-
-	if (!getcwd(cwd, sizeof(cwd)-1))
-		die_errno("Unable to read current working directory");
+		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -485,7 +519,6 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 * - ../../.git/
 	 *   etc.
 	 */
-	offset = len = strlen(cwd);
 	one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL);
@@ -628,20 +661,5 @@ int check_repository_format(void)
  */
 const char *setup_git_directory(void)
 {
-	const char *retval = setup_git_directory_gently(NULL);
-
-	/* If the work tree is not the default one, recompute prefix */
-	if ((!startup_info || startup_info->setup_explicit) &&
-	    inside_work_tree < 0) {
-		static char buffer[PATH_MAX + 1];
-		char *rel;
-		if (retval && chdir(retval))
-			die_errno ("Could not jump back into original cwd");
-		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
-		if (rel && *rel && chdir(get_git_work_tree()))
-			die_errno ("Could not jump to working directory");
-		return rel && *rel ? strcat(rel, "/") : NULL;
-	}
-
-	return retval;
+	return setup_git_directory_gently(NULL);
 }
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 5ae02ee..b7e4d5d 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -651,7 +651,7 @@ EOF
 	test_repo 6 "$TRASH_DIRECTORY/6/.git"
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=.. in subdir' '
+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
@@ -662,7 +662,7 @@ EOF
 	test_repo 6/sub/sub ../../.git
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=..(rel) in subdir' '
+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
@@ -783,7 +783,7 @@ EOF
 	test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git"
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=../.. at root' '
+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
@@ -794,7 +794,7 @@ EOF
 	test_repo 6 .git
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=../..(rel) at root' '
+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
@@ -827,7 +827,7 @@ EOF
 	test_repo 6 "$TRASH_DIRECTORY/6/.git"
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=../.. in subdir' '
+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
@@ -838,7 +838,7 @@ EOF
 	test_repo 6/sub/sub ../../.git
 '
 
-test_expect_failure '#6: GIT_DIR(rel), core.worktree=../..(rel) in subdir' '
+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
@@ -1260,7 +1260,7 @@ test_expect_success '#10: setup' '
 	cd ..
 '
 
-test_expect_failure '#10: at root' '
+test_expect_success '#10: at root' '
 	cat >10/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/10.git
 setup: worktree: $TRASH_DIRECTORY/10
@@ -1270,7 +1270,7 @@ EOF
 	test_repo 10 "$TRASH_DIRECTORY/10/.git"
 '
 
-test_expect_failure '#10: in subdir' '
+test_expect_success '#10: in subdir' '
 	cat >10/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/10.git
 setup: worktree: $TRASH_DIRECTORY/10/sub
@@ -1280,7 +1280,7 @@ EOF
 	test_repo 10/sub "$TRASH_DIRECTORY/10/.git"
 '
 
-test_expect_failure '#10: relative GIT_DIR at root' '
+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
@@ -1290,7 +1290,7 @@ EOF
 	test_repo 10 .git
 '
 
-test_expect_failure '#10: relative GIT_DIR in subdir' '
+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
@@ -1327,7 +1327,7 @@ test_expect_success '#11: setup' '
 	cd ..
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+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
@@ -1337,7 +1337,7 @@ EOF
 	test_repo 11 .git "$TRASH_DIRECTORY/11"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+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
@@ -1347,7 +1347,7 @@ EOF
 	test_repo 11 .git .
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=root at root' '
+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
@@ -1357,7 +1357,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11"
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+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
@@ -1367,7 +1367,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" .
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+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
@@ -1377,7 +1377,7 @@ EOF
 	test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -1387,7 +1387,7 @@ EOF
 	test_repo 11/sub/sub ../../.git ../..
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORKTREE=root in subdir' '
+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
@@ -1397,7 +1397,7 @@ EOF
 	test_repo 11/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11"
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -1407,7 +1407,7 @@ EOF
 	test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../..
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+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
@@ -1417,7 +1417,7 @@ EOF
 	test_repo 11 .git "$TRASH_DIRECTORY/11/wt"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -1427,7 +1427,7 @@ EOF
 	test_repo 11 .git wt
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -1437,7 +1437,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" wt
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=wt at root' '
+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
@@ -1447,7 +1447,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+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
@@ -1457,7 +1457,7 @@ EOF
 	test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11/wt"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -1467,7 +1467,7 @@ EOF
 	test_repo 11/sub/sub ../../.git ../../wt
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -1477,7 +1477,7 @@ EOF
 	test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../wt
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+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
@@ -1487,7 +1487,7 @@ EOF
 	test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+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
@@ -1497,7 +1497,7 @@ EOF
 	test_repo 11 .git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+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
@@ -1507,7 +1507,7 @@ EOF
 	test_repo 11 .git ..
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+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
@@ -1517,7 +1517,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" ..
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=.. at root' '
+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
@@ -1527,7 +1527,7 @@ EOF
 	test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+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
@@ -1537,7 +1537,7 @@ EOF
 	test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -1547,7 +1547,7 @@ EOF
 	test_repo 11/sub/sub ../../.git ../../..
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -1557,7 +1557,7 @@ EOF
 	test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../../
 '
 
-test_expect_failure '#11: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+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
@@ -1693,7 +1693,7 @@ test_expect_success '#14: setup' '
 	cd ..
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14 at root' '
+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
@@ -1704,7 +1704,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14(rel) at root' '
+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
@@ -1715,7 +1715,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14 at root' '
+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
@@ -1726,7 +1726,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14(rel) at root' '
+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
@@ -1737,7 +1737,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14 in subdir' '
+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
@@ -1748,7 +1748,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14(rel) in subdir' '
+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
@@ -1759,7 +1759,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14 in subdir' '
+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
@@ -1770,7 +1770,7 @@ EOF
 	test_repo 14/sub "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14(rel) in subdir' '
+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
@@ -1781,7 +1781,7 @@ EOF
 	test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14/wt at root' '
+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
@@ -1792,7 +1792,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) at root' '
+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
@@ -1803,7 +1803,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14/wt(rel) at root' '
+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
@@ -1814,7 +1814,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14/wt at root' '
+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
@@ -1825,7 +1825,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14/wt in subdir' '
+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
@@ -1836,7 +1836,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) in subdir' '
+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
@@ -1847,7 +1847,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14/wt(rel) in subdir' '
+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
@@ -1858,7 +1858,7 @@ EOF
 	test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=../14/wt in subdir' '
+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
@@ -1869,7 +1869,7 @@ EOF
 	test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=.. at root' '
+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
@@ -1880,7 +1880,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=..(rel) at root' '
+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
@@ -1891,7 +1891,7 @@ EOF
 	test_repo 14 .git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=..(rel) at root' '
+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
@@ -1902,7 +1902,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=.. at root' '
+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
@@ -1913,7 +1913,7 @@ EOF
 	test_repo 14 "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=.. in subdir' '
+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
@@ -1924,7 +1924,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR(rel), core.worktree=..(rel) in subdir' '
+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
@@ -1935,7 +1935,7 @@ EOF
 	test_repo 14/sub/sub ../../.git
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=..(rel) in subdir' '
+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
@@ -1946,7 +1946,7 @@ EOF
 	test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git"
 '
 
-test_expect_failure '#14: GIT_DIR, core.worktree=.. in subdir' '
+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
@@ -1985,7 +1985,7 @@ test_expect_success '#15: setup' '
 	cd ..
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+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
@@ -1995,7 +1995,7 @@ EOF
 	test_repo 15 .git "$TRASH_DIRECTORY/15"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+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
@@ -2005,7 +2005,7 @@ EOF
 	test_repo 15 .git .
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=root at root' '
+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
@@ -2015,7 +2015,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15"
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+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
@@ -2025,7 +2025,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" .
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+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
@@ -2035,7 +2035,7 @@ EOF
 	test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -2045,7 +2045,7 @@ EOF
 	test_repo 15/sub/sub ../../.git ../..
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORKTREE=root in subdir' '
+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
@@ -2055,7 +2055,7 @@ EOF
 	test_repo 15/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15"
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -2065,7 +2065,7 @@ EOF
 	test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../..
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+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
@@ -2075,7 +2075,7 @@ EOF
 	test_repo 15 .git "$TRASH_DIRECTORY/15/wt"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -2085,7 +2085,7 @@ EOF
 	test_repo 15 .git wt
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -2095,7 +2095,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" wt
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=wt at root' '
+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
@@ -2105,7 +2105,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+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
@@ -2115,7 +2115,7 @@ EOF
 	test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15/wt"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -2125,7 +2125,7 @@ EOF
 	test_repo 15/sub/sub ../../.git ../../wt
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -2135,7 +2135,7 @@ EOF
 	test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../wt
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+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
@@ -2145,7 +2145,7 @@ EOF
 	test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+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
@@ -2155,7 +2155,7 @@ EOF
 	test_repo 15 .git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+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
@@ -2165,7 +2165,7 @@ EOF
 	test_repo 15 .git ..
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+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
@@ -2175,7 +2175,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" ..
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=.. at root' '
+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
@@ -2185,7 +2185,7 @@ EOF
 	test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+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
@@ -2195,7 +2195,7 @@ EOF
 	test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -2205,7 +2205,7 @@ EOF
 	test_repo 15/sub/sub ../../.git ../../..
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -2215,7 +2215,7 @@ EOF
 	test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../../
 '
 
-test_expect_failure '#15: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+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
@@ -3160,7 +3160,7 @@ EOF
 	test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=. in .git/sub' '
+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
@@ -3171,7 +3171,7 @@ EOF
 	test_repo 22/.git/sub ..
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=.(rel) in .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
@@ -3292,7 +3292,7 @@ EOF
 	test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git"
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=.. at .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
@@ -3303,7 +3303,7 @@ EOF
 	test_repo 22/.git .
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=..(rel) at .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
@@ -3336,7 +3336,7 @@ EOF
 	test_repo 22/.git "$TRASH_DIRECTORY/22/.git"
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=.. in .git/sub' '
+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
@@ -3347,7 +3347,7 @@ EOF
 	test_repo 22/.git/sub ..
 '
 
-test_expect_failure '#22.1: GIT_DIR(rel), core.worktree=..(rel) in .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
@@ -3401,7 +3401,7 @@ test_expect_success '#22.2: setup' '
 	git config --file="$TRASH_DIRECTORY/22/.git/config" core.bare true
 '
 
-test_expect_failure '#22.2: at .git' '
+test_expect_success '#22.2: at .git' '
 	(
 	cd 22/.git &&
 	GIT_DIR=. &&
@@ -3411,7 +3411,7 @@ test_expect_failure '#22.2: at .git' '
 	)
 '
 
-test_expect_failure '#22.2: at root' '
+test_expect_success '#22.2: at root' '
 	(
 	cd 22 &&
 	GIT_DIR=.git &&
@@ -3814,7 +3814,7 @@ test_expect_success '#26: setup' '
 	cd ..
 '
 
-test_expect_failure '#26: (rel) at root' '
+test_expect_success '#26: (rel) at root' '
 	cat >26/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/26.git
 setup: worktree: (null)
@@ -3824,7 +3824,7 @@ EOF
 	 test_repo 26 .git
 '
 
-test_expect_failure '#26: at root' '
+test_expect_success '#26: at root' '
 	cat >26/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/26.git
 setup: worktree: (null)
@@ -3834,7 +3834,7 @@ EOF
 	 test_repo 26 "$TRASH_DIRECTORY/26/.git"
 '
 
-test_expect_failure '#26: (rel) in subdir' '
+test_expect_success '#26: (rel) in subdir' '
 	cat >26/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/26.git
 setup: worktree: (null)
@@ -3844,7 +3844,7 @@ EOF
 	test_repo 26/sub ../.git
 '
 
-test_expect_failure '#26: in subdir' '
+test_expect_success '#26: in subdir' '
 	cat >26/sub/expected <<EOF &&
 setup: git_dir: $TRASH_DIRECTORY/26.git
 setup: worktree: (null)
@@ -3882,7 +3882,7 @@ test_expect_success '#27: setup' '
 	cd ..
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+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
@@ -3892,7 +3892,7 @@ EOF
 	test_repo 27 .git "$TRASH_DIRECTORY/27"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+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
@@ -3902,7 +3902,7 @@ EOF
 	test_repo 27 .git .
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=root at root' '
+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
@@ -3912,7 +3912,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27"
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+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
@@ -3922,7 +3922,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" .
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+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
@@ -3932,7 +3932,7 @@ EOF
 	test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -3942,7 +3942,7 @@ EOF
 	test_repo 27/sub/sub ../../.git ../..
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORKTREE=root in subdir' '
+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
@@ -3952,7 +3952,7 @@ EOF
 	test_repo 27/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27"
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -3962,7 +3962,7 @@ EOF
 	test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../..
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+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
@@ -3972,7 +3972,7 @@ EOF
 	test_repo 27 .git "$TRASH_DIRECTORY/27/wt"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -3982,7 +3982,7 @@ EOF
 	test_repo 27 .git wt
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -3992,7 +3992,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" wt
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=wt at root' '
+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
@@ -4002,7 +4002,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+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
@@ -4012,7 +4012,7 @@ EOF
 	test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27/wt"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -4022,7 +4022,7 @@ EOF
 	test_repo 27/sub/sub ../../.git ../../wt
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -4032,7 +4032,7 @@ EOF
 	test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../wt
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+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
@@ -4042,7 +4042,7 @@ EOF
 	test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+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
@@ -4052,7 +4052,7 @@ EOF
 	test_repo 27 .git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+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
@@ -4062,7 +4062,7 @@ EOF
 	test_repo 27 .git ..
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+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
@@ -4072,7 +4072,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" ..
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=.. at root' '
+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
@@ -4082,7 +4082,7 @@ EOF
 	test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+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
@@ -4092,7 +4092,7 @@ EOF
 	test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -4102,7 +4102,7 @@ EOF
 	test_repo 27/sub/sub ../../.git ../../..
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -4112,7 +4112,7 @@ EOF
 	test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../../
 '
 
-test_expect_failure '#27: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+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
@@ -4250,7 +4250,7 @@ test_expect_success '#30: setup' '
 	cd ..
 '
 
-test_expect_failure '#30: at root' '
+test_expect_success '#30: at root' '
 	(
 	cd 30 &&
 	GIT_DIR=.git &&
@@ -4289,7 +4289,7 @@ test_expect_success '#31: setup' '
 	cd ..
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=root at root' '
+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
@@ -4299,7 +4299,7 @@ EOF
 	test_repo 31 .git "$TRASH_DIRECTORY/31"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' '
+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
@@ -4309,7 +4309,7 @@ EOF
 	test_repo 31 .git .
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=root at root' '
+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
@@ -4319,7 +4319,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31"
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=root(rel) at root' '
+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
@@ -4329,7 +4329,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" .
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORKTREE=root in subdir' '
+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
@@ -4339,7 +4339,7 @@ EOF
 	test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -4349,7 +4349,7 @@ EOF
 	test_repo 31/sub/sub ../../.git ../..
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORKTREE=root in subdir' '
+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
@@ -4359,7 +4359,7 @@ EOF
 	test_repo 31/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31"
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' '
+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
@@ -4369,7 +4369,7 @@ EOF
 	test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../..
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=wt at root' '
+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
@@ -4379,7 +4379,7 @@ EOF
 	test_repo 31 .git "$TRASH_DIRECTORY/31/wt"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -4389,7 +4389,7 @@ EOF
 	test_repo 31 .git wt
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' '
+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
@@ -4399,7 +4399,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" wt
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=wt at root' '
+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
@@ -4409,7 +4409,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' '
+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
@@ -4419,7 +4419,7 @@ EOF
 	test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31/wt"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -4429,7 +4429,7 @@ EOF
 	test_repo 31/sub/sub ../../.git ../../wt
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' '
+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
@@ -4439,7 +4439,7 @@ EOF
 	test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../wt
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=wt in subdir' '
+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
@@ -4449,7 +4449,7 @@ EOF
 	test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=.. at root' '
+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
@@ -4459,7 +4459,7 @@ EOF
 	test_repo 31 .git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' '
+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
@@ -4469,7 +4469,7 @@ EOF
 	test_repo 31 .git ..
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=..(rel) at root' '
+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
@@ -4479,7 +4479,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" ..
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=.. at root' '
+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
@@ -4489,7 +4489,7 @@ EOF
 	test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' '
+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
@@ -4499,7 +4499,7 @@ EOF
 	test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY"
 '
 
-test_expect_failure '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -4509,7 +4509,7 @@ EOF
 	test_repo 31/sub/sub ../../.git ../../..
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' '
+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
@@ -4519,7 +4519,7 @@ EOF
 	test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../../
 '
 
-test_expect_failure '#31: GIT_DIR, GIT_WORK_TREE=.. in subdir' '
+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
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 44/47] Remove all logic from get_git_work_tree()
Message-ID: <1290785563-15339-45-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-45-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
This logic is now only used by cmd_init_db(). setup_* functions do not
rely on it any more. Move all the logic to cmd_init_db() and turn
get_git_work_tree() into a simple function.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/init-db.c |   14 +++++++++++---
 cache.h           |    1 -
 environment.c     |   32 ++++++++------------------------
 3 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index ea06478..e3af9ea 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -414,6 +414,7 @@ static const char *const init_db_usage[] = {
 int cmd_init_db(int argc, const char **argv, const char *prefix)
 {
 	const char *git_dir;
+	const char *work_tree;
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
 	const struct option init_db_options[] = {
@@ -480,8 +481,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	 * without --bare.  Catch the error early.
 	 */
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
-	if ((!git_dir || is_bare_repository_cfg == 1)
-	    && getenv(GIT_WORK_TREE_ENVIRONMENT))
+	work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
+	if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
 		die("%s (or --work-tree=<directory>) not allowed without "
 		    "specifying %s (or --git-dir=<directory>)",
 		    GIT_WORK_TREE_ENVIRONMENT,
@@ -496,7 +497,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	if (is_bare_repository_cfg < 0)
 		is_bare_repository_cfg = guess_repository_type(git_dir);
 
-	startup_info->setup_explicit = 1;
 	if (!is_bare_repository_cfg) {
 		if (git_dir) {
 			const char *git_dir_parent = strrchr(git_dir, '/');
@@ -511,10 +511,18 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			if (!getcwd(git_work_tree_cfg, PATH_MAX))
 				die_errno ("Cannot access current working directory");
 		}
+		if (work_tree)
+			set_git_work_tree(make_absolute_path(work_tree));
+		else
+			set_git_work_tree(git_work_tree_cfg);
 		if (access(get_git_work_tree(), X_OK))
 			die_errno ("Cannot access work tree '%s'",
 				   get_git_work_tree());
 	}
+	else {
+		if (work_tree)
+			set_git_work_tree(make_absolute_path(work_tree));
+	}
 
 	set_git_dir(make_absolute_path(git_dir));
 
diff --git a/cache.h b/cache.h
index b2cdda7..123dd4b 100644
--- a/cache.h
+++ b/cache.h
@@ -1119,7 +1119,6 @@ const char *split_cmdline_strerror(int cmdline_errno);
 /* git.c */
 struct startup_info {
 	int have_repository;
-	int setup_explicit;
 };
 extern struct startup_info *startup_info;
 
diff --git a/environment.c b/environment.c
index d811049..149c132 100644
--- a/environment.c
+++ b/environment.c
@@ -137,36 +137,20 @@ static int git_work_tree_initialized;
  */
 void set_git_work_tree(const char *new_work_tree)
 {
+	if (git_work_tree_initialized) {
+		new_work_tree = make_absolute_path(new_work_tree);
+		if (strcmp(new_work_tree, work_tree))
+			die("internal error: work tree has already been set\n"
+			    "Current worktree: %s\nNew worktree: %s",
+			    work_tree, new_work_tree);
+		return;
+	}
 	git_work_tree_initialized = 1;
-	free(work_tree);
 	work_tree = xstrdup(make_absolute_path(new_work_tree));
-	is_bare_repository_cfg = 0;
 }
 
 const char *get_git_work_tree(void)
 {
-	if (startup_info && !startup_info->setup_explicit) {
-		if (is_bare_repository_cfg == 1)
-			return NULL;
-		if (work_tree)
-			is_bare_repository_cfg = 0;
-		return work_tree;
-	}
-
-	if (!git_work_tree_initialized) {
-		work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
-		/* core.bare = true overrides implicit and config work tree */
-		if (!work_tree && is_bare_repository_cfg < 1) {
-			work_tree = git_work_tree_cfg;
-			/* make_absolute_path also normalizes the path */
-			if (work_tree && !is_absolute_path(work_tree))
-				work_tree = xstrdup(make_absolute_path(git_path("%s", work_tree)));
-		} else if (work_tree)
-			work_tree = xstrdup(make_absolute_path(work_tree));
-		git_work_tree_initialized = 1;
-		if (work_tree)
-			is_bare_repository_cfg = 0;
-	}
 	return work_tree;
 }
 
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 45/47] t0001: test git init when run via an alias
Message-ID: <1290785563-15339-46-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-46-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
From: Jonathan Nieder <jrnieder@gmail.com>

Add some tests to document the correct behavior of (possibly aliased)
init when run within and outside a git directory.

If I set up a simple git alias “quietinit = init --quiet”, usually it
will work just like ‘git init --quiet’.

There are some differences, unfortunately, since in the process of
checking for aliases, git has to look for a .git/config file.  If ‘git
quietinit’ is run from a subdirectory of an existing git repository,
that repository’s configuration will affect the configuration of the
new repository.  In particular, the new repository can inherit
bogus values for core.bare and core.worktree.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t0001-init.sh |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 7fe8883..28c1858 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' '
+	(
+		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' '
+	(
+		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' '
+	(
+		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' '
+	(
+		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 (
 		unset GIT_DIR
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 46/47] Revert "Documentation: always respect core.worktree if set"
Message-ID: <1290785563-15339-47-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-47-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
This reverts commit f5e025a9d5b35e24768475f6890b836ce0d5ed15.

The commit reflected what the code did. But the code did that because
it had bugs.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config.txt |   23 ++++++++---------------
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 538ebb5..e29b174 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -317,24 +317,17 @@ false), while all other repositories are assumed to be bare (bare
 = true).
 
 core.worktree::
-	Set the path to the root of the work tree.
+	Set the path to the working tree.  The value will not be
+	used in combination with repositories found automatically in
+	a .git directory (i.e. $GIT_DIR is not set).
 	This can be overridden by the GIT_WORK_TREE environment
 	variable and the '--work-tree' command line option. It can be
-	an absolute path or a relative path to the .git directory,
-	either specified by --git-dir or GIT_DIR, or automatically
-	discovered.
-	If --git-dir or GIT_DIR are specified but none of
+	a absolute path or relative path to the directory specified by
+	--git-dir or GIT_DIR.
+	Note: If --git-dir or GIT_DIR are specified but none of
 	--work-tree, GIT_WORK_TREE and core.worktree is specified,
-	the current working directory is regarded as the root of the
-	work tree.
-+
-Note that this variable is honored even when set in a configuration
-file in a ".git" subdirectory of a directory, and its value differs
-from the latter directory (e.g. "/path/to/.git/config" has
-core.worktree set to "/different/path"), which is most likely a
-misconfiguration.  Running git commands in "/path/to" directory will
-still use "/different/path" as the root of the work tree and can cause
-great confusion to the users.
+	the current working directory is regarded as the top directory
+	of your working tree.
 
 core.logAllRefUpdates::
 	Enable the reflog. Updates to a ref <ref> is logged to the file
-- 
1.7.3.2.316.gda8b3

```

## Nguyễn Thái Ngọc Duy, 2010-11-26 15:32

Subject: [PATCH 47/47] git.txt: correct where --work-tree path is relative to
Message-ID: <1290785563-15339-48-git-send-email-pclouds@gmail.com>
URL: https://gitlist.dev/e/1290785563-15339-48-git-send-email-pclouds%40gmail.com
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 0c897df..7433601 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -285,7 +285,7 @@ help ...`.
 	This can also be controlled by setting the GIT_WORK_TREE
 	environment variable and the core.worktree configuration
 	variable. It can be an absolute path or relative path to
-	the directory specified by --git-dir or GIT_DIR.
+	current working directory.
 	Note: If --git-dir or GIT_DIR are specified but none of
 	--work-tree, GIT_WORK_TREE and core.worktree is specified,
 	the current working directory is regarded as the top directory
-- 
1.7.3.2.316.gda8b3

```

## Junio C Hamano, 2010-11-29 21:29

Subject: Re: [PATCH 00/47] nd/setup updates on pu
Message-ID: <7v1v6324zu.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v1v6324zu.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com>

```
Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> Only tests are updated to eliminate bashisms. Tested on busybox ash.

Thanks for your attention to detail; will replace.

```

## Junio C Hamano, 2010-12-22 01:56

Subject: Re: [PATCH 36/47] rev-parse: prints --git-dir relative to user's cwd
Message-ID: <7vvd2m605f.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vvd2m605f.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1290785563-15339-37-git-send-email-pclouds@gmail.com>

```
Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> git_dir variable in environment.c is relative to git's cwd, not user's
> cwd. Convert the relative path (actualy by making it absolute path)
> before printing out.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>  builtin/rev-parse.c |    6 +++++-
>  1 files changed, 5 insertions(+), 1 deletions(-)
>
> diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
> index a5a1c86..65c287b 100644
> --- a/builtin/rev-parse.c
> +++ b/builtin/rev-parse.c
> @@ -647,7 +647,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
>  				static char cwd[PATH_MAX];
>  				int len;
>  				if (gitdir) {
> -					puts(gitdir);
> +					if (is_absolute_path(gitdir) || !prefix) {
> +						puts(gitdir);
> +						continue;
> +					}
> +					puts(make_absolute_path(gitdir));
>  					continue;
>  				}
>  				if (!prefix) {

I do not quite understand this change.  I can obtain GIT_DIR in a relative
form without this patch already:

    $ cd t/
    $ git --git-dir=../.git rev-parse --git-dir HEAD
    ../.git
    c7511731675da8b50c0d5243aa04a98c8a5ee316

Could we please have a new test case to demonstrate what is broken without
this patch?

```

## Junio C Hamano, 2010-12-22 01:56

Subject: Re: [PATCH 44/47] Remove all logic from get_git_work_tree()
Message-ID: <7vpqsu6059.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vpqsu6059.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1290785563-15339-45-git-send-email-pclouds@gmail.com>

```
Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> This logic is now only used by cmd_init_db(). setup_* functions do not
> rely on it any more. Move all the logic to cmd_init_db() and turn
> get_git_work_tree() into a simple function.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> diff --git a/environment.c b/environment.c
> index d811049..149c132 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -137,36 +137,20 @@ static int git_work_tree_initialized;
>   */
> ...
>  const char *get_git_work_tree(void)
>  {
> -	if (startup_info && !startup_info->setup_explicit) {
> -...
> -	}
>  	return work_tree;
>  }

Would it be a bug in the new set-up code if this function gets called and
work_tree is still NULL?

There are quite a few callers that call get_git_work_tree() and expect
that it will always return a non NULL pointer.  Perhaps we would want an
assertion here?

```

## Nguyen Thai Ngoc Duy, 2010-12-22 07:05

Subject: Re: [PATCH 36/47] rev-parse: prints --git-dir relative to user's cwd
Message-ID: <AANLkTi=DPrQirbp3mOfQkU3Dx_eYmp1inVYx-GqqD9V5@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTi%3DDPrQirbp3mOfQkU3Dx_eYmp1inVYx-GqqD9V5%40mail.gmail.com
In-Reply-To: <7vvd2m605f.fsf@alter.siamese.dyndns.org>

```
2010/12/22 Junio C Hamano <gitster@pobox.com>:
> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
>
>> git_dir variable in environment.c is relative to git's cwd, not user's
>> cwd. Convert the relative path (actualy by making it absolute path)
>> before printing out.
>>
>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
>> Signed-off-by: Junio C Hamano <gitster@pobox.com>
>> ---
>>  builtin/rev-parse.c |    6 +++++-
>>  1 files changed, 5 insertions(+), 1 deletions(-)
>>
>> diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
>> index a5a1c86..65c287b 100644
>> --- a/builtin/rev-parse.c
>> +++ b/builtin/rev-parse.c
>> @@ -647,7 +647,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
>>                               static char cwd[PATH_MAX];
>>                               int len;
>>                               if (gitdir) {
>> -                                     puts(gitdir);
>> +                                     if (is_absolute_path(gitdir) || !prefix) {
>> +                                             puts(gitdir);
>> +                                             continue;
>> +                                     }
>> +                                     puts(make_absolute_path(gitdir));
>>                                       continue;
>>                               }
>>                               if (!prefix) {
>
> I do not quite understand this change.  I can obtain GIT_DIR in a relative
> form without this patch already:
>
>    $ cd t/
>    $ git --git-dir=../.git rev-parse --git-dir HEAD
>    ../.git
>    c7511731675da8b50c0d5243aa04a98c8a5ee316
>
> Could we please have a new test case to demonstrate what is broken without
> this patch?
>

Um.. GIT_DIR can be changed by set_git_dir() inside
setup_directory_gently() and be relative to git's internal (movable)
cwd. The current code won't fall to that code path because GIT_DIR is
made absolute in most cases. A few cases we keep GIT_DIR relative,
we're sure cwd is not moved, or $GIT_DIR is not set and handled by
rev-parse code.

I reverted the patch and ran "make test". Passed. When an attempt to
make $GIT_DIR relative to worktree as much as possible happens, this
may be needed. But for now, I'm OK if you take this patch out. I'll
put it back on when I make such an attempt.
-- 
Duy

```

## Nguyen Thai Ngoc Duy, 2010-12-22 07:22

Subject: Re: [PATCH 44/47] Remove all logic from get_git_work_tree()
Message-ID: <AANLkTikOOaKSf333UzawEgAf_=t-WBrWLu7tmiOrqO8V@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTikOOaKSf333UzawEgAf_%3Dt-WBrWLu7tmiOrqO8V%40mail.gmail.com
In-Reply-To: <7vpqsu6059.fsf@alter.siamese.dyndns.org>

```
2010/12/22 Junio C Hamano <gitster@pobox.com>:
>>  const char *get_git_work_tree(void)
>>  {
>> -     if (startup_info && !startup_info->setup_explicit) {
>> -...
>> -     }
>>       return work_tree;
>>  }
>
> Would it be a bug in the new set-up code if this function gets called and
> work_tree is still NULL?
>
> There are quite a few callers that call get_git_work_tree() and expect
> that it will always return a non NULL pointer.  Perhaps we would want an
> assertion here?
>

While the assertion sounds good, it does not work well. The old
function can return NULL in bare repos. is_bare_repository() and
is_inside_work_tree() expect NULL from get_git_work_tree() sometimes.

I'll see if I can move is_inside_work_tree() over environment.c (so
that both callers can access work_tree var directly) and have a clean
"make test". It does not look feasible though because of the static
variable inside_work_tree in setup.c.
-- 
Duy

```

## Junio C Hamano, 2010-12-22 15:17

Subject: Re: [PATCH 44/47] Remove all logic from get_git_work_tree()
Message-ID: <7vd3ot6dlx.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vd3ot6dlx.fsf%40alter.siamese.dyndns.org
In-Reply-To: <AANLkTikOOaKSf333UzawEgAf_=t-WBrWLu7tmiOrqO8V@mail.gmail.com>

```
Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:

> 2010/12/22 Junio C Hamano <gitster@pobox.com>:
>>>  const char *get_git_work_tree(void)
>>>  {
>>> -     if (startup_info && !startup_info->setup_explicit) {
>>> -...
>>> -     }
>>>       return work_tree;
>>>  }
>>
>> Would it be a bug in the new set-up code if this function gets called and
>> work_tree is still NULL?
>>
>> There are quite a few callers that call get_git_work_tree() and expect
>> that it will always return a non NULL pointer.  Perhaps we would want an
>> assertion here?
>>
>
> While the assertion sounds good, it does not work well. The old
> function can return NULL in bare repos. is_bare_repository() and
> is_inside_work_tree() expect NULL from get_git_work_tree() sometimes.

Ok, don't bother changing anything in that case---it won't help us much.

```

## Jonathan Nieder, 2011-01-18 07:44

Subject: Re: [PATCH 39/47] setup: limit get_git_work_tree()'s to explicit setup case only
Message-ID: <20110118074400.GA4185@burratino>
URL: https://gitlist.dev/e/20110118074400.GA4185%40burratino
In-Reply-To: <1290785563-15339-40-git-send-email-pclouds@gmail.com>

```
Nguyễn Thái Ngọc Duy wrote:

> get_git_work_tree() takes input as core.worktree, core.bare,
> GIT_WORK_TREE and decides correct worktree setting.
>
> Unfortunately it does not do its job well. core.worktree and
> GIT_WORK_TREE should only be taken into account, if GIT_DIR is set

As advertised, before this change

	GIT_WORK_TREE=$path git add .

paid attention to $GIT_WORK_TREE (and set GIT_DIR=.git), and
afterwards the GIT_WORK_TREE setting has been ignored when GIT_DIR is
not set explicitly.

Unfortunately, that breaks some scripts.  Example: using the "git
import-dsc" utility from git-buildpackage to import a source package:

	debsnap libwpd 0.7.2-1
	git clone git://libwpd.git.sourceforge.net/gitroot/libwpd/libwpd
	git tag upstream/0.7.2 RELEASE-0-7-2^{commit}
	git reset --keep origin/master
	git import-dsc ../source-libwpd/libwpd_0.7.2-1.dsc 
	echo $?
	git show --raw
	echo done.

With git v1.7.4-rc2:

	HEAD is now at d183cc6 Imported Debian patch 0.7.2-1
	gbp:info: Everything imported under 'libwpd'
	0
	commit d183cc6c4b8dcaf22b1b0875aad0655846ed3b1b
	Author: Masayuki Hatta (mhatta) <mhatta@debian.org>
	Date:   Tue Aug 10 00:37:47 2004 +0900

	    Imported Debian patch 0.7.2-1

	done

versus v1.7.3.2:

	HEAD is now at 735a8f2 Imported Debian patch 0.7.2-1
	gbp:info: Everything imported under 'libwpd'
	0
	commit 735a8f21ea817417ecc035817f777bd2943d4efc
	Author: Masayuki Hatta (mhatta) <mhatta@debian.org>
	Date:   Tue Aug 10 00:37:47 2004 +0900

	    Imported Debian patch 0.7.2-1

	:100644 000000 038cd09... 0000000... D  .gitignore
	:000000 100644 0000000... 0189791... A  CHANGES
	[...]

git-buildpackage uses the equivalent of

	GIT_INDEX_FILE=$(pwd)/.git/gbp_index \
	GIT_WORK_TREE=$unpack_dir \
	git add -f .

when creating the commit, so with v1.7.4-rc0 and later it is taking
its content from the cwd, producing an incorrect result without
complaint.

How about something like this patch?  It only concerns the
GIT_WORK_TREE variable and --work-tree command line option; the
semantics of core.worktree are unaffected.

(Sorry, no real patch yet.  Updating the test to reflect the change is
a pain in the neck.)

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
diff --git a/setup.c b/setup.c
index 3d73269..28b2fef 100644
--- a/setup.c
+++ b/setup.c
@@ -419,6 +419,11 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 		return NULL;
 	}
 
+	if (getenv(GIT_WORK_TREE_ENVIRONMENT)) {
+		warning("GIT_WORK_TREE without explicit GIT_DIR is deprecated");
+		return setup_explicit_git_dir(gitdir, cwd, offset, nongit_ok);
+	}
+
 	/* #0, #1, #5, #8, #9, #12, #13 */
 	set_git_work_tree(".");
 	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
@@ -443,6 +448,11 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
 	if (check_repository_format_gently(".", nongit_ok))
 		return NULL;
 
+	if (getenv(GIT_WORK_TREE_ENVIRONMENT)) {
+		warning("GIT_WORK_TREE without explicit GIT_DIR is deprecated");
+		return setup_explicit_git_dir(".", cwd, offset, nongit_ok);
+	}
+
 	inside_git_dir = 1;
 	inside_work_tree = 0;
 	if (offset != len) {

```

## Nguyen Thai Ngoc Duy, 2011-01-18 13:59

Subject: Re: [PATCH 39/47] setup: limit get_git_work_tree()'s to explicit setup case only
Message-ID: <AANLkTinTSiDhfcEzYVji0xD44BY0HPpzLYuZoNgMPdkt@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTinTSiDhfcEzYVji0xD44BY0HPpzLYuZoNgMPdkt%40mail.gmail.com
In-Reply-To: <20110118074400.GA4185@burratino>

```
2011/1/18 Jonathan Nieder <jrnieder@gmail.com>:
> How about something like this patch?  It only concerns the
> GIT_WORK_TREE variable and --work-tree command line option; the
> semantics of core.worktree are unaffected.

Perhaps only activate your code if $GIT_WORK_TREE is absolute path?
Things may go wild if $GIT_WORK_TREE is relative. We can die() if
GIT_WORK_TREE is set but not used. Annoying, but better than leave the
errors unseen.

> (Sorry, no real patch yet.  Updating the test to reflect the change is
> a pain in the neck.)

Yeah, I count on it to (over-)catch every mistakes in setup code :D
-- 
Duy

```

## Junio C Hamano, 2011-01-18 19:41

Subject: Re: [PATCH 39/47] setup: limit get_git_work_tree()'s to explicit setup case only
Message-ID: <7v1v4aknij.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v1v4aknij.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20110118074400.GA4185@burratino>

```
Jonathan Nieder <jrnieder@gmail.com> writes:

> diff --git a/setup.c b/setup.c
> index 3d73269..28b2fef 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -419,6 +419,11 @@ static const char *setup_discovered_git_dir(const char *gitdir,
>  		return NULL;
>  	}
>  
> +	if (getenv(GIT_WORK_TREE_ENVIRONMENT)) {
> +		warning("GIT_WORK_TREE without explicit GIT_DIR is deprecated");
> +		return setup_explicit_git_dir(gitdir, cwd, offset, nongit_ok);
> +	}
> +

My knee-jerk reaction is that calling this "deprecated" is probably
confusing. git merely failed to notice misconfiguration so far and went
ahead to produce a random result when GIT_DIR is not set (hence the usual
rule is in effect to find out where the .git directory is, starting from
the assumption that you _are_ somewhere _inside_ the work tree, _and_ the
root of the work tree _is_ where that .git directory is found in) and at
the same time GIT_WORK_TREE is pointing at a random other location.

Unless that location happens to match the parent directory of the
discovered .git, this invalidates the assumption of the whole discovery
logic (iow, how you found .git to begin with). In other words, it is my
understanding that setting only GIT_WORK_TREE without setting GIT_DIR
wasn't meant to be supported at all, because there is no sane logic to
specify a consistent behaviour in such a case.

If "we first run discovery as if you were somewhere in your work tree to
find .git directory, but you are allowed to say that your working tree is
elsewhere, possibly completely unrelated to the tree hierarchy used to
find .git directory to begin with; we could accomodate these conflicting
wishes because hopefully the necessary set-up happens before we actually
need to touch anything in the work tree" were a sane specification, this
patch may start making sense. Not breaking existing scripts that rely on
the behaviour is a nice bonus. The "hopefully" part makes me worried
enough to keep me from saying that semantics is sane without thinking
though.

I notice that git(1) manual page discusses --work-tree=<path> (and
GIT_WORK_TREE) to a reasonable level of details (the most importantly, the
rule to determine where the root of the working tree is when nothing is
specified is given), but the corresponding description on --git-dir=<path>
(and GIT_DIR) is too sketchy to tell how the discovery works when nothing
is given. Perhaps that part needs to address what the semantics should be?

>  	/* #0, #1, #5, #8, #9, #12, #13 */
>  	set_git_work_tree(".");
>  	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
> @@ -443,6 +448,11 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
>  	if (check_repository_format_gently(".", nongit_ok))
>  		return NULL;
>  
> +	if (getenv(GIT_WORK_TREE_ENVIRONMENT)) {
> +		warning("GIT_WORK_TREE without explicit GIT_DIR is deprecated");
> +		return setup_explicit_git_dir(".", cwd, offset, nongit_ok);
> +	}
>  	inside_git_dir = 1;
>  	inside_work_tree = 0;

This is for people who do "cd .git && GIT_WORK_TREE=.. git cmd". I have to
wonder what happens to the pathspec given to the cmd---you are clearly
outside of your working tree.

A tangent.

Do we make sure that whatever GIT_WORK_TREE we end up with using is an
ancestor directory of the $CWD when we require us to be inside the working
tree? I think we should, as I don't think of a sane use case otherwise
(unless you call "cd ../neigh; GIT_WORK_TREE=../work git diff ../work/foo"
a sane way to futz with the file "foo" in the working tree "work" from a
directory "neigh" that is unrelated to the repository).

```

## Nguyen Thai Ngoc Duy, 2011-01-19 01:58

Subject: Re: [PATCH 39/47] setup: limit get_git_work_tree()'s to explicit setup case only
Message-ID: <AANLkTi=bm6KO24XTMA+LM+xnszgFHJiV0inXZ-RJwwd-@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTi%3Dbm6KO24XTMA%2BLM%2BxnszgFHJiV0inXZ-RJwwd-%40mail.gmail.com
In-Reply-To: <7v1v4aknij.fsf@alter.siamese.dyndns.org>

```
2011/1/19 Junio C Hamano <gitster@pobox.com>:
> This is for people who do "cd .git && GIT_WORK_TREE=.. git cmd". I have to
> wonder what happens to the pathspec given to the cmd---you are clearly
> outside of your working tree.

pathspecs are relative to worktree's root because prefix is NULL in
this case. Not very intuitive. And pathspecs that are supposed to take
files relative to user's cwd simply fail.

> Do we make sure that whatever GIT_WORK_TREE we end up with using is an
> ancestor directory of the $CWD when we require us to be inside the working
> tree?

We don't for most of commands (i.e. blindly chdir(worktree) in
setup_work_tree()). Only two commands (ls-files and rev-parse) seem to
do that.

> I think we should, as I don't think of a sane use case otherwise
> (unless you call "cd ../neigh; GIT_WORK_TREE=../work git diff ../work/foo"
> a sane way to futz with the file "foo" in the working tree "work" from a
> directory "neigh" that is unrelated to the repository).

But we don't strictly need that for whole tree operations. If
pathspecs are not given, wherever worktree is compared to cwd does not
matter much. The tricky thing is, when setup code does not know in
advance whether pathspecs are given. Perhaps something (untested) like
this for a start? Some commands like commit can also have
WHOLE_WORK_TREE, but it needs to check for is_inside_work_tree() by
itself it pathspec is given.

diff --git a/git.c b/git.c
index 68334f6..28abbdd 100644
--- a/git.c
+++ b/git.c
@@ -248,6 +248,10 @@ const char git_version_string[] = GIT_VERSION;
  * RUN_SETUP for reading from the configuration file.
  */
 #define NEED_WORK_TREE		(1<<3)
+/*
+ * This command only works on work tree as a whole
+ */
+#define WHOLE_WORK_TREE         (1<<4)

 struct cmd_struct {
 	const char *cmd;
@@ -283,7 +287,7 @@ static int run_builtin(struct cmd_struct *p, int
argc, const char **argv)
 	commit_pager_choice();

 	if (!help && p->option & NEED_WORK_TREE)
-		setup_work_tree();
+		setup_work_tree(p->option & WHOLE_WORK_TREE);

 	trace_argv_printf(argv, "trace: built-in: git");

@@ -328,7 +332,7 @@ static void handle_internal_command(int argc,
const char **argv)
 		{ "check-ref-format", cmd_check_ref_format },
 		{ "check-attr", cmd_check_attr, RUN_SETUP },
 		{ "cherry", cmd_cherry, RUN_SETUP },
-		{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+		{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE |
WHOLE_WORK_TREE },
 		{ "clone", cmd_clone },
 		{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
 		{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
@@ -362,7 +366,7 @@ static void handle_internal_command(int argc,
const char **argv)
 		{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
 		{ "mailinfo", cmd_mailinfo },
 		{ "mailsplit", cmd_mailsplit },
-		{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
+		{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE | WHOLE_WORK_TREE },
 		{ "merge-base", cmd_merge_base, RUN_SETUP },
 		{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
 		{ "merge-index", cmd_merge_index, RUN_SETUP },
@@ -397,13 +401,13 @@ static void handle_internal_command(int argc,
const char **argv)
 		{ "reset", cmd_reset, RUN_SETUP },
 		{ "rev-list", cmd_rev_list, RUN_SETUP },
 		{ "rev-parse", cmd_rev_parse },
-		{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
+		{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE | WHOLE_WORK_TREE },
 		{ "rm", cmd_rm, RUN_SETUP },
 		{ "send-pack", cmd_send_pack, RUN_SETUP },
 		{ "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
 		{ "show-branch", cmd_show_branch, RUN_SETUP },
 		{ "show", cmd_show, RUN_SETUP },
-		{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
+		{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE | WHOLE_WORK_TREE },
 		{ "stripspace", cmd_stripspace },
 		{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
 		{ "tag", cmd_tag, RUN_SETUP },
diff --git a/setup.c b/setup.c
index 3d73269..c14e55c 100644
--- a/setup.c
+++ b/setup.c
@@ -208,7 +208,7 @@ int is_inside_work_tree(void)
 	return inside_work_tree;
 }

-void setup_work_tree(void)
+void setup_work_tree(int gently)
 {
 	const char *work_tree, *git_dir;
 	static int initialized = 0;
@@ -219,7 +219,11 @@ void setup_work_tree(void)
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
 		git_dir = make_absolute_path(git_dir);
-	if (!work_tree || chdir(work_tree))
+	if (work_tree && (gently || is_inside_work_tree()))
+		; 		/* Good */
+	else
+		die("This operation must be run in a work tree");
+	if (chdir(work_tree))
 		die("This operation must be run in a work tree");

 	/*

-- 
Duy

```

## Jonathan Nieder, 2011-01-19 12:37

Subject: [PATCH/RFC 0/3] setup: stop ignoring GIT_WORK_TREE (when GIT_DIR is unset)
Message-ID: <20110119123732.GA23222@burratino>
URL: https://gitlist.dev/e/20110119123732.GA23222%40burratino
In-Reply-To: <7v1v4aknij.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:

>> +++ b/setup.c
>> @@ -419,6 +419,11 @@ static const char *setup_discovered_git_dir(const char *gitdir,
>>  		return NULL;
>>  	}
>>  
>> +	if (getenv(GIT_WORK_TREE_ENVIRONMENT)) {
>> +		warning("GIT_WORK_TREE without explicit GIT_DIR is deprecated");
>> +		return setup_explicit_git_dir(gitdir, cwd, offset, nongit_ok);
>> +	}
>> +
>
> My knee-jerk reaction is that calling this "deprecated" is probably
> confusing. git merely failed to notice misconfiguration

After staring at test results, I agree.  The rule, before nd/setup,
seems to be something like this:

 - if GIT_DIR is set, you're safe
 - if GIT_DIR is unset and .git is in the current directory,
   GIT_WORK_TREE will work by accident
 - otherwise, git errors out.

The patch below should be more robust.  It prints a warning:

	warning: pretending GIT_DIR was supplied alongside GIT_WORK_TREE

As the night winds on I am less sure that that warning is a good idea.
The .git discovery behavior seems relatively safe.  What is more
worrisome for the future of the use of GIT_WORK_TREE independent of
cwd is the interaction with pathspecs.

Jonathan Nieder (3):
  tests: cosmetic improvements to the repo-setup test
  tests: make the setup tests briefer
  setup: stop ignoring GIT_WORK_TREE and core.worktree

 setup.c               |   27 +-
 t/t1510-repo-setup.sh | 5166 +++++++------------------------------------------
 2 files changed, 729 insertions(+), 4464 deletions(-)

```

## Jonathan Nieder, 2011-01-19 12:38

Subject: [PATCH 1/3] tests: cosmetic improvements to the repo-setup test
Message-ID: <20110119123822.GB23222@burratino>
URL: https://gitlist.dev/e/20110119123822.GB23222%40burratino
In-Reply-To: <20110119123732.GA23222@burratino>

```
Give an overview in "sh t1510-repo-setup.sh --help" output.
Waste some vertical and horizontal space for clearer code.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 t/t1510-repo-setup.sh |   94 ++++++++++++++++++++++++++-----------------------
 1 files changed, 50 insertions(+), 44 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index e9c451c..f42f206 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -1,53 +1,59 @@
 #!/bin/sh
 
-test_description='Tests of cwd/prefix/worktree/gitdir setup in all cases'
+test_description="Tests of cwd/prefix/worktree/gitdir setup in all cases
 
+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-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() {
+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
+		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
 	)
 }
 
-- 
1.7.4.rc2

```

## Jonathan Nieder, 2011-01-19 12:42

Subject: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <20110119124230.GD23222@burratino>
URL: https://gitlist.dev/e/20110119124230.GD23222%40burratino
In-Reply-To: <20110119123732.GA23222@burratino>

```
In the usual case, git commands are run from within a git worktree.
The toplevel directory and associated .git dir are found by chdir-ing
to .. repeatedly until .git is a valid repository.

That behavior can be overridden in two ways.

 (1) By setting GIT_DIR (through the environment or the --git-dir
     command line option), one can keep the repository somewhere
     unrelated to the worktree.

 (2) By setting GIT_WORK_TREE (through the environment, --work-tree
     command line option, or [core] worktree configuration) in
     addition to GIT_DIR, one can use a directory other than the cwd
     as toplevel of the worktree.

Unfortunately the existence of GIT_WORK_TREE makes it tempting to
use without setting GIT_DIR.  Until v1.7.4-rc0~4^2~9 (setup: limit
get_git_work_tree()'s to explicit setup case only, 2010-11-26), that
only happened to work, sometimes:

 - if .git is in the current directory, it might work;
 - otherwise, git would fail to discover the .git directory.

Ouch.  It would be better to forbid setting a work tree without git
dir entirely, except that due to this accidental support some scripts
(e.g., git-buildpackage, gitolite) learned to use rely on it over the
years.

Instead (1) first run discovery as though within a worktree trying to
find the .git dir, and (2) only once discovery is finished, check the
GIT_WORK_TREE setting to see if the worktree is declared to be
somewhere else entirely.

Also print a warning when GIT_WORK_TREE is set and GIT_DIR not, to
prevent nonportable scripts relying on this new behavior.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 setup.c               |   27 +++++++-
 t/t1510-repo-setup.sh |  199 ++++++++++++++++++++++++++----------------------
 2 files changed, 134 insertions(+), 92 deletions(-)

diff --git a/setup.c b/setup.c
index 3d73269..c0f5846 100644
--- a/setup.c
+++ b/setup.c
@@ -411,6 +411,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 	if (check_repository_format_gently(gitdir, nongit_ok))
 		return NULL;
 
+	/* Accept --work-tree to support old scripts that played with fire. */
+	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
+		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
+		if (offset != len && !is_absolute_path(gitdir))
+			gitdir = xstrdup(make_absolute_path(gitdir));
+		if (chdir(cwd))
+			die_errno("Could not come back to cwd");
+		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+	}
+
 	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
 	if (is_bare_repository_cfg > 0) {
 		set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir));
@@ -443,6 +453,19 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
 	if (check_repository_format_gently(".", nongit_ok))
 		return NULL;
 
+	/*
+	 * Accept --work-tree, reluctantly.
+	 */
+	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
+		const char *gitdir;
+
+		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
+		gitdir = offset == len ? "." : xmemdupz(cwd, offset);
+		if (chdir(cwd))
+			die_errno("Could not come back to cwd");
+		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+	}
+
 	inside_git_dir = 1;
 	inside_work_tree = 0;
 	if (offset != len) {
@@ -509,8 +532,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 * validation.
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
-	if (gitdirenv)
+	if (gitdirenv) {
+		trace_printf("trace: gitdirenv = %s\n", gitdirenv);
 		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
+	}
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 4f8f976..b8a1b02 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -16,8 +16,9 @@ A few rules for repo setup:
 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.
+5. GIT_WORK_TREE/core.worktree is only meant to work if GIT_DIR is set.
+   Otherwise there is a warning and a best effort is made to follow
+   historical behavior.
 
 6. Effective GIT_WORK_TREE overrides core.worktree and core.bare
 
@@ -224,13 +225,16 @@ try_repo () {
 test_expect_success '#0: nonbare repo, no explicit configuration' '
 	try_repo 0 unset unset unset "" unset \
 		.git "$here/0" "$here/0" "(null)" \
-		.git "$here/0" "$here/0" sub/
+		.git "$here/0" "$here/0" sub/ 2>messages &&
+	! grep "warning:.*GIT_DIR.*GIT_WORK_TREE" messages
 '
 
-test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is ignored' '
-	try_repo 1 non-existent unset unset "" unset \
-		.git "$here/1" "$here/1" "(null)" \
-		.git "$here/1" "$here/1" sub/
+test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is reluctantly accepted' '
+	mkdir -p wt &&
+	try_repo 1 "$here" unset unset "" unset \
+		"$here/1/.git" "$here" "$here" 1/ \
+		"$here/1/.git" "$here" "$here" 1/sub/ 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 test_expect_success '#2: worktree defaults to cwd with explicit GIT_DIR' '
@@ -251,17 +255,24 @@ test_expect_success '#3: setup' '
 '
 run_wt_tests 3
 
-test_expect_success '#4: core.worktree without GIT_DIR set is ignored' '
-	try_repo 4 unset unset non-existent "" unset \
-		.git "$here/4" "$here/4" "(null)" \
-		.git "$here/4" "$here/4" sub/
+test_expect_success '#4: core.worktree without GIT_DIR set is reluctantly accepted' '
+	setup_repo 4 ../sub "" unset &&
+	mkdir -p 4/sub sub &&
+	try_case 4 unset unset \
+		.git "$here/4/sub" "$here/4" "(null)" \
+		"$here/4/.git" "$here/4/sub" "$here/4/sub" "(null)" 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
-test_expect_success '#5: core.worktree + GIT_WORK_TREE is still ignored' '
+test_expect_success '#5: core.worktree + GIT_WORK_TREE is reluctantly accepted' '
 	# or: you cannot intimidate away the lack of GIT_DIR setting
-	try_repo 5 non-existent-too unset non-existent "" unset \
-		.git "$here/5" "$here/5" "(null)" \
-		.git "$here/5" "$here/5" sub/
+	try_repo 5 "$here" unset "$here/5" "" unset \
+		"$here/5/.git" "$here" "$here" 5/ \
+		"$here/5/.git" "$here" "$here" 5/sub/ 2>message &&
+	try_repo 5a .. unset "$here/5a" "" unset \
+		"$here/5a/.git" "$here" "$here" 5a/ \
+		"$here/5a/.git" "$here/5a" "$here/5a" sub/ &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 test_expect_success '#6: setting GIT_DIR brings core.worktree to life' '
@@ -353,10 +364,12 @@ test_expect_success '#8: gitfile, easy case' '
 		"$here/8.git" "$here/8" "$here/8" sub/
 '
 
-test_expect_success '#9: GIT_WORK_TREE ignored even with gitfile' '
-	try_repo 9 non-existent unset unset gitfile unset \
-		"$here/9.git" "$here/9" "$here/9" "(null)" \
-		"$here/9.git" "$here/9" "$here/9" sub/
+test_expect_success '#9: GIT_WORK_TREE reluctantly accepted with gitfile' '
+	mkdir -p 9/wt &&
+	try_repo 9 wt unset unset gitfile unset \
+		"$here/9.git" "$here/9/wt" "$here/9" "(null)" \
+		"$here/9.git" "$here/9/sub/wt" "$here/9/sub" "(null)" 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 test_expect_success '#10: GIT_DIR can point to gitfile' '
@@ -378,17 +391,19 @@ test_expect_success '#11: setup' '
 '
 run_wt_tests 11 gitfile
 
-test_expect_success '#12: core.worktree with gitfile is still ignored' '
-	try_repo 12 unset unset non-existent gitfile unset \
+test_expect_success '#12: core.worktree with gitfile is reluctantly accepted' '
+	try_repo 12 unset unset "$here/12" gitfile unset \
 		"$here/12.git" "$here/12" "$here/12" "(null)" \
-		"$here/12.git" "$here/12" "$here/12" sub/
+		"$here/12.git" "$here/12" "$here/12" sub/ 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
-test_expect_success '#13: core.worktree+GIT_WORK_TREE ignored (with gitfile)' '
+test_expect_success '#13: core.worktree+GIT_WORK_TREE relucantly accepted (with gitfile)' '
 	# or: you cannot intimidate away the lack of GIT_DIR setting
 	try_repo 13 non-existent-too unset non-existent gitfile unset \
-		"$here/13.git" "$here/13" "$here/13" "(null)" \
-		"$here/13.git" "$here/13" "$here/13" sub/
+		"$here/13.git" "$here/13/non-existent-too" "$here/13" "(null)" \
+		"$here/13.git" "$here/13/sub/non-existent-too" "$here/13/sub" "(null)" 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 # case #14.
@@ -499,30 +514,32 @@ test_expect_success '#16c: bare .git has no worktree' '
 		"$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
 '
 
-test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is ignored (bare case)' '
+test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is reluctantly accepted (bare case)' '
 	# Just like #16.
 	setup_repo 17a unset "" true &&
 	setup_repo 17b unset "" true &&
 	mkdir -p 17a/.git/wt/sub &&
 	mkdir -p 17b/.git/wt/sub &&
 
-	try_case 17a/.git non-existent unset \
-		. "(null)" "$here/17a/.git" "(null)" &&
-	try_case 17a/.git/wt non-existent unset \
-		"$here/17a/.git" "(null)" "$here/17a/.git/wt" "(null)" &&
-	try_case 17a/.git/wt/sub non-existent unset \
-		"$here/17a/.git" "(null)" "$here/17a/.git/wt/sub" "(null)" &&
+	try_case 17a/.git "$here/17a" unset \
+		"$here/17a/.git" "$here/17a" "$here/17a" .git/ \
+		2>message &&
+	try_case 17a/.git/wt "$here/17a" unset \
+		"$here/17a/.git" "$here/17a" "$here/17a" .git/wt/ &&
+	try_case 17a/.git/wt/sub "$here/17a" unset \
+		"$here/17a/.git" "$here/17a" "$here/17a" .git/wt/sub/ &&
 
-	try_case 17b/.git non-existent unset \
-		. "(null)" "$here/17b/.git" "(null)" &&
-	try_case 17b/.git/wt non-existent unset \
-		"$here/17b/.git" "(null)" "$here/17b/.git/wt" "(null)" &&
-	try_case 17b/.git/wt/sub non-existent unset \
-		"$here/17b/.git" "(null)" "$here/17b/.git/wt/sub" "(null)" &&
+	try_case 17b/.git "$here/17b" unset \
+		"$here/17b/.git" "$here/17b" "$here/17b" .git/ &&
+	try_case 17b/.git/wt "$here/17b" unset \
+		"$here/17b/.git" "$here/17b" "$here/17b" .git/wt/ &&
+	try_case 17b/.git/wt/sub "$here/17b" unset \
+		"$here/17b/.git" "$here/17b" "$here/17b" .git/wt/sub/ &&
 
-	try_repo 17c non-existent unset unset "" true \
-		.git "(null)" "$here/17c" "(null)" \
-		"$here/17c/.git" "(null)" "$here/17c/sub" "(null)"
+	try_repo 17c "$here/17c" unset unset "" true \
+		.git "$here/17c" "$here/17c" "(null)" \
+		"$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
@@ -541,56 +558,43 @@ test_expect_success '#19: setup' '
 '
 run_wt_tests 19
 
-test_expect_success '#20a: core.worktree without GIT_DIR ignored (inside .git)' '
-	# Just like case #16a.
-	setup_repo 20a non-existent "" unset &&
+test_expect_success '#20a: core.worktree without GIT_DIR reluctantly accepted (inside .git)' '
+	# Unlike case #16a.
+	setup_repo 20a "$here/20a" "" unset &&
 	mkdir -p 20a/.git/wt/sub &&
 	try_case 20a/.git unset unset \
-		. "(null)" "$here/20a/.git" "(null)" &&
+		"$here/20a/.git" "$here/20a" "$here/20a" .git/ 2>message &&
 	try_case 20a/.git/wt unset unset \
-		"$here/20a/.git" "(null)" "$here/20a/.git/wt" "(null)" &&
+		"$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
 	try_case 20a/.git/wt/sub unset unset \
-		"$here/20a/.git" "(null)" "$here/20a/.git/wt/sub" "(null)"
+		"$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
-test_expect_success '#20b/c: core.worktree without GIT_DIR ignored (bare repository)' '
-	# Just like case #16b/c.
+test_expect_success '#20b/c: core.worktree and core.bare conflict' '
 	setup_repo 20b non-existent "" true &&
 	mkdir -p 20b/.git/wt/sub &&
-	try_case 20b/.git unset unset \
-		. "(null)" "$here/20b/.git" "(null)" &&
-	try_case 20b/.git/wt unset unset \
-		"$here/20b/.git" "(null)" "$here/20b/.git/wt" "(null)" &&
-	try_case 20b/.git/wt/sub unset unset \
-		"$here/20b/.git" "(null)" "$here/20b/.git/wt/sub" "(null)" &&
-	try_repo 20c unset unset non-existent "" true \
-		.git "(null)" "$here/20c" "(null)" \
-		"$here/20c/.git" "(null)" "$here/20c/sub" "(null)"
+	(
+		cd 20b/.git &&
+		test_must_fail git symbolic-ref HEAD >/dev/null
+	) 2>message &&
+	grep "core.bare and core.worktree" message
 '
 
-test_expect_success '#21: core.worktree+GIT_WORK_TREE without GIT_DIR ignored (bare cases)' '
-	setup_repo 21a non-existent "" unset &&
-	mkdir -p 21a/.git/wt/sub &&
-	try_case 21a/.git non-existent-too unset \
-		. "(null)" "$here/21a/.git" "(null)" &&
-	try_case 21a/.git/wt non-existent-too unset \
-		"$here/21a/.git" "(null)" "$here/21a/.git/wt" "(null)" &&
-	try_case 21a/.git/wt/sub non-existent-too unset \
-		"$here/21a/.git" "(null)" "$here/21a/.git/wt/sub" "(null)" &&
+# Case #21: core.worktree/GIT_WORK_TREE reluctantly overrides core.bare' '
+test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
+	setup_repo 21 non-existent "" unset &&
+	mkdir -p 21/.git/wt/sub &&
+	(
+		cd 21/.git &&
+		GIT_WORK_TREE="$here/21" &&
+		export GIT_WORK_TREE &&
+		git symbolic-ref HEAD >/dev/null
+	) 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 
-	setup_repo 21b non-existent "" true &&
-	mkdir -p 21b/.git/wt/sub &&
-	try_case 21b/.git non-existent-too unset \
-		. "(null)" "$here/21b/.git" "(null)" &&
-	try_case 21b/.git/wt non-existent-too unset \
-		"$here/21b/.git" "(null)" "$here/21b/.git/wt" "(null)" &&
-	try_case 21b/.git/wt/sub non-existent-too unset \
-		"$here/21b/.git" "(null)" "$here/21b/.git/wt/sub" "(null)" &&
-
-	try_repo 21c non-existent-too unset non-existent "" true \
-		.git "(null)" "$here/21c" "(null)" \
-		"$here/21c/.git" "(null)" "$here/21c/sub" "(null)"
 '
+run_wt_tests 21
 
 test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
 	# like case #6.
@@ -699,10 +703,11 @@ test_expect_success '#24: bare repo has no worktree (gitfile case)' '
 		"$here/24.git" "(null)" "$here/24/sub" "(null)"
 '
 
-test_expect_success '#25: GIT_WORK_TREE ignored if GIT_DIR unset (bare gitfile case)' '
-	try_repo 25 non-existent unset unset gitfile true \
-		"$here/25.git" "(null)" "$here/25" "(null)" \
-		"$here/25.git" "(null)" "$here/25/sub" "(null)"
+test_expect_success '#25: GIT_WORK_TREE accepted reluctantly if GIT_DIR unset (bare gitfile case)' '
+	try_repo 25 "$here/25" unset unset gitfile true \
+		"$here/25.git" "$here/25" "$here/25" "(null)"  \
+		"$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
 
 test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
@@ -721,17 +726,29 @@ test_expect_success '#27: setup' '
 '
 run_wt_tests 27 gitfile
 
-test_expect_success '#28: core.worktree ignored if GIT_DIR unset (bare gitfile case)' '
-	try_repo 28 unset unset non-existent gitfile true \
-		"$here/28.git" "(null)" "$here/28" "(null)" \
-		"$here/28.git" "(null)" "$here/28/sub" "(null)"
+test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
+	setup_repo 28 "$here/28" gitfile true &&
+	(
+		cd 28 &&
+		test_must_fail git symbolic-ref HEAD
+	) 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message &&
+	grep "core.bare and core.worktree" message
 '
 
-test_expect_success '#29: GIT_WORK_TREE+core.worktree ignored if GIT_DIR unset (bare gitfile case)' '
-	try_repo 29 non-existent-too unset non-existent gitfile true \
-		"$here/29.git" "(null)" "$here/29" "(null)" \
-		"$here/29.git" "(null)" "$here/29/sub" "(null)"
+# Case #29: GIT_WORK_TREE(+core.worktree) reluctantly overries core.bare (gitfile case).
+test_expect_success '#29: setup' '
+	setup_repo 29 non-existent gitfile true &&
+	mkdir -p 29/sub/sub 29/wt/sub
+	(
+		cd 29 &&
+		GIT_WORK_TREE="$here/29" &&
+		export GIT_WORK_TREE &&
+		git symbolic-ref HEAD >/dev/null
+	) 2>message &&
+	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
 '
+run_wt_tests 29 gitfile
 
 test_expect_success '#30: core.worktree and core.bare conflict (gitfile version)' '
 	# Just like case #22.
-- 
1.7.4.rc2

```

## Jonathan Nieder, 2011-01-19 13:05

Subject: Re: [PATCH/RFC 0/3] setup: stop ignoring GIT_WORK_TREE (when GIT_DIR is unset)
Message-ID: <20110119130524.GB22496@burratino>
URL: https://gitlist.dev/e/20110119130524.GB22496%40burratino
In-Reply-To: <20110119123732.GA23222@burratino>

```
Jonathan Nieder wrote:

>   tests: cosmetic improvements to the repo-setup test
>   tests: make the setup tests briefer
>   setup: stop ignoring GIT_WORK_TREE and core.worktree
> 
>  setup.c               |   27 +-
>  t/t1510-repo-setup.sh | 5166 +++++++------------------------------------------
>  2 files changed, 729 insertions(+), 4464 deletions(-)

It seems that the second patch was too long to send by mail.  The
series can be retrieved by git at

 git://repo.or.cz/git/jrn.git worktree-with-implicit-git-dir

Patches are based on js/test-windows to avoid semantically
uninteresting conflicts.

```

## Nguyen Thai Ngoc Duy, 2011-01-19 14:48

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <AANLkTinE5gNZM_HDJq31qs5ARJn-DrO9HW66cszTayPa@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTinE5gNZM_HDJq31qs5ARJn-DrO9HW66cszTayPa%40mail.gmail.com
In-Reply-To: <20110119124230.GD23222@burratino>

```
2011/1/19 Jonathan Nieder <jrnieder@gmail.com>:
> @@ -411,6 +411,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,
>        if (check_repository_format_gently(gitdir, nongit_ok))
>                return NULL;
>
> +       /* Accept --work-tree to support old scripts that played with fire. */
> +       if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {

Can we leave git_work_tree_cfg out? If this code is to support misused
scripts, then $GIT_WORK_TREE alone ought to be enough. I don't think
any scripts would use core.worktree. Most of worktree headache comes
from core.worktree, not $GIT_WORK_TREE. Granted though the situation
is better now that we don't set worktree in setup_git_directory().

> +               warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");

What if core.worktree is set, not $GIT_WORK_TREE? In my opinion

> +               if (offset != len && !is_absolute_path(gitdir))
> +                       gitdir = xstrdup(make_absolute_path(gitdir));

The behavior regarding relative $GIT_WORK_TREE before nd/setup series
is inconsistent. If setup_git_directory() is used, work_tree is
relative to user's cwd. In other cases, when get_git_work_tree() is
called, work_tree is made absolute relative to _current_ cwd (usually
at discovered work_tree root). Which way do you want to keep?
-- 
Duy

```

## Maaartin, 2011-01-19 18:51

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <4D373296.6030101@seznam.cz>
URL: https://gitlist.dev/e/4D373296.6030101%40seznam.cz
In-Reply-To: <20110119124230.GD23222@burratino>

```
On 11-01-19 13:42, Jonathan Nieder wrote:
> Unfortunately the existence of GIT_WORK_TREE makes it tempting to
> use without setting GIT_DIR.

Maybe I'm asking nonsense, but why should I always use both? On the
command line, I either cd to my (alternate) working tree and use GIT_DIR
only or the other way round. I used both several times when I wanted to
compare the (normal) working tree with another commit using something
better than git-diff (git-difftool didn't work for me on cygwin).

```

## Jonathan Nieder, 2011-01-19 19:03

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <20110119190304.GA30618@burratino>
URL: https://gitlist.dev/e/20110119190304.GA30618%40burratino
In-Reply-To: <20110119124230.GD23222@burratino>

```
Jonathan Nieder wrote:

> --- a/setup.c
> +++ b/setup.c
> @@ -509,8 +532,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
>  	 * validation.
>  	 */
>  	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
> -	if (gitdirenv)
> +	if (gitdirenv) {
> +		trace_printf("trace: gitdirenv = %s\n", gitdirenv);
>  		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
> +	}
>  

The above hunk is a debugging remnant.  I suppose it was foolish to
send out the series so late.  Probably not such a big deal since the
problem Maaartin mentioned remains anyway (that is, the warning is
still confusing).

-- 8< --
Subject: fixup! setup: always honor GIT_WORK_TREE and core.worktree

Remove noisy debug code.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
diff --git b/setup.c a/setup.c
index c0f5846..e08cdf2 100644
--- b/setup.c
+++ a/setup.c
@@ -532,10 +532,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 * validation.
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
-	if (gitdirenv) {
-		trace_printf("trace: gitdirenv = %s\n", gitdirenv);
+	if (gitdirenv)
 		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
-	}
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))

```

## Junio C Hamano, 2011-01-19 19:13

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7vei88u2os.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vei88u2os.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20110119124230.GD23222@burratino>

```
Jonathan Nieder <jrnieder@gmail.com> writes:

> In the usual case, git commands are run from within a git worktree.
> The toplevel directory and associated .git dir are found by chdir-ing
> to .. repeatedly until .git is a valid repository.
>
> That behavior can be overridden in two ways.

Hmm, I wouldn't call them "two ways".

We originally had GIT_DIR and people who wanted to use a working tree
without an embedded .git (hence having to use GIT_DIR) complained that
they cannot work from subdirectories while cd'ing around; GIT_WORK_TREE
was added to augment the mechanism to allow them to specify where their
root is.  Saying "two ways" sounds as if it is sane to do one without
doing the other, which is not the case here.

For the same reason (another tangent), although t1510 seems to have
complex rules about "relative to", it does not make much sense to specify
a path in GIT_WORK_TREE relative to user's $cwd.  The mechanism is to
allow people to chdir around inside their working tree that does not have
an embedded .git directory to begin with.

> diff --git a/setup.c b/setup.c
> index 3d73269..c0f5846 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -411,6 +411,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,
>  	if (check_repository_format_gently(gitdir, nongit_ok))
>  		return NULL;
>  
> +	/* Accept --work-tree to support old scripts that played with fire. */
> +	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
> +		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
> +		if (offset != len && !is_absolute_path(gitdir))
> +			gitdir = xstrdup(make_absolute_path(gitdir));
> +		if (chdir(cwd))
> +			die_errno("Could not come back to cwd");
> +		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
> +	}
> +
>  	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
>  	if (is_bare_repository_cfg > 0) {
>  		set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir));
> @@ -443,6 +453,19 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
>  	if (check_repository_format_gently(".", nongit_ok))
>  		return NULL;
>  
> +	/*
> +	 * Accept --work-tree, reluctantly.
> +	 */
> +	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
> +		const char *gitdir;
> +
> +		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
> +		gitdir = offset == len ? "." : xmemdupz(cwd, offset);
> +		if (chdir(cwd))
> +			die_errno("Could not come back to cwd");
> +		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
> +	}
> +
>  	inside_git_dir = 1;
>  	inside_work_tree = 0;
>  	if (offset != len) {

This seems to be a good workaround to resurrect the historical buggy
behaviour, but it makes the already ugly code even uglier. Can we do
something about it?

I wonder if it would make it more readable if we restructure
setup_git_directory_gently_1() slightly, perhaps by making the loop to
discover the .git directory/file into a separate helper function that
returns:

 - the path to the discovered .git;
 - if the .git was found as an ancestor of the original $cwd (to handle "bare");
 - if the discovery was aborted due to ceiling (or hitting root);

and make the caller decide what kind of setup to call outside the loop.

But that is a minor point.

```

## Junio C Hamano, 2011-01-19 19:24

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7v4o94u26f.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v4o94u26f.fsf%40alter.siamese.dyndns.org
In-Reply-To: <4D373296.6030101@seznam.cz>

```
Maaartin <grajcar1@seznam.cz> writes:

> On 11-01-19 13:42, Jonathan Nieder wrote:
>> Unfortunately the existence of GIT_WORK_TREE makes it tempting to
>> use without setting GIT_DIR.
>
> Maybe I'm asking nonsense, but why should I always use both? On the
> command line, I either cd to my (alternate) working tree and use GIT_DIR
> only or the other way round.

As long as you were at the root level of these two sets of "working trees",
you don't need GIT_WORK_TREE at all.

We originally had only GIT_DIR and people who wanted to use a working tree
without an embedded .git (hence having to use GIT_DIR) complained that
they cannot work from subdirectories while cd'ing around, because you
declare that you are at the root of your working tree by using GIT_DIR
(naturally, there is no discovery of .git so we won't know where the root
is).  GIT_WORK_TREE was added to augment the mechanism to allow them to
specify where their root is, so that they can set both and then chdir
around inside their working tree.

```

## Jonathan Nieder, 2011-01-19 19:31

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <20110119193116.GB30618@burratino>
URL: https://gitlist.dev/e/20110119193116.GB30618%40burratino
In-Reply-To: <AANLkTinE5gNZM_HDJq31qs5ARJn-DrO9HW66cszTayPa@mail.gmail.com>

```
Nguyen Thai Ngoc Duy wrote:
> 2011/1/19 Jonathan Nieder <jrnieder@gmail.com>:

>> @@ -411,6 +411,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,
>>        if (check_repository_format_gently(gitdir, nongit_ok))
>>                return NULL;
>>
>> +       /* Accept --work-tree to support old scripts that played with fire. */
>> +       if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
>
> Can we leave git_work_tree_cfg out? If this code is to support misused
> scripts, then $GIT_WORK_TREE alone ought to be enough.

Sure, it would be easy to exclude git_work_tree_cfg here.  I guess the
relevant question is

Maaartin wrote:
> On 11-01-19 13:42, Jonathan Nieder wrote:

>> Unfortunately the existence of GIT_WORK_TREE makes it tempting to
>> use without setting GIT_DIR.
>
> Maybe I'm asking nonsense, but why should I always use both?

That is, why do we want to discourage setting the work tree without
GIT_DIR in the first place?

The issues seem to be:

1. Previously there was some confusion about what path the worktree
   is relative to.  Now setup_explicit_git_dir makes it clear:
   + GIT_WORK_TREE and --work-tree are relative to the original cwd;
   + the "[core] worktree" setting is relative to the gitdir.

2. Previously there was some confusion about the right order of
   operations --- move to worktree first, or find the git dir?
   Now the setup procedure is clearly "first find git dir, then
   act on worktree".

3. A global "[core] worktree" setting with relative path is
   nonsensical since there is not necessarily a gitdir for it to be
   relative to.

4. Likewise, setting GIT_WORK_TREE when outside any git repository
   has no clear meaning.

5. The interaction with core.bare and implicit bareness are not
   obvious.  Clearly core.bare should conflict with core.worktree,
   but can GIT_WORK_TREE override that?  Maybe
   check_repository_format_gently is the right place for this check
   (rather than the setup procedure).

(1) and (2) have been resolved by your work (nice!), (3) seems like
a case of "don't do that, then", and (4) out to error out in
setup_nongit (though my patch doesn't take care of that).  Given an
answer to (5) we could wholeheartedly and consistently support
worktree with implicit gitdir, as a new feature.

Is that a fair summary?

[...]
>> +               if (offset != len && !is_absolute_path(gitdir))
>> +                       gitdir = xstrdup(make_absolute_path(gitdir));
>
> The behavior regarding relative $GIT_WORK_TREE before nd/setup series
> is inconsistent. If setup_git_directory() is used, work_tree is
> relative to user's cwd. In other cases, when get_git_work_tree() is
> called, work_tree is made absolute relative to _current_ cwd (usually
> at discovered work_tree root). Which way do you want to keep?

The former.  But this is worrisome: scripts using cd_to_toplevel are
getting the latter behavior.  Maybe a warning for relative
GIT_WORK_TREE is in order, like you hinted before.

```

## Junio C Hamano, 2011-01-19 20:17

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7vpqrssl5d.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vpqrssl5d.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20110119193116.GB30618@burratino>

```
Jonathan Nieder <jrnieder@gmail.com> writes:

> Maaartin wrote:
>> On 11-01-19 13:42, Jonathan Nieder wrote:
>
>>> Unfortunately the existence of GIT_WORK_TREE makes it tempting to
>>> use without setting GIT_DIR.
>>
>> Maybe I'm asking nonsense, but why should I always use both?
>
> That is, why do we want to discourage setting the work tree without
> GIT_DIR in the first place?

I read that one quite differently.  Maaartin was always at the root level
and did not need GIT_WORK_TREE, and in such a case there is no need to use
both.  Only GIT_DIR is needed.

    This is a tangent, because I just said what Maaartin said is
    irrelevant to the question "Why do I have to set GIT_DIR when I want
    to set GIT_WORK_TREE?", which is what you are discussing, but I
    suspect Maaartin was not getting the correct output from diff commands
    by having two sets of "working tree" looking files, chdir'ing to their
    root level and having a single GIT_DIR, and was not noticing it.  It
    should _not_ work: think "index".

The answer to your question might be your question itself, though.

Having said that, thanks for a nice summary.

> 1. Previously there was some confusion about what path the worktree
>    is relative to.  Now setup_explicit_git_dir makes it clear:
>    + GIT_WORK_TREE and --work-tree are relative to the original cwd;
>    + the "[core] worktree" setting is relative to the gitdir.

Good.  I earlier said that relative GIT_WORK_TREE does not make much
sense, but I wasn't (and I am not) opposed to the above definition.  It is
just that

	GIT_DIR=/some/where; export GIT_DIR
        cd /some/other/place
        GIT_WORK_TREE=. git reset --hard
	cd onelevel
	edit edit edit
        GIT_WORK_TREE=.. git add file
        cd twolevels
        edit edit edit
        GIT_WORK_TREE=../.. git add file
	...

would be a much more cumbersome thing to do compared to:

	GIT_WORK_TREE=/some/other/place; export GIT_WORK_TREE
        cd $(GIT_WORK_TREE)
        git reset --hard
	cd onelevel
	edit edit edit
	git add file
        cd twolevels
        edit edit edit
        git add file
	...

> 5. The interaction with core.bare and implicit bareness are not
>    obvious.  Clearly core.bare should conflict with core.worktree,
>    but can GIT_WORK_TREE override that?  Maybe
>    check_repository_format_gently is the right place for this check
>    (rather than the setup procedure).

IIRC, we on purpose added support to allow GIT_WORK_TREE to tentatively
lift bareness of a repository so that people can

	cd /var/tmp
        GIT_WORK_TREE=. git --git-dir=/srv/git/jgit.git checkout -f

to get a snapshot easily.

> (1) and (2) have been resolved by your work (nice!), (3) seems like
> a case of "don't do that, then", and (4) out to error out in
> setup_nongit (though my patch doesn't take care of that).  Given an
> answer to (5) we could wholeheartedly and consistently support
> worktree with implicit gitdir, as a new feature.

As long as we really can support it _consistently_, I wouldn't see a big
problem in resurrecting the historical accident as a feature.  You earlier
said gitolite also misuses the interface, but does the usage pattern it
has the same as the one in the debian script you had trouble with, and do
they expect the same behaviour?

```

## Maaartin, 2011-01-19 20:35

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <4D374B04.80500@seznam.cz>
URL: https://gitlist.dev/e/4D374B04.80500%40seznam.cz
In-Reply-To: <7v4o94u26f.fsf@alter.siamese.dyndns.org>

```
On 11-01-19 20:24, Junio C Hamano wrote:
> Maaartin <grajcar1@seznam.cz> writes:
> 
>> On 11-01-19 13:42, Jonathan Nieder wrote:
>>> Unfortunately the existence of GIT_WORK_TREE makes it tempting to
>>> use without setting GIT_DIR.
>>
>> Maybe I'm asking nonsense, but why should I always use both? On the
>> command line, I either cd to my (alternate) working tree and use GIT_DIR
>> only or the other way round.
> 
> As long as you were at the root level of these two sets of "working trees",
> you don't need GIT_WORK_TREE at all.

Actually I did mostly something like

git --work-tree /tmp/somewhere checkout somebranch -- .
  && winmerge . /tmp/somewhere

at root of my normal work tree as a poor man's replacement for

git difftool somebranch

This is probably no good idea as it mixes up the index. Sorry for
misusing this thread, but a side question: Should I specify
GIT_INDEX_FILE or is there a better way?

Btw., I see that GIT_INDEX_FILE is relative to the work tree instead of
to the git dir. I find it strange as it's normally a part of the git dir.

> We originally had only GIT_DIR and people who wanted to use a working tree
> without an embedded .git (hence having to use GIT_DIR) complained that
> they cannot work from subdirectories while cd'ing around, because you
> declare that you are at the root of your working tree by using GIT_DIR
> (naturally, there is no discovery of .git so we won't know where the root
> is).  GIT_WORK_TREE was added to augment the mechanism to allow them to
> specify where their root is, so that they can set both and then chdir
> around inside their working tree.

That's nice.

```

## Jonathan Nieder, 2011-01-19 20:52

Subject: checkout to other directory (Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree)
Message-ID: <20110119205257.GA31029@burratino>
URL: https://gitlist.dev/e/20110119205257.GA31029%40burratino
In-Reply-To: <4D374B04.80500@seznam.cz>

```
Maaartin wrote:

> Actually I did mostly something like
>
> git --work-tree /tmp/somewhere checkout somebranch -- .
>   && winmerge . /tmp/somewhere
>
> at root of my normal work tree as a poor man's replacement for
>
> git difftool somebranch
>
> This is probably no good idea as it mixes up the index.

Right.  I think the simplest (and usual) method is something like

	rm -fr /tmp/somewhere &&
	mkdir -p /tmp/somewhere &&
	git archive somebranch | (cd /tmp/somewhere && tar -xf -)

But suppose that the tracked tree is very big, so that re-creating
/tmp/somewhere each time is expensive.  Then you can do

	(
		GIT_DIR=$(pwd)/.git &&
		GIT_INDEX_FILE=$(pwd)/.git/somewhere-index &&
		export GIT_DIR GIT_INDEX_FILE &&

		cd /tmp/somewhere &&
		git update-index --refresh -q &&
		git read-tree --reset -m -u somebranch
	)

The state of /tmp/somewhere is remembered in the somewhere-index file.

In practice, I tend to use something closer to the following:

	sh /usr/share/doc/git/contrib/git-new-workdir repo /tmp/somewhere &&
	(
		cd /tmp/somewhere &&
		git checkout somebranch^0
	)

See [1] for caveats and future directions.

[1] http://thread.gmane.org/gmane.comp.version-control.git/150559

```

## Junio C Hamano, 2011-01-21 20:58

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7v39omotxg.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v39omotxg.fsf%40alter.siamese.dyndns.org
In-Reply-To: <7vpqrssl5d.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano <gitster@pobox.com> writes:

> Having said that, thanks for a nice summary.
> ...
>
>> 5. The interaction with core.bare and implicit bareness are not
>>    obvious.  Clearly core.bare should conflict with core.worktree,
>>    but can GIT_WORK_TREE override that?  Maybe
>>    check_repository_format_gently is the right place for this check
>>    (rather than the setup procedure).
>
> IIRC, we on purpose added support to allow GIT_WORK_TREE to tentatively
> lift bareness of a repository so that people can
>
> 	cd /var/tmp
>         GIT_WORK_TREE=. git --git-dir=/srv/git/jgit.git checkout -f
>
> to get a snapshot easily.
>
>> (1) and (2) have been resolved by your work (nice!), (3) seems like
>> a case of "don't do that, then", and (4) out to error out in
>> setup_nongit (though my patch doesn't take care of that).  Given an
>> answer to (5) we could wholeheartedly and consistently support
>> worktree with implicit gitdir, as a new feature.
>
> As long as we really can support it _consistently_, I wouldn't see a big
> problem in resurrecting the historical accident as a feature.  You earlier
> said gitolite also misuses the interface, but does the usage pattern it
> has the same as the one in the debian script you had trouble with, and do
> they expect the same behaviour?

I was re-reading this thread, and changed my mind; I think we should have
this series to avoid unnecessary regression, with or without clarifying
(5), before 1.7.4 final.

Even if some scripts you had trouble with started using GIT_WORK_TREE
without specifying GIT_DIR because they misunderstood what these are
designed to do, as long as the combination has been working consistently
with the expectation of these scripts, ans as long as we can keep the same
behaviour, I don't see a reason to change it.

```

## Junio C Hamano, 2011-01-21 22:02

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7vtyh1oqy8.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vtyh1oqy8.fsf%40alter.siamese.dyndns.org
In-Reply-To: <7v39omotxg.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano <gitster@pobox.com> writes:

> I was re-reading this thread, and changed my mind; I think we should have
> this series to avoid unnecessary regression, with or without clarifying
> (5), before 1.7.4 final.
>
> Even if some scripts you had trouble with started using GIT_WORK_TREE
> without specifying GIT_DIR because they misunderstood what these are
> designed to do, as long as the combination has been working consistently
> with the expectation of these scripts, ans as long as we can keep the same
> behaviour, I don't see a reason to change it.

... and that leads me to suggest that we may not even want to issue a
warning in these cases.

Perhaps squash this into, or apply on top of, your 3/3?

-- >8 --
Subject: setup: officially support --work-tree without --git-dir

The original intention of --work-tree was to allow people to work in a
subdirectory of their working tree that does not have an embedded .git
directory.  Because their working tree, which their $cwd was in, did not
have an embedded .git, they needed to use $GIT_DIR to specify where it is,
and because this meant there was no way to discover where the root level
of the working tree was, so we needed to add $GIT_WORK_TREE to tell git
where it was.

However, this facility has long been (mis)used by people's scripts to
start git from a working tree _with_ an embedded .git directory, let git
find .git directory, and then pretend as if an unrelated directory were
the associated working tree of the .git directory found by the discovery
process.  It happens to work in simple cases, and is not worth causing
"regression" to these scripts.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c               |    8 +-----
 t/t1510-repo-setup.sh |   59 +++++++++++++++++++++++++-----------------------
 2 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/setup.c b/setup.c
index e08cdf2..dadc666 100644
--- a/setup.c
+++ b/setup.c
@@ -411,9 +411,8 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 	if (check_repository_format_gently(gitdir, nongit_ok))
 		return NULL;
 
-	/* Accept --work-tree to support old scripts that played with fire. */
+	/* --work-tree is set without --git-dir; use discovered one */
 	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
-		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
 		if (offset != len && !is_absolute_path(gitdir))
 			gitdir = xstrdup(make_absolute_path(gitdir));
 		if (chdir(cwd))
@@ -453,13 +452,10 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
 	if (check_repository_format_gently(".", nongit_ok))
 		return NULL;
 
-	/*
-	 * Accept --work-tree, reluctantly.
-	 */
+	/* --work-tree is set without --git-dir; use discovered one */
 	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
 		const char *gitdir;
 
-		warning("pretending GIT_DIR was supplied alongside GIT_WORK_TREE");
 		gitdir = offset == len ? "." : xmemdupz(cwd, offset);
 		if (chdir(cwd))
 			die_errno("Could not come back to cwd");
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index b8a1b02..dcc0f86 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -16,9 +16,12 @@ A few rules for repo setup:
 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 meant to work if GIT_DIR is set.
-   Otherwise there is a warning and a best effort is made to follow
-   historical behavior.
+5. GIT_WORK_TREE/core.worktree was originally meant to work only if
+   GIT_DIR is set, but earlier git didn't enforce it, and some scripts
+   depend on the implementation that happened to first discover .git by
+   going up from the users $cwd and then using the specified working tree
+   that may or may not have any relation to where .git was found in.  This
+   historical behaviour must be kept.
 
 6. Effective GIT_WORK_TREE overrides core.worktree and core.bare
 
@@ -225,16 +228,16 @@ try_repo () {
 test_expect_success '#0: nonbare repo, no explicit configuration' '
 	try_repo 0 unset unset unset "" unset \
 		.git "$here/0" "$here/0" "(null)" \
-		.git "$here/0" "$here/0" sub/ 2>messages &&
-	! grep "warning:.*GIT_DIR.*GIT_WORK_TREE" messages
+		.git "$here/0" "$here/0" sub/ 2>message &&
+	! test -s message
 '
 
-test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is reluctantly accepted' '
+test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is accepted' '
 	mkdir -p wt &&
 	try_repo 1 "$here" unset unset "" unset \
 		"$here/1/.git" "$here" "$here" 1/ \
 		"$here/1/.git" "$here" "$here" 1/sub/ 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#2: worktree defaults to cwd with explicit GIT_DIR' '
@@ -255,16 +258,16 @@ test_expect_success '#3: setup' '
 '
 run_wt_tests 3
 
-test_expect_success '#4: core.worktree without GIT_DIR set is reluctantly accepted' '
+test_expect_success '#4: core.worktree without GIT_DIR set is accepted' '
 	setup_repo 4 ../sub "" unset &&
 	mkdir -p 4/sub sub &&
 	try_case 4 unset unset \
 		.git "$here/4/sub" "$here/4" "(null)" \
 		"$here/4/.git" "$here/4/sub" "$here/4/sub" "(null)" 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
-test_expect_success '#5: core.worktree + GIT_WORK_TREE is reluctantly accepted' '
+test_expect_success '#5: core.worktree + GIT_WORK_TREE is accepted' '
 	# or: you cannot intimidate away the lack of GIT_DIR setting
 	try_repo 5 "$here" unset "$here/5" "" unset \
 		"$here/5/.git" "$here" "$here" 5/ \
@@ -272,7 +275,7 @@ test_expect_success '#5: core.worktree + GIT_WORK_TREE is reluctantly accepted'
 	try_repo 5a .. unset "$here/5a" "" unset \
 		"$here/5a/.git" "$here" "$here" 5a/ \
 		"$here/5a/.git" "$here/5a" "$here/5a" sub/ &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#6: setting GIT_DIR brings core.worktree to life' '
@@ -364,12 +367,12 @@ test_expect_success '#8: gitfile, easy case' '
 		"$here/8.git" "$here/8" "$here/8" sub/
 '
 
-test_expect_success '#9: GIT_WORK_TREE reluctantly accepted with gitfile' '
+test_expect_success '#9: GIT_WORK_TREE accepted with gitfile' '
 	mkdir -p 9/wt &&
 	try_repo 9 wt unset unset gitfile unset \
 		"$here/9.git" "$here/9/wt" "$here/9" "(null)" \
 		"$here/9.git" "$here/9/sub/wt" "$here/9/sub" "(null)" 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#10: GIT_DIR can point to gitfile' '
@@ -391,19 +394,19 @@ test_expect_success '#11: setup' '
 '
 run_wt_tests 11 gitfile
 
-test_expect_success '#12: core.worktree with gitfile is reluctantly accepted' '
+test_expect_success '#12: core.worktree with gitfile is accepted' '
 	try_repo 12 unset unset "$here/12" gitfile unset \
 		"$here/12.git" "$here/12" "$here/12" "(null)" \
 		"$here/12.git" "$here/12" "$here/12" sub/ 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
-test_expect_success '#13: core.worktree+GIT_WORK_TREE relucantly accepted (with gitfile)' '
+test_expect_success '#13: core.worktree+GIT_WORK_TREE accepted (with gitfile)' '
 	# or: you cannot intimidate away the lack of GIT_DIR setting
 	try_repo 13 non-existent-too unset non-existent gitfile unset \
 		"$here/13.git" "$here/13/non-existent-too" "$here/13" "(null)" \
 		"$here/13.git" "$here/13/sub/non-existent-too" "$here/13/sub" "(null)" 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 # case #14.
@@ -514,7 +517,7 @@ test_expect_success '#16c: bare .git has no worktree' '
 		"$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
 '
 
-test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is reluctantly accepted (bare case)' '
+test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
 	# Just like #16.
 	setup_repo 17a unset "" true &&
 	setup_repo 17b unset "" true &&
@@ -539,7 +542,7 @@ test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is reluctantly
 	try_repo 17c "$here/17c" unset unset "" true \
 		.git "$here/17c" "$here/17c" "(null)" \
 		"$here/17c/.git" "$here/17c" "$here/17c" sub/ 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#18: bare .git named by GIT_DIR has no worktree' '
@@ -558,7 +561,7 @@ test_expect_success '#19: setup' '
 '
 run_wt_tests 19
 
-test_expect_success '#20a: core.worktree without GIT_DIR reluctantly accepted (inside .git)' '
+test_expect_success '#20a: core.worktree without GIT_DIR accepted (inside .git)' '
 	# Unlike case #16a.
 	setup_repo 20a "$here/20a" "" unset &&
 	mkdir -p 20a/.git/wt/sub &&
@@ -568,7 +571,7 @@ test_expect_success '#20a: core.worktree without GIT_DIR reluctantly accepted (i
 		"$here/20a/.git" "$here/20a" "$here/20a" .git/wt/ &&
 	try_case 20a/.git/wt/sub unset unset \
 		"$here/20a/.git" "$here/20a" "$here/20a" .git/wt/sub/ &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#20b/c: core.worktree and core.bare conflict' '
@@ -581,7 +584,7 @@ test_expect_success '#20b/c: core.worktree and core.bare conflict' '
 	grep "core.bare and core.worktree" message
 '
 
-# Case #21: core.worktree/GIT_WORK_TREE reluctantly overrides core.bare' '
+# Case #21: core.worktree/GIT_WORK_TREE overrides core.bare' '
 test_expect_success '#21: setup, core.worktree warns before overriding core.bare' '
 	setup_repo 21 non-existent "" unset &&
 	mkdir -p 21/.git/wt/sub &&
@@ -591,7 +594,7 @@ test_expect_success '#21: setup, core.worktree warns before overriding core.bare
 		export GIT_WORK_TREE &&
 		git symbolic-ref HEAD >/dev/null
 	) 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 
 '
 run_wt_tests 21
@@ -703,11 +706,11 @@ test_expect_success '#24: bare repo has no worktree (gitfile case)' '
 		"$here/24.git" "(null)" "$here/24/sub" "(null)"
 '
 
-test_expect_success '#25: GIT_WORK_TREE accepted reluctantly if GIT_DIR unset (bare gitfile case)' '
+test_expect_success '#25: GIT_WORK_TREE accepted if GIT_DIR unset (bare gitfile case)' '
 	try_repo 25 "$here/25" unset unset gitfile true \
 		"$here/25.git" "$here/25" "$here/25" "(null)"  \
 		"$here/25.git" "$here/25" "$here/25" "sub/" 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 
 test_expect_success '#26: bare repo has no worktree (GIT_DIR -> gitfile case)' '
@@ -732,11 +735,11 @@ test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
 		cd 28 &&
 		test_must_fail git symbolic-ref HEAD
 	) 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message &&
+	! grep "^warning:" message &&
 	grep "core.bare and core.worktree" message
 '
 
-# Case #29: GIT_WORK_TREE(+core.worktree) reluctantly overries core.bare (gitfile case).
+# Case #29: GIT_WORK_TREE(+core.worktree) overries core.bare (gitfile case).
 test_expect_success '#29: setup' '
 	setup_repo 29 non-existent gitfile true &&
 	mkdir -p 29/sub/sub 29/wt/sub
@@ -746,7 +749,7 @@ test_expect_success '#29: setup' '
 		export GIT_WORK_TREE &&
 		git symbolic-ref HEAD >/dev/null
 	) 2>message &&
-	grep "warning:.*GIT_DIR.*GIT_WORK_TREE" message
+	! test -s message
 '
 run_wt_tests 29 gitfile
 

```

## Jonathan Nieder, 2011-01-21 22:05

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <20110121220532.GA23695@burratino>
URL: https://gitlist.dev/e/20110121220532.GA23695%40burratino
In-Reply-To: <7vtyh1oqy8.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano wrote:

> Perhaps squash this into, or apply on top of, your 3/3?

Looks good to me.  I'd suggest squashing and using your commit
message for the combined commit.

```

## Junio C Hamano, 2011-01-21 23:01

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7vpqrpoo7v.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vpqrpoo7v.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20110121220532.GA23695@burratino>

```
Jonathan Nieder <jrnieder@gmail.com> writes:

> Junio C Hamano wrote:
>
>> Perhaps squash this into, or apply on top of, your 3/3?
>
> Looks good to me.  I'd suggest squashing and using your commit
> message for the combined commit.

Thanks, will do.

```

## Nguyen Thai Ngoc Duy, 2011-01-22 10:30

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <AANLkTim_o9GGWbDFkeGb-va+4dP+StQE6GJyLpSMmV1H@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTim_o9GGWbDFkeGb-va%2B4dP%2BStQE6GJyLpSMmV1H%40mail.gmail.com
In-Reply-To: <7v39omotxg.fsf@alter.siamese.dyndns.org>

```
On Sat, Jan 22, 2011 at 3:58 AM, Junio C Hamano <gitster@pobox.com> wrote:
> I was re-reading this thread, and changed my mind; I think we should have
> this series to avoid unnecessary regression, with or without clarifying
> (5), before 1.7.4 final.

Sorry for late response. If we no longer consider this work-around,
perhaps git.txt and config.txt should be updated to reflect it?
-- 
Duy

```

## Junio C Hamano, 2011-01-23 23:49

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <7vipxfmb9u.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vipxfmb9u.fsf%40alter.siamese.dyndns.org
In-Reply-To: <AANLkTim_o9GGWbDFkeGb-va+4dP+StQE6GJyLpSMmV1H@mail.gmail.com>

```
Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:

> On Sat, Jan 22, 2011 at 3:58 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> I was re-reading this thread, and changed my mind; I think we should have
>> this series to avoid unnecessary regression, with or without clarifying
>> (5), before 1.7.4 final.
>
> Sorry for late response. If we no longer consider this work-around,
> perhaps git.txt and config.txt should be updated to reflect it?

I am Ok with us considering this as a "work-around"; as long as we keep it
alive, the label does not matter much.

And the necessity of documentation updates you raised is really a good
point.  Something like this (on top of jn/setup-fixes branch queued in
next)?


 Documentation/config.txt |   23 ++++++++++++++++-------
 Documentation/git.txt    |   13 ++++---------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ff7c225..72b74c4 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -317,17 +317,26 @@ false), while all other repositories are assumed to be bare (bare
 = true).
 
 core.worktree::
-	Set the path to the working tree.  The value will not be
-	used in combination with repositories found automatically in
-	a .git directory (i.e. $GIT_DIR is not set).
+	Set the path to the root of the work tree.
 	This can be overridden by the GIT_WORK_TREE environment
 	variable and the '--work-tree' command line option. It can be
-	an absolute path or relative path to the directory specified by
-	--git-dir or GIT_DIR.
-	Note: If --git-dir or GIT_DIR are specified but none of
+	an absolute path or a relative path to the .git directory,
+	either specified by --git-dir or GIT_DIR, or automatically
+	discovered.
+	If --git-dir or GIT_DIR are specified but none of
 	--work-tree, GIT_WORK_TREE and core.worktree is specified,
-	the current working directory is regarded as the top directory
+	the current working directory is regarded as the top level
 	of your working tree.
++
+Note that this variable is honored even when set in a configuration
+file in a ".git" subdirectory of a directory, and its value differs
+from the latter directory (e.g. "/path/to/.git/config" has
+core.worktree set to "/different/path"), which is most likely a
+misconfiguration.  Running git commands in "/path/to" directory will
+still use "/different/path" as the root of the work tree and can cause
+confusion, unless you know what you are doing (e.g. you are creating a
+read-only snapshot of the same index to a location different from the
+repository's usual working tree).
 
 core.logAllRefUpdates::
 	Enable the reflog. Updates to a ref <ref> is logged to the file
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 4e5fe4d..245d84f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -291,17 +291,12 @@ help ...`.
 	path or relative path to current working directory.
 
 --work-tree=<path>::
-	Set the path to the working tree.  The value will not be
-	used in combination with repositories found automatically in
-	a .git directory (i.e. $GIT_DIR is not set).
+	Set the path to the working tree. It can be an absolute path
+	or relative path to the current working directory.
 	This can also be controlled by setting the GIT_WORK_TREE
 	environment variable and the core.worktree configuration
-	variable. It can be an absolute path or relative path to
-	current working directory.
-	Note: If --git-dir or GIT_DIR are specified but none of
-	--work-tree, GIT_WORK_TREE and core.worktree is specified,
-	the current working directory is regarded as the top directory
-	of your working tree.
+	variable (see core.worktree in linkgit:git-config[1] for a
+	more detailed discussion).
 
 --bare::
 	Treat the repository as a bare repository.  If GIT_DIR

```

## Jonathan Nieder, 2011-01-24 08:45

Subject: Re: [PATCH 3/3] setup: always honor GIT_WORK_TREE and core.worktree
Message-ID: <20110124084552.GA17348@burratino>
URL: https://gitlist.dev/e/20110124084552.GA17348%40burratino
In-Reply-To: <7vipxfmb9u.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano wrote:

> Something like this (on top of jn/setup-fixes branch queued in
> next)?

For what it's worth,
 Acked-by: Jonathan Nieder <jrnieder@gmail.com>

> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -317,17 +317,26 @@ false), while all other repositories are assumed to be bare (bare
>  = true).
>  
>  core.worktree::
> -	Set the path to the working tree.  The value will not be
> -	used in combination with repositories found automatically in
> -	a .git directory (i.e. $GIT_DIR is not set).
> +	Set the path to the root of the work tree.

Most manpages seem to stick to the phrase "working tree".  Not sure
if that's worth worrying about --- maybe it would be good to allow or
encourage usage to drift to the term "work tree" that gets used in
many parts of the interface.

>  	This can be overridden by the GIT_WORK_TREE environment
>  	variable and the '--work-tree' command line option. It can be
> +	an absolute path or a relative path to the .git directory,
> +	either specified by --git-dir or GIT_DIR, or automatically
> +	discovered.

Maybe:

	The value can be an absolute path or relative to the path to
	the .git directory, which is either specified by --git-dir or
	GIT_DIR or automatically discovered.

> -	an absolute path or relative path to the directory specified by
> -	--git-dir or GIT_DIR.
> -	Note: If --git-dir or GIT_DIR are specified but none of
> +	If --git-dir or GIT_DIR are specified but none of
>  	--work-tree, GIT_WORK_TREE and core.worktree is specified,
> -	the current working directory is regarded as the top directory
> +	the current working directory is regarded as the top level
>  	of your working tree.

Subject-verb agreement: "--git-dir or GIT_DIR is specified" (s/are/is/)

> ++
> +Note that this variable is honored even when set in a configuration
> +file in a ".git" subdirectory of a directory, and its value differs
> +from the latter directory (e.g. "/path/to/.git/config" has
> +core.worktree set to "/different/path"), which is most likely a
> +misconfiguration.

I think it's clearer without the comma between "directory" and "and"
(otherwise, it's too easy to parse as

	Note that this variable is honored even when set ....
	Its value differs from the latter directory, which is most
	likely a misconfiguration.

).

> +                   Running git commands in "/path/to" directory will
> +still use "/different/path" as the root of the work tree and can cause
> +confusion, unless you know what you are doing (e.g. you are creating a
> +read-only snapshot of the same index to a location different from the
> +repository's usual working tree).

Missing article: s,in "path/to" directory,in the "/path/to" directory,

Comma usage: s/confusion, unless/confusion unless/ to avoid misparsing
this as meaning "will use this work tree unless you know what you are
doing".

> --- a/Documentation/git.txt
> +++ b/Documentation/git.txt
> @@ -291,17 +291,12 @@ help ...`.
>  	path or relative path to current working directory.
>  
>  --work-tree=<path>::
> -	Set the path to the working tree.  The value will not be
> -	used in combination with repositories found automatically in
> -	a .git directory (i.e. $GIT_DIR is not set).
> +	Set the path to the working tree. It can be an absolute path
> +	or relative path to the current working directory.

s/relative path to/path relative to/

>  	This can also be controlled by setting the GIT_WORK_TREE
>  	environment variable and the core.worktree configuration
> +	variable (see core.worktree in linkgit:git-config[1] for a
> +	more detailed discussion).
> -	variable. It can be an absolute path or relative path to
[...]

Nice.

```

## Jonathan Nieder, 2011-01-26 00:49

Subject: [PATCH/RFC 0/3] trace: omit noisy repository discovery report
Message-ID: <20110126004915.GA11230@burratino>
URL: https://gitlist.dev/e/20110126004915.GA11230%40burratino
In-Reply-To: <1290785563-15339-2-git-send-email-pclouds@gmail.com>

```
Nguyễn Thái Ngọc Duy wrote:

> +++ b/trace.c
[...]
> +	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
> +	trace_printf("setup: worktree: %s\n", quote_crnl(get_git_work_tree()));
> +	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
> +	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
> +}

A few days ago I was tracing something or other and decided that these
extra lines are annoying.

Patch 1 moves this code from trace.c to git.c, to contain its impact
to a single translation unit (that is, it let me experiment without
touching cache.h after that).

Patch 2 removes the repo-setup tracing code, introducing a
test-repo-setup helper to take its place in the repo setup tests.

Patch 3 does some cleaning up made possible by patch 2.

Thoughts?
Jonathan Nieder (3):
  setup: do not expose tracing code
  setup: move debugging code to test-repo-setup helper
  setup: stop using GIT_TRACE in tests

 .gitignore            |    1 +
 Makefile              |    1 +
 cache.h               |    1 -
 git.c                 |    4 ----
 t/t1510-repo-setup.sh |   12 +++++-------
 test-repo-setup.c     |   32 ++++++++++++++++++++++++++++++++
 trace.c               |   49 -------------------------------------------------
 7 files changed, 39 insertions(+), 61 deletions(-)
 create mode 100644 test-repo-setup.c

-- 
1.7.4.rc3

```

## Jonathan Nieder, 2011-01-26 00:55

Subject: [PATCH 1/3] setup: do not expose tracing code
Message-ID: <20110126005530.GB11230@burratino>
URL: https://gitlist.dev/e/20110126005530.GB11230%40burratino
In-Reply-To: <20110126004915.GA11230@burratino>

```
The trace_repo_setup function has only one caller (run_builtin)
which lives in git.c.  Move the code there and stop advertising
it in cache.h.

This means it is likely to remain safe to use startup_info within
trace_repo_setup, since the trace_repo_setup function is only used
when running builtins.  Do so and drop the "prefix" parameter.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 cache.h |    1 -
 git.c   |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 trace.c |   49 -------------------------------------------------
 3 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/cache.h b/cache.h
index d83d68c..2eb3ccc 100644
--- a/cache.h
+++ b/cache.h
@@ -1067,7 +1067,6 @@ __attribute__((format (printf, 1, 2)))
 extern void trace_printf(const char *format, ...);
 __attribute__((format (printf, 2, 3)))
 extern void trace_argv_printf(const char **argv, const char *format, ...);
-extern void trace_repo_setup(const char *prefix);
 
 /* convert.c */
 /* returns 1 if *dst was used */
diff --git a/git.c b/git.c
index 68334f6..d1b15f1 100644
--- a/git.c
+++ b/git.c
@@ -238,6 +238,55 @@ static int handle_alias(int *argcp, const char ***argv)
 	return ret;
 }
 
+static const char *quote_crnl(const char *path)
+{
+	static char new_path[PATH_MAX];
+	const char *p2 = path;
+	char *p1 = new_path;
+
+	if (!path)
+		return NULL;
+
+	while (*p2) {
+		switch (*p2) {
+		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
+		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
+		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
+		default:
+			*p1++ = *p2;
+		}
+		p2++;
+	}
+	*p1 = '\0';
+	return new_path;
+}
+
+static void trace_repo_setup(void)
+{
+	const char *git_work_tree;
+	const char *prefix = startup_info->prefix;
+	char cwd[PATH_MAX];
+	char *trace = getenv("GIT_TRACE");
+
+	if (!trace || !strcmp(trace, "") ||
+	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
+		return;
+
+	if (!getcwd(cwd, PATH_MAX))
+		die("Unable to get current working directory");
+
+	if (!(git_work_tree = get_git_work_tree()))
+		git_work_tree = "(null)";
+
+	if (!prefix)
+		prefix = "(null)";
+
+	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+	trace_printf("setup: worktree: %s\n", quote_crnl(git_work_tree));
+	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
+	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
+}
+
 const char git_version_string[] = GIT_VERSION;
 
 #define RUN_SETUP		(1<<0)
@@ -278,7 +327,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 
 		if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
 		    startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
-			trace_repo_setup(prefix);
+			trace_repo_setup();
 	}
 	commit_pager_choice();
 
diff --git a/trace.c b/trace.c
index 35d388d..0fb2a2c 100644
--- a/trace.c
+++ b/trace.c
@@ -127,52 +127,3 @@ void trace_argv_printf(const char **argv, const char *fmt, ...)
 	if (need_close)
 		close(fd);
 }
-
-static const char *quote_crnl(const char *path)
-{
-	static char new_path[PATH_MAX];
-	const char *p2 = path;
-	char *p1 = new_path;
-
-	if (!path)
-		return NULL;
-
-	while (*p2) {
-		switch (*p2) {
-		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
-		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
-		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
-		default:
-			*p1++ = *p2;
-		}
-		p2++;
-	}
-	*p1 = '\0';
-	return new_path;
-}
-
-/* FIXME: move prefix to startup_info struct and get rid of this arg */
-void trace_repo_setup(const char *prefix)
-{
-	const char *git_work_tree;
-	char cwd[PATH_MAX];
-	char *trace = getenv("GIT_TRACE");
-
-	if (!trace || !strcmp(trace, "") ||
-	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
-		return;
-
-	if (!getcwd(cwd, PATH_MAX))
-		die("Unable to get current working directory");
-
-	if (!(git_work_tree = get_git_work_tree()))
-		git_work_tree = "(null)";
-
-	if (!prefix)
-		prefix = "(null)";
-
-	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
-	trace_printf("setup: worktree: %s\n", quote_crnl(git_work_tree));
-	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
-	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
-}
-- 
1.7.4.rc3

```

## Jonathan Nieder, 2011-01-26 00:59

Subject: [PATCH 2/3] trace: omit repository discovery report
Message-ID: <20110126005916.GC11230@burratino>
URL: https://gitlist.dev/e/20110126005916.GC11230%40burratino
In-Reply-To: <20110126004915.GA11230@burratino>

```
The run-command library advertises what process it is running through
the GIT_TRACE stream (see 575ba9d6, 2006-06-25) to provide context
during debugging for error messages that might come from the child
process.  In the same spirit, since v1.7.4-rc0~4^2~46 (builtins: print
setup info if repo is found, 2010-11-26) the repo-setup library prints
its result to GIT_TRACE, so the cwd, location of the git directory,
and so on are readily available during debug.

In practice, four extra lines of trace output per git process is too
much noise.  So stop printing repository discovery info except when
running tests.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 .gitignore            |    1 +
 Makefile              |    1 +
 git.c                 |   53 -------------------------------------------
 t/t1510-repo-setup.sh |    2 +-
 test-repo-setup.c     |   60 +++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 63 insertions(+), 54 deletions(-)
 create mode 100644 test-repo-setup.c

diff --git a/.gitignore b/.gitignore
index 3dd6ef7..e1fc557 100644
--- a/.gitignore
+++ b/.gitignore
@@ -173,6 +173,7 @@
 /test-obj-pool
 /test-parse-options
 /test-path-utils
+/test-repo-setup
 /test-run-command
 /test-sha1
 /test-sigchain
diff --git a/Makefile b/Makefile
index 775ee83..01cc5c0 100644
--- a/Makefile
+++ b/Makefile
@@ -427,6 +427,7 @@ TEST_PROGRAMS_NEED_X += test-match-trees
 TEST_PROGRAMS_NEED_X += test-obj-pool
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-path-utils
+TEST_PROGRAMS_NEED_X += test-repo-setup
 TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sigchain
diff --git a/git.c b/git.c
index d1b15f1..d532576 100644
--- a/git.c
+++ b/git.c
@@ -238,55 +238,6 @@ static int handle_alias(int *argcp, const char ***argv)
 	return ret;
 }
 
-static const char *quote_crnl(const char *path)
-{
-	static char new_path[PATH_MAX];
-	const char *p2 = path;
-	char *p1 = new_path;
-
-	if (!path)
-		return NULL;
-
-	while (*p2) {
-		switch (*p2) {
-		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
-		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
-		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
-		default:
-			*p1++ = *p2;
-		}
-		p2++;
-	}
-	*p1 = '\0';
-	return new_path;
-}
-
-static void trace_repo_setup(void)
-{
-	const char *git_work_tree;
-	const char *prefix = startup_info->prefix;
-	char cwd[PATH_MAX];
-	char *trace = getenv("GIT_TRACE");
-
-	if (!trace || !strcmp(trace, "") ||
-	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
-		return;
-
-	if (!getcwd(cwd, PATH_MAX))
-		die("Unable to get current working directory");
-
-	if (!(git_work_tree = get_git_work_tree()))
-		git_work_tree = "(null)";
-
-	if (!prefix)
-		prefix = "(null)";
-
-	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
-	trace_printf("setup: worktree: %s\n", quote_crnl(git_work_tree));
-	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
-	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
-}
-
 const char git_version_string[] = GIT_VERSION;
 
 #define RUN_SETUP		(1<<0)
@@ -324,10 +275,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 			use_pager = check_pager_config(p->cmd);
 		if (use_pager == -1 && p->option & USE_PAGER)
 			use_pager = 1;
-
-		if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
-		    startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
-			trace_repo_setup();
 	}
 	commit_pager_choice();
 
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 15101d5..c2edf6f 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -57,7 +57,7 @@ test_repo () {
 			export GIT_WORK_TREE
 		fi &&
 		rm -f trace &&
-		GIT_TRACE="$(pwd)/trace" git symbolic-ref HEAD >/dev/null &&
+		GIT_TRACE="$(pwd)/trace" test-repo-setup &&
 		grep '^setup: ' trace >result &&
 		test_cmp expected result
 	)
diff --git a/test-repo-setup.c b/test-repo-setup.c
new file mode 100644
index 0000000..3b66237
--- /dev/null
+++ b/test-repo-setup.c
@@ -0,0 +1,60 @@
+#include "cache.h"
+
+static const char *quote_crnl(const char *path)
+{
+	static char new_path[PATH_MAX];
+	const char *p2 = path;
+	char *p1 = new_path;
+
+	if (!path)
+		return NULL;
+
+	while (*p2) {
+		switch (*p2) {
+		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
+		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
+		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
+		default:
+			*p1++ = *p2;
+		}
+		p2++;
+	}
+	*p1 = '\0';
+	return new_path;
+}
+
+static void trace_repo_setup(void)
+{
+	const char *git_work_tree;
+	const char *prefix = startup_info->prefix;
+	char cwd[PATH_MAX];
+	char *trace = getenv("GIT_TRACE");
+
+	if (!trace || !strcmp(trace, "") ||
+	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
+		return;
+
+	if (!getcwd(cwd, PATH_MAX))
+		die("Unable to get current working directory");
+
+	if (!(git_work_tree = get_git_work_tree()))
+		git_work_tree = "(null)";
+
+	if (!prefix)
+		prefix = "(null)";
+
+	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+	trace_printf("setup: worktree: %s\n", quote_crnl(git_work_tree));
+	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
+	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
+}
+
+int main(int argc, char **argv)
+{
+	static struct startup_info test_startup_info;
+
+	startup_info = &test_startup_info;
+	setup_git_directory();
+	trace_repo_setup();
+	return 0;
+}
-- 
1.7.4.rc3

```

## Jonathan Nieder, 2011-01-26 01:01

Subject: [PATCH 3/3] tests: avoid unnecessary use of GIT_TRACE in repo-setup tests
Message-ID: <20110126010147.GD11230@burratino>
URL: https://gitlist.dev/e/20110126010147.GD11230%40burratino
In-Reply-To: <20110126004915.GA11230@burratino>

```
Now that the startup info is printed by a separate helper, there
is no need to mark that output with "setup: " or use an environment
variable to request it.

While we're changing the test-repo-setup output format, stop quoting
newlines to give the tests a chance of passing when $TEST_DIRECTORY
contains a newline or backslash.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Thanks for reading.

 t/t1510-repo-setup.sh |   12 +++++-------
 test-repo-setup.c     |   40 ++++++----------------------------------
 2 files changed, 11 insertions(+), 41 deletions(-)

diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index c2edf6f..a8cb445 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -56,9 +56,7 @@ test_repo () {
 			GIT_WORK_TREE="$3" &&
 			export GIT_WORK_TREE
 		fi &&
-		rm -f trace &&
-		GIT_TRACE="$(pwd)/trace" test-repo-setup &&
-		grep '^setup: ' trace >result &&
+		test-repo-setup >result &&
 		test_cmp expected result
 	)
 }
@@ -105,10 +103,10 @@ setup_env () {
 
 expect () {
 	cat >"$1/expected" <<-EOF
-	setup: git_dir: $2
-	setup: worktree: $3
-	setup: cwd: $4
-	setup: prefix: $5
+	git_dir: $2
+	worktree: $3
+	cwd: $4
+	prefix: $5
 	EOF
 }
 
diff --git a/test-repo-setup.c b/test-repo-setup.c
index 3b66237..72d35fe 100644
--- a/test-repo-setup.c
+++ b/test-repo-setup.c
@@ -1,52 +1,24 @@
 #include "cache.h"
 
-static const char *quote_crnl(const char *path)
-{
-	static char new_path[PATH_MAX];
-	const char *p2 = path;
-	char *p1 = new_path;
-
-	if (!path)
-		return NULL;
-
-	while (*p2) {
-		switch (*p2) {
-		case '\\': *p1++ = '\\'; *p1++ = '\\'; break;
-		case '\n': *p1++ = '\\'; *p1++ = 'n'; break;
-		case '\r': *p1++ = '\\'; *p1++ = 'r'; break;
-		default:
-			*p1++ = *p2;
-		}
-		p2++;
-	}
-	*p1 = '\0';
-	return new_path;
-}
-
 static void trace_repo_setup(void)
 {
-	const char *git_work_tree;
+	const char *git_work_tree = get_git_work_tree();
 	const char *prefix = startup_info->prefix;
 	char cwd[PATH_MAX];
-	char *trace = getenv("GIT_TRACE");
-
-	if (!trace || !strcmp(trace, "") ||
-	    !strcmp(trace, "0") || !strcasecmp(trace, "false"))
-		return;
 
 	if (!getcwd(cwd, PATH_MAX))
 		die("Unable to get current working directory");
 
-	if (!(git_work_tree = get_git_work_tree()))
+	if (!git_work_tree)
 		git_work_tree = "(null)";
 
 	if (!prefix)
 		prefix = "(null)";
 
-	trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
-	trace_printf("setup: worktree: %s\n", quote_crnl(git_work_tree));
-	trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
-	trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
+	printf("git_dir: %s\n", get_git_dir());
+	printf("worktree: %s\n", git_work_tree);
+	printf("cwd: %s\n", cwd);
+	printf("prefix: %s\n", prefix);
 }
 
 int main(int argc, char **argv)
-- 
1.7.4.rc3

```

## Sverre Rabbelier, 2011-01-26 01:19

Subject: Re: [PATCH 2/3] trace: omit repository discovery report
Message-ID: <AANLkTinyVKQOVHgdVhB3PhQOp9FbdNNHLqYny6i=_qKw@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTinyVKQOVHgdVhB3PhQOp9FbdNNHLqYny6i%3D_qKw%40mail.gmail.com
In-Reply-To: <20110126005916.GC11230@burratino>

```
Heya,

2011/1/26 Jonathan Nieder <jrnieder@gmail.com>:
> In practice, four extra lines of trace output per git process is too
> much noise.  So stop printing repository discovery info except when
> running tests.

Doesn't this disable _all_ discovery debugging aids? So doesn't this
make it more difficult to figure out what's going on in the
not-many-child case?

-- 
Cheers,

Sverre Rabbelier

```

## Nguyen Thai Ngoc Duy, 2011-01-26 01:45

Subject: Re: [PATCH/RFC 0/3] trace: omit noisy repository discovery report
Message-ID: <AANLkTimB0rJPLkwyrQEibngeRjgHLxhrntG5sMdQ9CW0@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTimB0rJPLkwyrQEibngeRjgHLxhrntG5sMdQ9CW0%40mail.gmail.com
In-Reply-To: <20110126004915.GA11230@burratino>

```
2011/1/26 Jonathan Nieder <jrnieder@gmail.com>:
> Nguyễn Thái Ngọc Duy wrote:
>
>> +++ b/trace.c
> [...]
>> +     trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir()));
>> +     trace_printf("setup: worktree: %s\n", quote_crnl(get_git_work_tree()));
>> +     trace_printf("setup: cwd: %s\n", quote_crnl(cwd));
>> +     trace_printf("setup: prefix: %s\n", quote_crnl(prefix));
>> +}
>
> A few days ago I was tracing something or other and decided that these
> extra lines are annoying.
>
> Patch 1 moves this code from trace.c to git.c, to contain its impact
> to a single translation unit (that is, it let me experiment without
> touching cache.h after that).
>
> Patch 2 removes the repo-setup tracing code, introducing a
> test-repo-setup helper to take its place in the repo setup tests.
>
> Patch 3 does some cleaning up made possible by patch 2.
>
> Thoughts?

I'm fine with this. Although long term maybe we should support pattern
matching or category selection in GIT_TRACE.
-- 
Duy

```

## Jonathan Nieder, 2011-01-26 01:46

Subject: Re: [PATCH 2/3] trace: omit repository discovery report
Message-ID: <20110126014638.GA29929@burratino>
URL: https://gitlist.dev/e/20110126014638.GA29929%40burratino
In-Reply-To: <AANLkTinyVKQOVHgdVhB3PhQOp9FbdNNHLqYny6i=_qKw@mail.gmail.com>

```
Sverre Rabbelier wrote:
> 2011/1/26 Jonathan Nieder <jrnieder@gmail.com>:

>> In practice, four extra lines of trace output per git process is too
>> much noise.  So stop printing repository discovery info except when
>> running tests.
>
> Doesn't this disable _all_ discovery debugging aids? So doesn't this
> make it more difficult to figure out what's going on in the
> not-many-child case?

Let's take the 0-child case.  With v1.7.4-rc3:

 $ GIT_TRACE=1; export GIT_TRACE
 $ git symbolic-ref confused
 setup: git_dir: .git
 setup: worktree: /home/jrn/src/git
 setup: cwd: /home/jrn/src/git
 setup: prefix: (null)
 trace: built-in: git 'symbolic-ref' 'confused'
 fatal: ref confused is not a symbolic ref

 $ git rev-parse confused >/dev/null
 trace: built-in: git 'rev-parse' 'confused'
 fatal: ambiguous argument 'confused': unknown revision or path not in the working tree.
 Use '--' to separate paths from revisions

Observations:

- Orthogonal to the useful quantity of information is that it would be
  nice if the setup info dump were consistent.  Currently non-builtins
  and commands like rev-parse without RUN_SETUP|RUN_SETUP_GENTLY skip
  it.

- Except for "cwd", the setup lines write information that is easy to
  retrieve with git rev-parse.  In my limited experience, it is not
  the information I need when debugging.

- The cwd, on the other hand, could be very useful.  Maybe git should
  make sense to always follow "trace: run_command", "trace: exec", and
  "trace: built-in" lines with "trace: cwd".

```

## Nguyen Thai Ngoc Duy, 2011-01-26 01:53

Subject: Re: [PATCH 2/3] trace: omit repository discovery report
Message-ID: <AANLkTimrRSkbzULnaQhrhA2LQSgEPH95cWFbJGsAmvC6@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTimrRSkbzULnaQhrhA2LQSgEPH95cWFbJGsAmvC6%40mail.gmail.com
In-Reply-To: <20110126005916.GC11230@burratino>

```
2011/1/26 Jonathan Nieder <jrnieder@gmail.com>:
> +int main(int argc, char **argv)
> +{
> +       static struct startup_info test_startup_info;
> +
> +       startup_info = &test_startup_info;
> +       setup_git_directory();

I think you should do _gently() here (in future maybe, because t1510
does not use it yet).
Note to self, support for testing setup_work_tree() behavior.
-- 
Duy

```

## Jeff King, 2011-01-26 05:07

Subject: Re: [PATCH/RFC 0/3] trace: omit noisy repository discovery report
Message-ID: <20110126050715.GA2665@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20110126050715.GA2665%40sigill.intra.peff.net
In-Reply-To: <AANLkTimB0rJPLkwyrQEibngeRjgHLxhrntG5sMdQ9CW0@mail.gmail.com>

```
On Wed, Jan 26, 2011 at 08:45:12AM +0700, Nguyen Thai Ngoc Duy wrote:

> > A few days ago I was tracing something or other and decided that these
> > extra lines are annoying.
> >
> > Patch 1 moves this code from trace.c to git.c, to contain its impact
> > to a single translation unit (that is, it let me experiment without
> > touching cache.h after that).
> >
> > Patch 2 removes the repo-setup tracing code, introducing a
> > test-repo-setup helper to take its place in the repo setup tests.
> >
> > Patch 3 does some cleaning up made possible by patch 2.
> >
> > Thoughts?
> 
> I'm fine with this. Although long term maybe we should support pattern
> matching or category selection in GIT_TRACE.

Yeah. I recently was peeking at the git protocol, and I wrote some
nice-ish packet-tracing support. I triggered it via:

  GIT_TRACE=$whatever GIT_TRACE_PACKET=1 git push ...

So you have to turn on tracing (to whatever destination you want) and
then turn on packet tracing with a bool. In retrospect, probably
GIT_TRACE_* should take the same type of location parameter as
GIT_TRACE, so you can get whatever subset of trace going to wherever you
like. And then the repo setup code can just go into GIT_TRACE_SETUP or
something.

-Peff

```
