diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Documentation/config.txt | 23 | ||||
-rw-r--r-- | Documentation/git-rev-parse.txt | 7 | ||||
-rw-r--r-- | Documentation/git.txt | 2 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | builtin/init-db.c | 13 | ||||
-rw-r--r-- | cache.h | 2 | ||||
-rw-r--r-- | config.c | 19 | ||||
-rw-r--r-- | environment.c | 26 | ||||
-rw-r--r-- | git.c | 4 | ||||
-rw-r--r-- | setup.c | 238 | ||||
-rwxr-xr-x | t/t0001-init.sh | 56 | ||||
-rwxr-xr-x | t/t1020-subdirectory.sh | 8 | ||||
-rwxr-xr-x | t/t1501-worktree.sh | 7 | ||||
-rwxr-xr-x | t/t1510-repo-setup.sh | 4532 | ||||
-rw-r--r-- | test-subprocess.c | 21 | ||||
-rw-r--r-- | trace.c | 42 |
17 files changed, 4868 insertions, 134 deletions
diff --git a/.gitignore b/.gitignore index 87b833c9d8..3dd6ef7d25 100644 --- a/.gitignore +++ b/.gitignore @@ -177,6 +177,7 @@ /test-sha1 /test-sigchain /test-string-pool +/test-subprocess /test-svn-fe /test-treap /common-cmds.h diff --git a/Documentation/config.txt b/Documentation/config.txt index 54597f1897..a8759cff80 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 + 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 --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 diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 4a27643c1e..ff23cb0219 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 diff --git a/Documentation/git.txt b/Documentation/git.txt index 012837145e..72e98aaa0f 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -296,7 +296,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 @@ -431,6 +431,7 @@ TEST_PROGRAMS_NEED_X += test-run-command TEST_PROGRAMS_NEED_X += test-sha1 TEST_PROGRAMS_NEED_X += test-sigchain TEST_PROGRAMS_NEED_X += test-string-pool +TEST_PROGRAMS_NEED_X += test-subprocess TEST_PROGRAMS_NEED_X += test-svn-fe TEST_PROGRAMS_NEED_X += test-treap TEST_PROGRAMS_NEED_X += test-index-version diff --git a/builtin/init-db.c b/builtin/init-db.c index 9d4886c716..e3af9eaa87 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, @@ -510,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)); @@ -987,6 +987,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 *); @@ -1066,6 +1067,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 */ @@ -852,10 +852,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. */ @@ -877,12 +876,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) @@ -891,6 +888,18 @@ int git_config(config_fn_t fn, void *data) return ret == 0 ? found : 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. */ diff --git a/environment.c b/environment.c index c79f2a9b56..9564475f42 100644 --- a/environment.c +++ b/environment.c @@ -139,30 +139,20 @@ 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"); + 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 (!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; } @@ -275,6 +275,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(); @@ -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; @@ -239,13 +221,33 @@ void setup_work_tree(void) git_dir = make_absolute_path(git_dir); if (!work_tree || chdir(work_tree)) die("This operation must be run in a work tree"); + + /* + * Make sure subsequent git processes find correct worktree + * if $GIT_WORK_TREE is set relative + */ + if (getenv(GIT_WORK_TREE_ENVIRONMENT)) + setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1); + set_git_dir(make_relative_path(git_dir, work_tree)); 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", @@ -314,64 +316,115 @@ 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 (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(nongit_ok)) - return NULL; - return retval; + + if (check_repository_format_gently(gitdirenv, nongit_ok)) { + free(gitfile); + return NULL; } - if (check_repository_format_gently(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; -} + } -static int cwd_contains_git_dir(const char **gitfile_dirp) -{ - 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 (!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; } - return is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT); + + /* cwd outside worktree */ + set_git_dir(gitdirenv); + free(gitfile); + return NULL; } -static const char *setup_discovered_git_dir(const char *work_tree_env, - int offset, int len, char *cwd, int *nongit_ok) +static const char *setup_discovered_git_dir(const char *gitdir, + char *cwd, int offset, int len, + int *nongit_ok) { - int root_len; + if (check_repository_format_gently(gitdir, nongit_ok)) + return NULL; - 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); - if (check_repository_format_gently(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)); + 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; + inside_work_tree = 1; if (offset == len) return NULL; @@ -382,23 +435,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); - } else + } + else set_git_dir("."); - check_repository_format_gently(nongit_ok); return NULL; } @@ -428,11 +483,10 @@ 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; - const char *gitfile_dir; + const char *gitdirenv, *ret; + char *gitfile; int len, offset, ceil_offset; dev_t current_device = 0; int one_filesystem = 1; @@ -445,6 +499,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 @@ -452,10 +510,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)) @@ -472,17 +527,30 @@ 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); for (;;) { - if (cwd_contains_git_dir(&gitfile_dir)) - return setup_discovered_git_dir(work_tree_env, 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(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); @@ -592,7 +660,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); } /* @@ -603,19 +671,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 (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/t0001-init.sh b/t/t0001-init.sh index d44194c35f..af8b9c52a9 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 ( sane_unset GIT_DIR && diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index a3ac33801a..1fd187c5eb 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -110,6 +110,14 @@ test_expect_success 'read-tree' ' ) ' +test_expect_success 'alias expansion' ' + ( + git config alias.ss status && + cd dir && + git status && + git ss + ) +' test_expect_success 'no file/rev ambiguity check inside .git' ' git commit -a -m 1 && ( diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 2c8f01f668..f072a8ed48 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -340,4 +340,11 @@ test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file ' +test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \ + test-subprocess --setup-work-tree rev-parse --show-toplevel >actual && + echo "$TRASH_DIRECTORY/repo.git/work" >expected && + test_cmp expected actual +' + test_done diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh new file mode 100755 index 0000000000..500ffafc22 --- /dev/null +++ b/t/t1510-repo-setup.sh @@ -0,0 +1,4532 @@ +#!/bin/sh + +test_description='Tests of cwd/prefix/worktree/gitdir setup in all cases' + +. ./test-lib.sh + +# +# A few rules for repo setup: +# +# 1. GIT_DIR is relative to user's cwd. --git-dir is equivalent to +# GIT_DIR. +# +# 2. .git file is relative to parent directory. .git file is basically +# symlink in disguise. The directory where .git file points to will +# become new git_dir. +# +# 3. core.worktree is relative to git_dir. +# +# 4. GIT_WORK_TREE is relative to user's cwd. --work-tree is +# equivalent to GIT_WORK_TREE. +# +# 5. GIT_WORK_TREE/core.worktree is only effective if GIT_DIR is set +# Uneffective worktree settings should be warned. +# +# 6. Effective GIT_WORK_TREE overrides core.worktree and core.bare +# +# 7. Effective core.worktree conflicts with core.bare +# +# 8. If GIT_DIR is set but neither worktree nor bare setting is given, +# original cwd becomes worktree. +# +# 9. If .git discovery is done inside a repo, the repo becomes a bare +# repo. .git discovery is performed if GIT_DIR is not set. +# +# 10. If no worktree is available, cwd remains unchanged, prefix is +# NULL. +# +# 11. When user's cwd is outside worktree, cwd remains unchanged, +# prefix is NULL. +# + +test_repo() { + ( + cd "$1" && + if test -n "$2"; then GIT_DIR="$2" && export GIT_DIR; fi && + if test -n "$3"; then GIT_WORK_TREE="$3" && export GIT_WORK_TREE; fi && + rm -f trace && + GIT_TRACE="`pwd`/trace" git symbolic-ref HEAD >/dev/null && + grep '^setup: ' trace >result && + test_cmp expected result + ) +} + +# Bit 0 = GIT_WORK_TREE +# Bit 1 = GIT_DIR +# Bit 2 = core.worktree +# Bit 3 = .git is a file +# Bit 4 = bare repo +# Case# = encoding of the above 5 bits + +# +# Case #0 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# - worktree is .git's parent directory +# - cwd is at worktree root dir +# - prefix is calculated +# - git_dir is set to ".git" +# - cwd can't be outside worktree + +test_expect_success '#0: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 0 0/sub && + cd 0 && git init && cd .. +' + +test_expect_success '#0: at root' ' + cat >0/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/0 +setup: cwd: $TRASH_DIRECTORY/0 +setup: prefix: (null) +EOF + test_repo 0 +' + +test_expect_success '#0: in subdir' ' + cat >0/sub/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/0 +setup: cwd: $TRASH_DIRECTORY/0 +setup: prefix: sub/ +EOF + test_repo 0/sub +' + +# +# case #1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# GIT_WORK_TREE is ignored -> #0 + +test_expect_success '#1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 1 1/sub 1.wt 1.wt/sub 1/wt 1/wt/sub && + cd 1 && + git init && + GIT_WORK_TREE=non-existent && + export GIT_WORK_TREE && + cd .. +' + +test_expect_success '#1: at root' ' + cat >1/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/1 +setup: cwd: $TRASH_DIRECTORY/1 +setup: prefix: (null) +EOF + test_repo 1 +' + +test_expect_success '#1: in subdir' ' + cat >1/sub/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/1 +setup: cwd: $TRASH_DIRECTORY/1 +setup: prefix: sub/ +EOF + test_repo 1/sub +' + +# +# case #2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# - worktree is at original cwd +# - cwd is unchanged +# - prefix is NULL +# - git_dir is set to $GIT_DIR +# - cwd can't be outside worktree + +test_expect_success '#2: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 2 2/sub && + cd 2 && git init && cd .. +' + +test_expect_success '#2: at root' ' + cat >2/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/2/.git +setup: worktree: $TRASH_DIRECTORY/2 +setup: cwd: $TRASH_DIRECTORY/2 +setup: prefix: (null) +EOF + test_repo 2 "$TRASH_DIRECTORY/2/.git" +' + +test_expect_success '#2: in subdir' ' + cat >2/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/2/.git +setup: worktree: $TRASH_DIRECTORY/2/sub +setup: cwd: $TRASH_DIRECTORY/2/sub +setup: prefix: (null) +EOF + test_repo 2/sub "$TRASH_DIRECTORY/2/.git" +' + +test_expect_success '#2: relative GIT_DIR at root' ' + cat >2/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/2 +setup: cwd: $TRASH_DIRECTORY/2 +setup: prefix: (null) +EOF + test_repo 2 .git +' + +test_expect_success '#2: relative GIT_DIR in subdir' ' + cat >2/sub/expected <<EOF && +setup: git_dir: ../.git +setup: worktree: $TRASH_DIRECTORY/2/sub +setup: cwd: $TRASH_DIRECTORY/2/sub +setup: prefix: (null) +EOF + test_repo 2/sub ../.git +' + +# +# case #3 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# - worktree is set to $GIT_WORK_TREE +# - cwd is at worktree root +# - prefix is calculated +# - git_dir is set to $GIT_DIR +# - cwd can be outside worktree + +test_expect_success '#3: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 3 3/sub 3/sub/sub 3.wt 3.wt/sub 3/wt 3/wt/sub && + cd 3 && git init && cd .. +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >3/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 .git "$TRASH_DIRECTORY/3" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 .git . +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3" +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" . +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: sub/sub/ +EOF + test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY/3" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: sub/sub/ +EOF + test_repo 3/sub/sub ../../.git ../.. +' + +test_expect_success '#3: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >3/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: sub/ +EOF + test_repo 3/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3" +' + +test_expect_success '#3: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3 +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: sub/sub/ +EOF + test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../.. +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >3/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 .git "$TRASH_DIRECTORY/3/wt" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 .git wt +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" wt +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3 +setup: prefix: (null) +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3/wt" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3/sub/sub +setup: prefix: (null) +EOF + test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY/3/wt" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3/sub/sub +setup: prefix: (null) +EOF + test_repo 3/sub/sub ../../.git ../../wt +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3/sub/sub +setup: prefix: (null) +EOF + test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../../wt +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY/3/wt +setup: cwd: $TRASH_DIRECTORY/3/sub/sub +setup: prefix: (null) +EOF + test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY/3/wt" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/ +EOF + test_repo 3 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/ +EOF + test_repo 3 .git .. +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/ +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" .. +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >3/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/ +EOF + test_repo 3 "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/sub/sub/ +EOF + test_repo 3/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#3: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/sub/sub/ +EOF + test_repo 3/sub/sub ../../.git ../../.. +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/sub/sub/ +EOF + test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" ../../../ +' + +test_expect_success '#3: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >3/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/3/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 3/sub/sub/ +EOF + test_repo 3/sub/sub "$TRASH_DIRECTORY/3/.git" "$TRASH_DIRECTORY" +' + +# +# case #4 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# core.worktree is ignored -> #0 + +test_expect_success '#4: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 4 4/sub && + cd 4 && + git init && + git config core.worktree non-existent && + cd .. +' + +test_expect_success '#4: at root' ' + cat >4/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/4 +setup: cwd: $TRASH_DIRECTORY/4 +setup: prefix: (null) +EOF + test_repo 4 +' + +test_expect_success '#4: in subdir' ' + cat >4/sub/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/4 +setup: cwd: $TRASH_DIRECTORY/4 +setup: prefix: sub/ +EOF + test_repo 4/sub +' + +# +# case #5 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# GIT_WORK_TREE/core.worktree are ignored -> #0 + +test_expect_success '#5: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 5 5/sub && + cd 5 && + git init && + git config core.worktree non-existent && + GIT_WORK_TREE=non-existent-too && + export GIT_WORK_TREE && + cd .. +' + +test_expect_success '#5: at root' ' + cat >5/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/5 +setup: cwd: $TRASH_DIRECTORY/5 +setup: prefix: (null) +EOF + test_repo 5 +' + +test_expect_success '#5: in subdir' ' + cat >5/sub/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/5 +setup: cwd: $TRASH_DIRECTORY/5 +setup: prefix: sub/ +EOF + test_repo 5/sub +' + +# +# case #6 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# - worktree is at core.worktree +# - cwd is at worktree root +# - prefix is calculated +# - git_dir is at $GIT_DIR +# - cwd can be outside worktree + +test_expect_success '#6: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 6 6/sub 6/sub/sub 6.wt 6.wt/sub 6/wt 6/wt/sub && + cd 6 && git init && cd .. +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=.. at root' ' + cat >6/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=..(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR, core.worktree=.. at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=..(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=.. in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=..(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR, core.worktree=.. in subdir' ' + cat >6/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6" && + test_repo 6/sub "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=..(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6 +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree .. && + test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt at root' ' + cat >6/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR, core.worktree=../wt(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=../wt at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../wt(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR, core.worktree=../wt(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../wt && + test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=../wt in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY/6/wt +setup: cwd: $TRASH_DIRECTORY/6/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY/6/wt" && + test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../.. at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../..(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../../ && + test_repo 6 .git +' + +test_expect_success '#6: GIT_DIR, core.worktree=../..(rel) at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../../ && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=../.. at root' ' + cat >6/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 6 "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../.. in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR(rel), core.worktree=../..(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../.. && + test_repo 6/sub/sub ../../.git +' + +test_expect_success '#6: GIT_DIR, core.worktree=../..(rel) in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree ../.. && + test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git" +' + +test_expect_success '#6: GIT_DIR, core.worktree=../.. in subdir' ' + cat >6/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/6/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 6/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/6/.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 6/sub/sub "$TRASH_DIRECTORY/6/.git" +' + +# +# case #7 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a directory +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# core.worktree is overridden by GIT_WORK_TREE -> #3 + +test_expect_success '#7: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 7 7/sub 7/sub/sub 7.wt 7.wt/sub 7/wt 7/wt/sub && + cd 7 && + git init && + git config core.worktree non-existent && + cd .. +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >7/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 .git "$TRASH_DIRECTORY/7" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 .git . +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7" +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" . +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: sub/sub/ +EOF + test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY/7" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: sub/sub/ +EOF + test_repo 7/sub/sub ../../.git ../.. +' + +test_expect_success '#7: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >7/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: sub/ +EOF + test_repo 7/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7" +' + +test_expect_success '#7: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7 +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: sub/sub/ +EOF + test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../.. +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >7/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 .git "$TRASH_DIRECTORY/7/wt" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 .git wt +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" wt +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7 +setup: prefix: (null) +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7/wt" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7/sub/sub +setup: prefix: (null) +EOF + test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY/7/wt" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7/sub/sub +setup: prefix: (null) +EOF + test_repo 7/sub/sub ../../.git ../../wt +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7/sub/sub +setup: prefix: (null) +EOF + test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../../wt +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY/7/wt +setup: cwd: $TRASH_DIRECTORY/7/sub/sub +setup: prefix: (null) +EOF + test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY/7/wt" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/ +EOF + test_repo 7 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/ +EOF + test_repo 7 .git .. +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/ +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" .. +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >7/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/ +EOF + test_repo 7 "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/sub/sub/ +EOF + test_repo 7/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#7: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/sub/sub/ +EOF + test_repo 7/sub/sub ../../.git ../../.. +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/sub/sub/ +EOF + test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" ../../../ +' + +test_expect_success '#7: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >7/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/7/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 7/sub/sub/ +EOF + test_repo 7/sub/sub "$TRASH_DIRECTORY/7/.git" "$TRASH_DIRECTORY" +' + +# +# case #8 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #0 except that git_dir is set by .git file + +test_expect_success '#8: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 8 8/sub && + cd 8 && + git init && + mv .git ../8.git && + echo gitdir: ../8.git >.git && + cd .. +' + +test_expect_success '#8: at root' ' + cat >8/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/8.git +setup: worktree: $TRASH_DIRECTORY/8 +setup: cwd: $TRASH_DIRECTORY/8 +setup: prefix: (null) +EOF + test_repo 8 +' + +test_expect_success '#8: in subdir' ' + cat >8/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/8.git +setup: worktree: $TRASH_DIRECTORY/8 +setup: cwd: $TRASH_DIRECTORY/8 +setup: prefix: sub/ +EOF + test_repo 8/sub +' + +# +# case #9 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #1 except that git_dir is set by .git file + +test_expect_success '#9: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 9 9/sub 9.wt 9.wt/sub 9/wt 9/wt/sub && + cd 9 && + git init && + mv .git ../9.git && + echo gitdir: ../9.git >.git && + GIT_WORK_TREE=non-existent && + export GIT_WORK_TREE && + cd .. +' + +test_expect_success '#9: at root' ' + cat >9/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/9.git +setup: worktree: $TRASH_DIRECTORY/9 +setup: cwd: $TRASH_DIRECTORY/9 +setup: prefix: (null) +EOF + test_repo 9 +' + +test_expect_success '#9: in subdir' ' + cat >9/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/9.git +setup: worktree: $TRASH_DIRECTORY/9 +setup: cwd: $TRASH_DIRECTORY/9 +setup: prefix: sub/ +EOF + test_repo 9/sub +' + +# +# case #10 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #2 except that git_dir is set by .git file + +test_expect_success '#10: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 10 10/sub && + cd 10 && + git init && + mv .git ../10.git && + echo gitdir: ../10.git >.git && + cd .. +' + +test_expect_success '#10: at root' ' + cat >10/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/10.git +setup: worktree: $TRASH_DIRECTORY/10 +setup: cwd: $TRASH_DIRECTORY/10 +setup: prefix: (null) +EOF + test_repo 10 "$TRASH_DIRECTORY/10/.git" +' + +test_expect_success '#10: in subdir' ' + cat >10/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/10.git +setup: worktree: $TRASH_DIRECTORY/10/sub +setup: cwd: $TRASH_DIRECTORY/10/sub +setup: prefix: (null) +EOF + test_repo 10/sub "$TRASH_DIRECTORY/10/.git" +' + +test_expect_success '#10: relative GIT_DIR at root' ' + cat >10/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/10.git +setup: worktree: $TRASH_DIRECTORY/10 +setup: cwd: $TRASH_DIRECTORY/10 +setup: prefix: (null) +EOF + test_repo 10 .git +' + +test_expect_success '#10: relative GIT_DIR in subdir' ' + cat >10/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/10.git +setup: worktree: $TRASH_DIRECTORY/10/sub +setup: cwd: $TRASH_DIRECTORY/10/sub +setup: prefix: (null) +EOF + test_repo 10/sub ../.git +' + +# +# case #11 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #3 except that git_dir is set by .git file + +test_expect_success '#11: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 11 11/sub 11/sub/sub 11.wt 11.wt/sub 11/wt 11/wt/sub && + cd 11 && + git init && + mv .git ../11.git && + echo gitdir: ../11.git >.git && + cd .. +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 .git "$TRASH_DIRECTORY/11" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 .git . +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11" +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" . +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: sub/sub/ +EOF + test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: sub/sub/ +EOF + test_repo 11/sub/sub ../../.git ../.. +' + +test_expect_success '#11: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >11/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: sub/ +EOF + test_repo 11/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11" +' + +test_expect_success '#11: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11 +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: sub/sub/ +EOF + test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../.. +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 .git "$TRASH_DIRECTORY/11/wt" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 .git wt +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" wt +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11 +setup: prefix: (null) +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11/sub/sub +setup: prefix: (null) +EOF + test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY/11/wt" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11/sub/sub +setup: prefix: (null) +EOF + test_repo 11/sub/sub ../../.git ../../wt +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11/sub/sub +setup: prefix: (null) +EOF + test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../wt +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY/11/wt +setup: cwd: $TRASH_DIRECTORY/11/sub/sub +setup: prefix: (null) +EOF + test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY/11/wt" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/ +EOF + test_repo 11 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/ +EOF + test_repo 11 .git .. +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/ +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" .. +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >11/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/ +EOF + test_repo 11 "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/sub/sub/ +EOF + test_repo 11/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#11: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/sub/sub/ +EOF + test_repo 11/sub/sub ../../.git ../../.. +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/sub/sub/ +EOF + test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" ../../../ +' + +test_expect_success '#11: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >11/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/11.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 11/sub/sub/ +EOF + test_repo 11/sub/sub "$TRASH_DIRECTORY/11/.git" "$TRASH_DIRECTORY" +' + +# +# case #12 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #4 except that git_dir is set by .git file + + +test_expect_success '#12: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 12 12/sub 12/sub/sub 12.wt 12.wt/sub 12/wt 12/wt/sub && + cd 12 && + git init && + git config core.worktree non-existent && + mv .git ../12.git && + echo gitdir: ../12.git >.git && + cd .. +' + +test_expect_success '#12: at root' ' + cat >12/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/12.git +setup: worktree: $TRASH_DIRECTORY/12 +setup: cwd: $TRASH_DIRECTORY/12 +setup: prefix: (null) +EOF + test_repo 12 +' + +test_expect_success '#12: in subdir' ' + cat >12/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/12.git +setup: worktree: $TRASH_DIRECTORY/12 +setup: cwd: $TRASH_DIRECTORY/12 +setup: prefix: sub/ +EOF + test_repo 12/sub +' + +# +# case #13 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #5 except that git_dir is set by .git file + +test_expect_success '#13: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 13 13/sub 13/sub/sub 13.wt 13.wt/sub 13/wt 13/wt/sub && + cd 13 && + git init && + git config core.worktree non-existent && + GIT_WORK_TREE=non-existent-too && + export GIT_WORK_TREE && + mv .git ../13.git && + echo gitdir: ../13.git >.git && + cd .. +' + +test_expect_success '#13: at root' ' + cat >13/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/13.git +setup: worktree: $TRASH_DIRECTORY/13 +setup: cwd: $TRASH_DIRECTORY/13 +setup: prefix: (null) +EOF + test_repo 13 +' + +test_expect_success '#13: in subdir' ' + cat >13/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/13.git +setup: worktree: $TRASH_DIRECTORY/13 +setup: cwd: $TRASH_DIRECTORY/13 +setup: prefix: sub/ +EOF + test_repo 13/sub +' + +# +# case #14 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #6 except that git_dir is set by .git file + +test_expect_success '#14: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 14 14/sub 14/sub/sub 14.wt 14.wt/sub 14/wt 14/wt/sub && + cd 14 && + git init && + mv .git ../14.git && + echo gitdir: ../14.git >.git && + cd .. +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14 at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14 at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14 in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14 in subdir' ' + cat >14/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14" && + test_repo 14/sub "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14 +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14 && + test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14/wt(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14/wt at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14 +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=../14/wt(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14/wt(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree ../14/wt && + test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=../14/wt in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY/14/wt +setup: cwd: $TRASH_DIRECTORY/14/sub/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY/14/wt" && + test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=.. at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=..(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. && + test_repo 14 .git +' + +test_expect_success '#14: GIT_DIR, core.worktree=..(rel) at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=.. at root' ' + cat >14/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 14 "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=.. in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR(rel), core.worktree=..(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. && + test_repo 14/sub/sub ../../.git +' + +test_expect_success '#14: GIT_DIR, core.worktree=..(rel) in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree .. && + test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git" +' + +test_expect_success '#14: GIT_DIR, core.worktree=.. in subdir' ' + cat >14/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/14.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 14/sub/sub/ +EOF + git config --file="$TRASH_DIRECTORY/14.git/config" core.worktree "$TRASH_DIRECTORY" && + test_repo 14/sub/sub "$TRASH_DIRECTORY/14/.git" +' + +# +# case #15 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a file +# - core.bare is not set, cwd is outside .git +# +# Output: +# +# #7 except that git_dir is set by .git file + +test_expect_success '#15: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 15 15/sub 15/sub/sub 15.wt 15.wt/sub 15/wt 15/wt/sub && + cd 15 && + git init && + git config core.worktree non-existent && + mv .git ../15.git && + echo gitdir: ../15.git >.git && + cd .. +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 .git "$TRASH_DIRECTORY/15" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 .git . +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15" +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" . +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: sub/sub/ +EOF + test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: sub/sub/ +EOF + test_repo 15/sub/sub ../../.git ../.. +' + +test_expect_success '#15: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >15/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: sub/ +EOF + test_repo 15/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15" +' + +test_expect_success '#15: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15 +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: sub/sub/ +EOF + test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../.. +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 .git "$TRASH_DIRECTORY/15/wt" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 .git wt +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" wt +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15 +setup: prefix: (null) +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15/sub/sub +setup: prefix: (null) +EOF + test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY/15/wt" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15/sub/sub +setup: prefix: (null) +EOF + test_repo 15/sub/sub ../../.git ../../wt +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15/sub/sub +setup: prefix: (null) +EOF + test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../wt +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY/15/wt +setup: cwd: $TRASH_DIRECTORY/15/sub/sub +setup: prefix: (null) +EOF + test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY/15/wt" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/ +EOF + test_repo 15 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/ +EOF + test_repo 15 .git .. +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/ +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" .. +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >15/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/ +EOF + test_repo 15 "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/sub/sub/ +EOF + test_repo 15/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#15: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/sub/sub/ +EOF + test_repo 15/sub/sub ../../.git ../../.. +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/sub/sub/ +EOF + test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" ../../../ +' + +test_expect_success '#15: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >15/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/15.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 15/sub/sub/ +EOF + test_repo 15/sub/sub "$TRASH_DIRECTORY/15/.git" "$TRASH_DIRECTORY" +' + +# +# case #16.1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - cwd is inside .git +# +# Output: +# +# - no worktree +# - cwd is unchanged +# - prefix is NULL +# - git_dir is set +# - cwd can't be outside worktree + +test_expect_success '#16.1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 16 16/sub && + cd 16 && + git init && + mkdir .git/wt .git/wt/sub && + cd .. +' + +test_expect_success '#16.1: at .git' ' + cat >16/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git +setup: prefix: (null) +EOF + test_repo 16/.git +' + +test_expect_success '#16.1: in .git/wt' ' + cat >16/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/16/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git/wt +setup: prefix: (null) +EOF + test_repo 16/.git/wt +' + +test_expect_success '#16.1: in .git/wt/sub' ' + cat >16/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/16/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 16/.git/wt/sub +' + +# +# case #16.2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# - no worktree +# - cwd is unchanged +# - prefix is NULL +# - git_dir is set +# - cwd can't be outside worktree + +test_expect_success '#16.2: setup' ' + git config --file="$TRASH_DIRECTORY/16/.git/config" core.bare true +' + +test_expect_success '#16.2: at .git' ' + cat >16/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git +setup: prefix: (null) +EOF + test_repo 16/.git +' + +test_expect_success '#16.2: in .git/wt' ' + cat >16/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/16/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git/wt +setup: prefix: (null) +EOF + test_repo 16/.git/wt +' + +test_expect_success '#16.2: in .git/wt/sub' ' + cat >16/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/16/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 16/.git/wt/sub +' + +test_expect_success '#16.2: at root' ' + cat >16/expected <<EOF && +setup: git_dir: .git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16 +setup: prefix: (null) +EOF + test_repo 16 +' + +test_expect_success '#16.2: in subdir' ' + cat >16/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/16/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/16/sub +setup: prefix: (null) +EOF + test_repo 16/sub +' + +# +# case #17.1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - cwd is inside .git +# +# Output: +# +# GIT_WORK_TREE is ignored -> #16.1 (with warnings perhaps) + +test_expect_success '#17.1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 17 17/sub && + cd 17 && + git init && + mkdir .git/wt .git/wt/sub && + GIT_WORK_TREE=non-existent && + export GIT_WORK_TREE && + cd .. +' + +test_expect_success '#17.1: at .git' ' + cat >17/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git +setup: prefix: (null) +EOF + test_repo 17/.git +' + +test_expect_success '#17.1: in .git/wt' ' + cat >17/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/17/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git/wt +setup: prefix: (null) +EOF + test_repo 17/.git/wt +' + +test_expect_success '#17.1: in .git/wt/sub' ' + cat >17/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/17/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 17/.git/wt/sub +' + +# +# case #17.2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# GIT_WORK_TREE is ignored -> #16.2 (with warnings perhaps) + +test_expect_success '#17.2: setup' ' + git config --file="$TRASH_DIRECTORY/17/.git/config" core.bare true +' + +test_expect_success '#17.2: at .git' ' + cat >17/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git +setup: prefix: (null) +EOF + test_repo 17/.git +' + +test_expect_success '#17.2: in .git/wt' ' + cat >17/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/17/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git/wt +setup: prefix: (null) +EOF + test_repo 17/.git/wt +' + +test_expect_success '#17.2: in .git/wt/sub' ' + cat >17/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/17/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 17/.git/wt/sub +' + +test_expect_success '#17.2: at root' ' + cat >17/expected <<EOF && +setup: git_dir: .git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17 +setup: prefix: (null) +EOF + test_repo 17 +' + +test_expect_success '#17.2: in subdir' ' + cat >17/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/17/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/17/sub +setup: prefix: (null) +EOF + test_repo 17/sub +' + +# +# case #18 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# - no worktree (rule #8) +# - cwd is unchanged +# - prefix is NULL +# - git_dir is set to $GIT_DIR +# - cwd can't be outside worktree + +test_expect_success '#18: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 18 18/sub && + cd 18 && + git init && + mkdir .git/wt .git/wt/sub && + git config core.bare true && + cd .. +' + +test_expect_success '#18: (rel) at root' ' + cat >18/expected <<EOF && +setup: git_dir: .git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/18 +setup: prefix: (null) +EOF + test_repo 18 .git +' + +test_expect_success '#18: at root' ' + cat >18/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/18/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/18 +setup: prefix: (null) +EOF + test_repo 18 "$TRASH_DIRECTORY/18/.git" +' + +test_expect_success '#18: (rel) in subdir' ' + cat >18/sub/expected <<EOF && +setup: git_dir: ../.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/18/sub +setup: prefix: (null) +EOF + test_repo 18/sub ../.git +' + +test_expect_success '#18: in subdir' ' + cat >18/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/18/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/18/sub +setup: prefix: (null) +EOF + test_repo 18/sub "$TRASH_DIRECTORY/18/.git" +' + +# +# case #19 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - .git is a directory +# - core.worktree is not set +# - core.bare is set +# +# Output: +# +# bare repo is overridden by GIT_WORK_TREE -> #3 + +test_expect_success '#19: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 19 19/sub 19/sub/sub 19.wt 19.wt/sub 19/wt 19/wt/sub && + cd 19 && + git init && + git config core.bare true && + cd .. +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >19/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 .git "$TRASH_DIRECTORY/19" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 .git . +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19" +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" . +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: sub/sub/ +EOF + test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY/19" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: sub/sub/ +EOF + test_repo 19/sub/sub ../../.git ../.. +' + +test_expect_success '#19: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >19/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: sub/ +EOF + test_repo 19/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19" +' + +test_expect_success '#19: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19 +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: sub/sub/ +EOF + test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../.. +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >19/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 .git "$TRASH_DIRECTORY/19/wt" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 .git wt +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" wt +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19 +setup: prefix: (null) +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19/wt" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19/sub/sub +setup: prefix: (null) +EOF + test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY/19/wt" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19/sub/sub +setup: prefix: (null) +EOF + test_repo 19/sub/sub ../../.git ../../wt +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19/sub/sub +setup: prefix: (null) +EOF + test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../../wt +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY/19/wt +setup: cwd: $TRASH_DIRECTORY/19/sub/sub +setup: prefix: (null) +EOF + test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY/19/wt" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/ +EOF + test_repo 19 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/ +EOF + test_repo 19 .git .. +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/ +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" .. +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >19/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/ +EOF + test_repo 19 "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/sub/sub/ +EOF + test_repo 19/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#19: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/sub/sub/ +EOF + test_repo 19/sub/sub ../../.git ../../.. +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/sub/sub/ +EOF + test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" ../../../ +' + +test_expect_success '#19: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >19/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/19/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 19/sub/sub/ +EOF + test_repo 19/sub/sub "$TRASH_DIRECTORY/19/.git" "$TRASH_DIRECTORY" +' + +# +# case #20.1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - cwd is inside .git +# +# Output: +# +# core.worktree is ignored -> #16.1 + +test_expect_success '#20.1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 20 20/sub && + cd 20 && + git init && + git config core.worktree non-existent && + mkdir .git/wt .git/wt/sub && + cd .. +' + +test_expect_success '#20.1: at .git' ' + cat >20/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git +setup: prefix: (null) +EOF + test_repo 20/.git +' + +test_expect_success '#20.1: in .git/wt' ' + cat >20/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/20/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git/wt +setup: prefix: (null) +EOF + test_repo 20/.git/wt +' + +test_expect_success '#20.1: in .git/wt/sub' ' + cat >20/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/20/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 20/.git/wt/sub +' + +# +# case #20.2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# core.worktree is ignored -> #16.2 + +test_expect_success '#20.2: setup' ' + git config --file="$TRASH_DIRECTORY/20/.git/config" core.bare true +' + +test_expect_success '#20.2: at .git' ' + cat >20/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git +setup: prefix: (null) +EOF + test_repo 20/.git +' + +test_expect_success '#20.2: in .git/wt' ' + cat >20/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/20/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git/wt +setup: prefix: (null) +EOF + test_repo 20/.git/wt +' + +test_expect_success '#20.2: in .git/wt/sub' ' + cat >20/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/20/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 20/.git/wt/sub +' + +test_expect_success '#20.2: at root' ' + cat >20/expected <<EOF && +setup: git_dir: .git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20 +setup: prefix: (null) +EOF + test_repo 20 +' + +test_expect_success '#20.2: in subdir' ' + cat >20/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/20/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/20/sub +setup: prefix: (null) +EOF + test_repo 20/sub +' + +# +# case #21.1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - cwd is inside .git +# +# Output: +# +# GIT_WORK_TREE/core.worktree are ignored -> #20.1 + +test_expect_success '#21.1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 21 21/sub && + cd 21 && + git init && + git config core.worktree non-existent && + GIT_WORK_TREE=non-existent-too && + export GIT_WORK_TREE && + mkdir .git/wt .git/wt/sub && + cd .. +' + +test_expect_success '#21.1: at .git' ' + cat >21/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git +setup: prefix: (null) +EOF + test_repo 21/.git +' + +test_expect_success '#21.1: in .git/wt' ' + cat >21/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/21/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git/wt +setup: prefix: (null) +EOF + test_repo 21/.git/wt +' + +test_expect_success '#21.1: in .git/wt/sub' ' + cat >21/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/21/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 21/.git/wt/sub +' + +# +# case #21.2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# GIT_WORK_TREE/core.worktree are ignored -> #20.2 + +test_expect_success '#21.2: setup' ' + git config --file="$TRASH_DIRECTORY/21/.git/config" core.bare true +' + +test_expect_success '#21.2: at .git' ' + cat >21/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git +setup: prefix: (null) +EOF + test_repo 21/.git +' + +test_expect_success '#21.2: in .git/wt' ' + cat >21/.git/wt/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/21/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git/wt +setup: prefix: (null) +EOF + test_repo 21/.git/wt +' + +test_expect_success '#21.2: in .git/wt/sub' ' + cat >21/.git/wt/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/21/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/.git/wt/sub +setup: prefix: (null) +EOF + test_repo 21/.git/wt/sub +' + +test_expect_success '#21.2: at root' ' + cat >21/expected <<EOF && +setup: git_dir: .git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21 +setup: prefix: (null) +EOF + test_repo 21 +' + +test_expect_success '#21.2: in subdir' ' + cat >21/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/21/.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/21/sub +setup: prefix: (null) +EOF + test_repo 21/sub +' + +# +# case #22.1 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a directory +# - cwd is inside .git +# +# Output: +# +# bare attribute is ignored +# +# - worktree is at core.worktree +# - cwd is at worktree root +# - prefix is calculated +# - git_dir is at $GIT_DIR +# - cwd can be outside worktree + +test_expect_success '#22.1: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 22 && + cd 22 && + git init && + mkdir .git/sub .git/wt .git/wt/sub && + cd .. +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=. at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.(rel) at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=. at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=.(rel) at root' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=. in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" && + test_repo 22/.git/sub .. +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . && + test_repo 22/.git/sub/ .. +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=. in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git" && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=.(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree . && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt(rel) at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: . +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=wt(rel) at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=wt at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: .. +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" && + test_repo 22/.git/sub .. +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=wt(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: .. +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt && + test_repo 22/.git/sub .. +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=wt(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree wt && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=wt in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22/.git/wt +setup: cwd: $TRASH_DIRECTORY/22/.git/sub +setup: prefix: (null) +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22/.git/wt" && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.. at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=..(rel) at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. && + test_repo 22/.git . +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=..(rel) at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=.. at .git' ' + cat >22/.git/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" && + test_repo 22/.git "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=.. in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" && + test_repo 22/.git/sub .. +' + +test_expect_success '#22.1: GIT_DIR(rel), core.worktree=..(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. && + test_repo 22/.git/sub .. +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=..(rel) in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree .. && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +test_expect_success '#22.1: GIT_DIR, core.worktree=.. in .git/sub' ' + cat >22/.git/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/22/.git +setup: worktree: $TRASH_DIRECTORY/22 +setup: cwd: $TRASH_DIRECTORY/22 +setup: prefix: .git/sub/ +EOF + git config --file="$TRASH_DIRECTORY/22/.git/config" core.worktree "$TRASH_DIRECTORY/22" && + test_repo 22/.git/sub "$TRASH_DIRECTORY/22/.git" +' + +# +# case #22.2 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# core.worktree and core.bare conflict, won't fly. + +test_expect_success '#22.2: setup' ' + git config --file="$TRASH_DIRECTORY/22/.git/config" core.bare true +' + +test_expect_success '#22.2: at .git' ' + ( + cd 22/.git && + GIT_DIR=. && + export GIT_DIR && + test_must_fail git symbolic-ref HEAD 2>result && + grep "core.bare and core.worktree do not make sense" result + ) +' + +test_expect_success '#22.2: at root' ' + ( + cd 22 && + GIT_DIR=.git && + export GIT_DIR && + test_must_fail git symbolic-ref HEAD 2>result && + grep "core.bare and core.worktree do not make sense" result + ) +' + +# +# case #23 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a directory +# - core.bare is set +# +# Output: +# +# core.worktree is overridden by GIT_WORK_TREE -> #19 + +test_expect_success '#23: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 23 23/sub 23/sub/sub 23.wt 23.wt/sub 23/wt 23/wt/sub && + cd 23 && + git init && + git config core.bare true && + git config core.worktree non-existent && + cd .. +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >23/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 .git "$TRASH_DIRECTORY/23" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 .git . +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23" +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" . +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: sub/sub/ +EOF + test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY/23" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: sub/sub/ +EOF + test_repo 23/sub/sub ../../.git ../.. +' + +test_expect_success '#23: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >23/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: sub/ +EOF + test_repo 23/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23" +' + +test_expect_success '#23: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23 +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: sub/sub/ +EOF + test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../.. +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >23/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 .git "$TRASH_DIRECTORY/23/wt" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: .git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 .git wt +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" wt +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23 +setup: prefix: (null) +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23/wt" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23/sub/sub +setup: prefix: (null) +EOF + test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY/23/wt" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: ../../.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23/sub/sub +setup: prefix: (null) +EOF + test_repo 23/sub/sub ../../.git ../../wt +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23/sub/sub +setup: prefix: (null) +EOF + test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../../wt +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY/23/wt +setup: cwd: $TRASH_DIRECTORY/23/sub/sub +setup: prefix: (null) +EOF + test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY/23/wt" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/ +EOF + test_repo 23 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/ +EOF + test_repo 23 .git .. +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/ +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" .. +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >23/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/ +EOF + test_repo 23 "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/sub/sub/ +EOF + test_repo 23/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#23: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/sub/sub/ +EOF + test_repo 23/sub/sub ../../.git ../../.. +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/sub/sub/ +EOF + test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" ../../../ +' + +test_expect_success '#23: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >23/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/23/.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 23/sub/sub/ +EOF + test_repo 23/sub/sub "$TRASH_DIRECTORY/23/.git" "$TRASH_DIRECTORY" +' + +# +# case #24 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a file +# - core.bare is set +# +# Output: +# +# #16.2 except git_dir is set according to .git file + +test_expect_success '#24: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 24 24/sub && + cd 24 && + git init && + git config core.bare true && + mv .git ../24.git && + echo gitdir: ../24.git >.git && + cd .. +' + +test_expect_success '#24: at root' ' + cat >24/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/24.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/24 +setup: prefix: (null) +EOF + test_repo 24 +' + +test_expect_success '#24: in subdir' ' + cat >24/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/24.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/24/sub +setup: prefix: (null) +EOF + test_repo 24/sub +' + +# +# case #25 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is not set +# - .git is a file +# - core.bare is set +# +# Output: +# +# #17.2 except git_dir is set according to .git file + +test_expect_success '#25: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 25 25/sub && + cd 25 && + git init && + git config core.bare true && + GIT_WORK_TREE=non-existent && + export GIT_WORK_TREE && + mv .git ../25.git && + echo gitdir: ../25.git >.git && + cd .. +' + +test_expect_success '#25: at root' ' + cat >25/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/25.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/25 +setup: prefix: (null) +EOF + test_repo 25 +' + +test_expect_success '#25: in subdir' ' + cat >25/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/25.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/25/sub +setup: prefix: (null) +EOF + test_repo 25/sub +' + +# +# case #26 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is not set +# - .git is a file +# - core.bare is set +# +# Output: +# +# #18 except git_dir is set according to .git file + +test_expect_success '#26: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 26 26/sub && + cd 26 && + git init && + git config core.bare true && + mv .git ../26.git && + echo gitdir: ../26.git >.git && + cd .. +' + +test_expect_success '#26: (rel) at root' ' + cat >26/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/26.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/26 +setup: prefix: (null) +EOF + test_repo 26 .git +' + +test_expect_success '#26: at root' ' + cat >26/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/26.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/26 +setup: prefix: (null) +EOF + test_repo 26 "$TRASH_DIRECTORY/26/.git" +' + +test_expect_success '#26: (rel) in subdir' ' + cat >26/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/26.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/26/sub +setup: prefix: (null) +EOF + test_repo 26/sub ../.git +' + +test_expect_success '#26: in subdir' ' + cat >26/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/26.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/26/sub +setup: prefix: (null) +EOF + test_repo 26/sub "$TRASH_DIRECTORY/26/.git" +' + +# +# case #27 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - .git is a file +# - core.worktree is not set +# - core.bare is set +# +# Output: +# +# #19 except git_dir is set according to .git file + +test_expect_success '#27: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 27 27/sub 27/sub/sub 27.wt 27.wt/sub 27/wt 27/wt/sub && + cd 27 && + git init && + git config core.bare true && + mv .git ../27.git && + echo gitdir: ../27.git >.git && + cd .. +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 .git "$TRASH_DIRECTORY/27" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 .git . +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27" +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" . +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: sub/sub/ +EOF + test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: sub/sub/ +EOF + test_repo 27/sub/sub ../../.git ../.. +' + +test_expect_success '#27: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >27/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: sub/ +EOF + test_repo 27/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27" +' + +test_expect_success '#27: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27 +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: sub/sub/ +EOF + test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../.. +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 .git "$TRASH_DIRECTORY/27/wt" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 .git wt +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" wt +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27 +setup: prefix: (null) +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27/sub/sub +setup: prefix: (null) +EOF + test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY/27/wt" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27/sub/sub +setup: prefix: (null) +EOF + test_repo 27/sub/sub ../../.git ../../wt +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27/sub/sub +setup: prefix: (null) +EOF + test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../wt +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY/27/wt +setup: cwd: $TRASH_DIRECTORY/27/sub/sub +setup: prefix: (null) +EOF + test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY/27/wt" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/ +EOF + test_repo 27 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/ +EOF + test_repo 27 .git .. +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/ +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" .. +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >27/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/ +EOF + test_repo 27 "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/sub/sub/ +EOF + test_repo 27/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#27: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/sub/sub/ +EOF + test_repo 27/sub/sub ../../.git ../../.. +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/sub/sub/ +EOF + test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" ../../../ +' + +test_expect_success '#27: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >27/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/27.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 27/sub/sub/ +EOF + test_repo 27/sub/sub "$TRASH_DIRECTORY/27/.git" "$TRASH_DIRECTORY" +' + +# +# case #28 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a file +# - core.bare is set +# +# Output: +# +# core.worktree is ignored -> #24 + +test_expect_success '#28: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 28 28/sub && + cd 28 && + git init && + git config core.bare true && + git config core.worktree non-existent && + mv .git ../28.git && + echo gitdir: ../28.git >.git && + cd .. +' + +test_expect_success '#28: at root' ' + cat >28/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/28.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/28 +setup: prefix: (null) +EOF + test_repo 28 +' + +test_expect_success '#28: in subdir' ' + cat >28/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/28.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/28/sub +setup: prefix: (null) +EOF + test_repo 28/sub +' + +# +# case #29 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is not set +# - core.worktree is set +# - .git is a file +# - core.bare is set +# +# Output: +# +# GIT_WORK_TREE/core.worktree are ignored -> #28 + +test_expect_success '#29: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 29 29/sub && + cd 29 && + git init && + git config core.bare true && + GIT_WORK_TREE=non-existent && + export GIT_WORK_TREE && + mv .git ../29.git && + echo gitdir: ../29.git >.git && + cd .. +' + +test_expect_success '#29: at root' ' + cat >29/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/29.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/29 +setup: prefix: (null) +EOF + test_repo 29 +' + +test_expect_success '#29: in subdir' ' + cat >29/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/29.git +setup: worktree: (null) +setup: cwd: $TRASH_DIRECTORY/29/sub +setup: prefix: (null) +EOF + test_repo 29/sub +' + +# +# case #30 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is not set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a file +# - core.bare is set +# +# Output: +# +# core.worktree and core.bare conflict, won't fly. + +test_expect_success '#30: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 30 && + cd 30 && + git init && + git config core.bare true && + git config core.worktree non-existent && + mv .git ../30.git && + echo gitdir: ../30.git >.git && + cd .. +' + +test_expect_success '#30: at root' ' + ( + cd 30 && + GIT_DIR=.git && + export GIT_DIR && + test_must_fail git symbolic-ref HEAD 2>result && + grep "core.bare and core.worktree do not make sense" result + ) +' + +# +# case #31 +# +############################################################ +# +# Input: +# +# - GIT_WORK_TREE is set +# - GIT_DIR is set +# - core.worktree is set +# - .git is a file +# - core.bare is set +# +# Output: +# +# #23 except git_dir is set according to .git file + +test_expect_success '#31: setup' ' + unset GIT_DIR GIT_WORK_TREE && + mkdir 31 31/sub 31/sub/sub 31.wt 31.wt/sub 31/wt 31/wt/sub && + cd 31 && + git init && + git config core.bare true && + git config core.worktree non-existent && + mv .git ../31.git && + echo gitdir: ../31.git >.git && + cd .. +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=root at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 .git "$TRASH_DIRECTORY/31" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=root(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 .git . +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=root at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31" +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=root(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" . +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORKTREE=root in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: sub/sub/ +EOF + test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORKTREE=root(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: sub/sub/ +EOF + test_repo 31/sub/sub ../../.git ../.. +' + +test_expect_success '#31: GIT_DIR, GIT_WORKTREE=root in subdir' ' + cat >31/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: sub/ +EOF + test_repo 31/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31" +' + +test_expect_success '#31: GIT_DIR, GIT_WORKTREE=root(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31 +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: sub/sub/ +EOF + test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../.. +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 .git "$TRASH_DIRECTORY/31/wt" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 .git wt +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" wt +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31 +setup: prefix: (null) +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31/sub/sub +setup: prefix: (null) +EOF + test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY/31/wt" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=wt(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31/sub/sub +setup: prefix: (null) +EOF + test_repo 31/sub/sub ../../.git ../../wt +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31/sub/sub +setup: prefix: (null) +EOF + test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../wt +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=wt in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY/31/wt +setup: cwd: $TRASH_DIRECTORY/31/sub/sub +setup: prefix: (null) +EOF + test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY/31/wt" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=.. at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/ +EOF + test_repo 31 .git "$TRASH_DIRECTORY" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/ +EOF + test_repo 31 .git .. +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=..(rel) at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/ +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" .. +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=.. at root' ' + cat >31/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/ +EOF + test_repo 31 "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=.. in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/sub/sub/ +EOF + test_repo 31/sub/sub ../../.git "$TRASH_DIRECTORY" +' + +test_expect_success '#31: GIT_DIR(rel), GIT_WORK_TREE=..(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/sub/sub/ +EOF + test_repo 31/sub/sub ../../.git ../../.. +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=..(rel) in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/sub/sub/ +EOF + test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" ../../../ +' + +test_expect_success '#31: GIT_DIR, GIT_WORK_TREE=.. in subdir' ' + cat >31/sub/sub/expected <<EOF && +setup: git_dir: $TRASH_DIRECTORY/31.git +setup: worktree: $TRASH_DIRECTORY +setup: cwd: $TRASH_DIRECTORY +setup: prefix: 31/sub/sub/ +EOF + test_repo 31/sub/sub "$TRASH_DIRECTORY/31/.git" "$TRASH_DIRECTORY" +' + +test_done diff --git a/test-subprocess.c b/test-subprocess.c new file mode 100644 index 0000000000..667d3e5079 --- /dev/null +++ b/test-subprocess.c @@ -0,0 +1,21 @@ +#include "cache.h" +#include "run-command.h" + +int main(int argc, char **argv) +{ + const char *prefix; + struct child_process cp; + int nogit = 0; + + prefix = setup_git_directory_gently(&nogit); + if (nogit) + die("No git repo found"); + if (!strcmp(argv[1], "--setup-work-tree")) { + setup_work_tree(); + argv++; + } + memset(&cp, 0, sizeof(cp)); + cp.git_cmd = 1; + cp.argv = (const char **)argv+1; + return run_command(&cp); +} @@ -127,3 +127,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)); +} |