unset_git_directory() can only clean up things as long as set_git_dir() has not been called because set_git_dir() sets internal state itself. Even worse, set_git_dir() may override $GIT_DIR env variable. Add unset_git_env() to undo set_git_dir(), allow unset_git_directory() to undo a succesful setup_git_directory_gently(). While at there, fix alias handling code regarding git_dir {,un-}setup, use unset_git_directory() instead of just chdir() back. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- cache.h | 1 + environment.c | 20 ++++++++++++++++++++ git.c | 11 +++++------ setup.c | 2 ++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cache.h b/cache.h index bdcd1ec..137edac 100644 --- a/cache.h +++ b/cache.h @@ -422,6 +422,7 @@ extern void setup_work_tree(void); extern const char *setup_git_directory_gently(int *); extern const char *setup_git_directory(void); extern void unset_git_directory(const char *prefix); +extern void unset_git_env(); extern const char *prefix_path(const char *prefix, int len, const char *path); extern const char *prefix_filename(const char *prefix, int len, const char *path); extern int check_filename(const char *prefix, const char *name); diff --git a/environment.c b/environment.c index c36c902..6127025 100644 --- a/environment.c +++ b/environment.c @@ -62,6 +62,7 @@ char *git_work_tree_cfg; static char *work_tree; static const char *git_dir; +static const char *original_git_dir; static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file; /* @@ -81,6 +82,20 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = { NULL }; +void unset_git_env(void) +{ + git_dir = NULL; + if (original_git_dir) + setenv(GIT_DIR_ENVIRONMENT, original_git_dir, 1); + else + unsetenv(GIT_DIR_ENVIRONMENT); + git_object_dir = NULL; + git_refs_dir = NULL; + git_index_file = NULL; + git_graft_file = NULL; + read_replace_refs = 1; +} + static void setup_git_env(void) { git_dir = getenv(GIT_DIR_ENVIRONMENT); @@ -184,6 +199,11 @@ char *get_graft_file(void) int set_git_dir(const char *path) { + static int original_git_dir_set = 0; + if (!original_git_dir_set) { + original_git_dir = getenv(GIT_DIR_ENVIRONMENT); + original_git_dir_set = 1; + } if (setenv(GIT_DIR_ENVIRONMENT, path, 1)) return error("Could not set GIT_DIR to '%s'", path); setup_git_env(); diff --git a/git.c b/git.c index d60f792..17482dd 100644 --- a/git.c +++ b/git.c @@ -146,14 +146,13 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; - const char *subdir; int count, option_count; const char **new_argv; const char *alias_command; char *alias_string; int unused_nongit; - subdir = setup_git_directory_gently(&unused_nongit); + setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); @@ -210,8 +209,7 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir && chdir(subdir)) - die_errno("Cannot change to '%s'", subdir); + unset_git_directory(startup_info->prefix); errno = saved_errno; @@ -240,8 +238,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) int status; struct stat st; - memset(&git_startup_info, 0, sizeof(git_startup_info)); - startup_info = &git_startup_info; startup_info->help = argc == 2 && !strcmp(argv[1], "-h"); if (!startup_info->help) { if (p->option & RUN_SETUP) @@ -486,6 +482,9 @@ int main(int argc, const char **argv) { const char *cmd; + memset(&git_startup_info, 0, sizeof(git_startup_info)); + startup_info = &git_startup_info; + cmd = git_extract_argv0_path(argv[0]); if (!cmd) cmd = "git-help"; diff --git a/setup.c b/setup.c index 858cf6b..b0269aa 100644 --- a/setup.c +++ b/setup.c @@ -336,6 +336,8 @@ void unset_git_directory(const char *prefix) die("Cannot change to '%s'", prefix); if (startup_info) { + if (startup_info->have_repository) + unset_git_env(); startup_info->prefix = NULL; startup_info->have_repository = 0; } -- 1.7.0.rc1.541.g2da82.dirty -- 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