When GIT_DIR environment variable is not specified, .git will be searched if a repository is needed. Currently this can be done in two places: setup_git_directory_gently() and setup_git_env(). The one in setup_git_env() is no longer correct and should IMHO have been removed since the introduction of setup_git_directory_gently() in d288a70. Having two ways of auto detection may lead to obscure errors because .git may be misdetected by setup_git_env(), automatically called via git_path(), which is all over the place. This patch makes setup_git_env() die if GIT_DIR is not explictly set. That's setup_git_directory_gently()'s job. If you ever want to touch things inside $GIT_DIR, you should have already called setup_git_directory_gently(). However, doing that will break Git the hard way. So the die()ing behavior will be only triggered if environment variable GIT_HARDENED_SETUP is set. Otherwise old behavior remains. Once all Git commands have been adapted to stay away from the old behavior, the old code can be removed. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- config.c | 17 ++++++++++++----- environment.c | 42 ++++++++++++++++++++++++++++++++---------- setup.c | 4 +++- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/config.c b/config.c index 6963fbe..eee12b4 100644 --- a/config.c +++ b/config.c @@ -704,6 +704,7 @@ int git_config(config_fn_t fn, void *data) int ret = 0, found = 0; char *repo_config = NULL; const char *home = NULL; + const char *hardened_setup = getenv("GIT_HARDENED_SETUP"); /* Setting $GIT_CONFIG makes git read _only_ the given config file. */ if (config_exclusive_filename) @@ -724,12 +725,18 @@ int git_config(config_fn_t fn, void *data) free(user_config); } - repo_config = git_pathdup("config"); - if (!access(repo_config, R_OK)) { - ret += git_config_from_file(fn, repo_config, data); - found += 1; + if (hardened_setup && !*hardened_setup) + hardened_setup = NULL; + if (hardened_setup && startup_info && !startup_info->have_set_gitdir) + die("Try to access a repository before properly setting it up"); + if (!hardened_setup || !startup_info || startup_info->have_repository) { + repo_config = git_pathdup("config"); + if (!access(repo_config, R_OK)) { + ret += git_config_from_file(fn, repo_config, data); + found += 1; + } + free(repo_config); } - free(repo_config); if (found == 0) return -1; return ret; diff --git a/environment.c b/environment.c index 1ab8815..4795441 100644 --- a/environment.c +++ b/environment.c @@ -66,9 +66,19 @@ static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file; static void setup_git_env(void) { + const char *harden_setup = getenv("GIT_HARDENED_SETUP"); + + if (harden_setup && !*harden_setup) + harden_setup = NULL; + git_dir = getenv(GIT_DIR_ENVIRONMENT); - if (!git_dir) - git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT); + if (!git_dir) { + if (harden_setup) + die("GIT_DIR not properly set"); + git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT); + } + if (harden_setup && startup_info && startup_info->have_set_gitdir) + die("internal error: setup_git_env can't be called twice"); if (!git_dir) git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; git_object_dir = getenv(DB_ENVIRONMENT); @@ -103,8 +113,11 @@ int have_git_dir(void) const char *get_git_dir(void) { - if (!git_dir) - setup_git_env(); + if (!git_dir) { + const char *harden_setup = getenv("GIT_HARDENED_SETUP"); + if (!harden_setup || !*harden_setup) + setup_git_env(); + } return git_dir; } @@ -146,22 +159,31 @@ const char *get_git_work_tree(void) char *get_object_directory(void) { - if (!git_object_dir) - setup_git_env(); + if (!git_object_dir) { + const char *harden_setup = getenv("GIT_HARDENED_SETUP"); + if (!harden_setup || !*harden_setup) + setup_git_env(); + } return git_object_dir; } char *get_index_file(void) { - if (!git_index_file) - setup_git_env(); + if (!git_index_file) { + const char *harden_setup = getenv("GIT_HARDENED_SETUP"); + if (!harden_setup || !*harden_setup) + setup_git_env(); + } return git_index_file; } char *get_graft_file(void) { - if (!git_graft_file) - setup_git_env(); + if (!git_graft_file) { + const char *harden_setup = getenv("GIT_HARDENED_SETUP"); + if (!harden_setup || !*harden_setup) + setup_git_env(); + } return git_graft_file; } diff --git a/setup.c b/setup.c index 0c05d36..5c8777a 100644 --- a/setup.c +++ b/setup.c @@ -453,8 +453,10 @@ const char *setup_git_directory_gently(int *nongit_ok) const char *prefix; prefix = setup_git_directory_gently_1(nongit_ok); - if (startup_info) + if (startup_info) { startup_info->have_set_gitdir = 1; + startup_info->have_repository = get_git_dir() != NULL; + } if ((!nongit_ok || !*nongit_ok) && check_repository_format_gently(nongit_ok)) prefix = NULL; if (startup_info) { -- 1.7.0.195.g637a2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html