Merge branch 'nd/clear-gitenv-upon-use-of-alias'
d95138e6(setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR, 2015-06-26) attempted to work around a glitch in alias handling by overwriting GIT_WORK_TREE environment variable to affect subprocesses when set_git_work_tree() gets called, which resulted in a rather unpleasant regression to "clone" and "init". Try to address the same issue by always restoring the environment and respawning the real underlying command when handling alias. * nd/clear-gitenv-upon-use-of-alias: run-command: don't warn on SIGPIPE deaths git.c: make sure we do not leak GIT_* to alias scripts setup.c: re-fixd95138e(setup: set env $GIT_WORK_TREE when .. git.c: make it clear save_env() is for alias handling only
This commit is contained in:
41
git.c
41
git.c
@ -25,14 +25,14 @@ static const char *env_names[] = {
|
||||
GIT_PREFIX_ENVIRONMENT
|
||||
};
|
||||
static char *orig_env[4];
|
||||
static int saved_environment;
|
||||
static int saved_env_before_alias;
|
||||
|
||||
static void save_env(void)
|
||||
static void save_env_before_alias(void)
|
||||
{
|
||||
int i;
|
||||
if (saved_environment)
|
||||
if (saved_env_before_alias)
|
||||
return;
|
||||
saved_environment = 1;
|
||||
saved_env_before_alias = 1;
|
||||
orig_cwd = xgetcwd();
|
||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
||||
orig_env[i] = getenv(env_names[i]);
|
||||
@ -41,13 +41,16 @@ static void save_env(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_env(void)
|
||||
static void restore_env(int external_alias)
|
||||
{
|
||||
int i;
|
||||
if (orig_cwd && chdir(orig_cwd))
|
||||
if (!external_alias && orig_cwd && chdir(orig_cwd))
|
||||
die_errno("could not move to %s", orig_cwd);
|
||||
free(orig_cwd);
|
||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
||||
if (external_alias &&
|
||||
!strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT))
|
||||
continue;
|
||||
if (orig_env[i])
|
||||
setenv(env_names[i], orig_env[i], 1);
|
||||
else
|
||||
@ -226,14 +229,14 @@ 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);
|
||||
save_env_before_alias();
|
||||
setup_git_directory_gently(&unused_nongit);
|
||||
|
||||
alias_command = (*argv)[0];
|
||||
alias_string = alias_lookup(alias_command);
|
||||
@ -243,6 +246,7 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
int argc = *argcp, i;
|
||||
|
||||
commit_pager_choice();
|
||||
restore_env(1);
|
||||
|
||||
/* build alias_argv */
|
||||
alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
|
||||
@ -291,8 +295,7 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (subdir && chdir(subdir))
|
||||
die_errno("Cannot change to '%s'", subdir);
|
||||
restore_env(0);
|
||||
|
||||
errno = saved_errno;
|
||||
|
||||
@ -307,7 +310,6 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||
* RUN_SETUP for reading from the configuration file.
|
||||
*/
|
||||
#define NEED_WORK_TREE (1<<3)
|
||||
#define NO_SETUP (1<<4)
|
||||
|
||||
struct cmd_struct {
|
||||
const char *cmd;
|
||||
@ -389,7 +391,7 @@ static struct cmd_struct commands[] = {
|
||||
{ "cherry", cmd_cherry, RUN_SETUP },
|
||||
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "clone", cmd_clone, NO_SETUP },
|
||||
{ "clone", cmd_clone },
|
||||
{ "column", cmd_column, RUN_SETUP_GENTLY },
|
||||
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
|
||||
@ -415,8 +417,8 @@ static struct cmd_struct commands[] = {
|
||||
{ "hash-object", cmd_hash_object },
|
||||
{ "help", cmd_help },
|
||||
{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
|
||||
{ "init", cmd_init_db, NO_SETUP },
|
||||
{ "init-db", cmd_init_db, NO_SETUP },
|
||||
{ "init", cmd_init_db },
|
||||
{ "init-db", cmd_init_db },
|
||||
{ "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY },
|
||||
{ "log", cmd_log, RUN_SETUP },
|
||||
{ "ls-files", cmd_ls_files, RUN_SETUP },
|
||||
@ -530,9 +532,13 @@ static void handle_builtin(int argc, const char **argv)
|
||||
|
||||
builtin = get_builtin(cmd);
|
||||
if (builtin) {
|
||||
if (saved_environment && (builtin->option & NO_SETUP))
|
||||
restore_env();
|
||||
else
|
||||
/*
|
||||
* XXX: if we can figure out cases where it is _safe_
|
||||
* to do, we can avoid spawning a new process when
|
||||
* saved_env_before_alias is true
|
||||
* (i.e. setup_git_dir* has been run once)
|
||||
*/
|
||||
if (!saved_env_before_alias)
|
||||
exit(run_builtin(builtin, argc, argv));
|
||||
}
|
||||
}
|
||||
@ -590,7 +596,6 @@ static int run_argv(int *argcp, const char ***argv)
|
||||
*/
|
||||
if (done_alias)
|
||||
break;
|
||||
save_env();
|
||||
if (!handle_alias(argcp, argv))
|
||||
break;
|
||||
done_alias = 1;
|
||||
|
||||
Reference in New Issue
Block a user