diff --git a/cache.h b/cache.h index 3c6b677418..c1fe67ffcf 100644 --- a/cache.h +++ b/cache.h @@ -365,6 +365,18 @@ static inline enum object_type object_type(unsigned int mode) #define GIT_NOTES_REWRITE_REF_ENVIRONMENT "GIT_NOTES_REWRITE_REF" #define GIT_NOTES_REWRITE_MODE_ENVIRONMENT "GIT_NOTES_REWRITE_MODE" +/* + * This environment variable is expected to contain a boolean indicating + * whether we should or should not treat: + * + * GIT_DIR=foo.git git ... + * + * as if GIT_WORK_TREE=. was given. It's not expected that users will make use + * of this, but we use it internally to communicate to sub-processes that we + * are in a bare repo. If not set, defaults to true. + */ +#define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE" + /* * Repository-local GIT_* environment variables; these will be cleared * when git spawns a sub-process that runs inside another repository. diff --git a/environment.c b/environment.c index 4fb7ceac3a..92c5dff008 100644 --- a/environment.c +++ b/environment.c @@ -85,6 +85,7 @@ const char * const local_repo_env[] = { DB_ENVIRONMENT, GIT_DIR_ENVIRONMENT, GIT_WORK_TREE_ENVIRONMENT, + GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, GRAFT_ENVIRONMENT, INDEX_ENVIRONMENT, NO_REPLACE_OBJECTS_ENVIRONMENT, diff --git a/git.c b/git.c index d33f9b32a2..0ffea570c7 100644 --- a/git.c +++ b/git.c @@ -125,6 +125,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) static char git_dir[PATH_MAX+1]; is_bare_repository_cfg = 1; setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); + setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "-c")) { diff --git a/setup.c b/setup.c index d0e3ecdcd4..01c5476eb7 100644 --- a/setup.c +++ b/setup.c @@ -497,6 +497,12 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, set_git_work_tree(core_worktree); } } + else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) { + /* #16d */ + set_git_dir(gitdirenv); + free(gitfile); + return NULL; + } else /* #2, #10 */ set_git_work_tree("."); @@ -575,6 +581,8 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi if (check_repository_format_gently(".", nongit_ok)) return NULL; + setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1); + /* --work-tree is set without --git-dir; use discovered one */ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { const char *gitdir; diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index 80aedfca8c..cf2ee7885a 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -517,6 +517,25 @@ test_expect_success '#16c: bare .git has no worktree' ' "$here/16c/.git" "(null)" "$here/16c/sub" "(null)" ' +test_expect_success '#16d: bareness preserved across alias' ' + setup_repo 16d unset "" unset && + ( + cd 16d/.git && + test_must_fail git status && + git config alias.st status && + test_must_fail git st + ) +' + +test_expect_success '#16e: bareness preserved by --bare' ' + setup_repo 16e unset "" unset && + ( + cd 16e/.git && + test_must_fail git status && + test_must_fail git --bare status + ) +' + test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' ' # Just like #16. setup_repo 17a unset "" true &&