diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-02-17 10:13:31 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-02-17 10:13:31 -0800 |
commit | dbda66b0e283494c35958316c9b1c47b6e6c9f59 (patch) | |
tree | cfbee1f5d4982aa377386aafc2661568dbc2e70a /git.c | |
parent | f60ccdd98c3f1183922b43478b629049408849ff (diff) | |
parent | 8384c139cb9409fb3cf5ef70afff263917581258 (diff) | |
download | git-dbda66b0e283494c35958316c9b1c47b6e6c9f59.tar.gz |
Merge branch 'nd/clear-gitenv-upon-use-of-alias'
The automatic typo correction applied to an alias was broken
with a recent change already in 'master'.
* nd/clear-gitenv-upon-use-of-alias:
restore_env(): free the saved environment variable once we are done
git: simplify environment save/restore logic
git: protect against unbalanced calls to {save,restore}_env()
git: remove an early return from save_env_before_alias()
Diffstat (limited to 'git.c')
-rw-r--r-- | git.c | 42 |
1 files changed, 24 insertions, 18 deletions
@@ -25,14 +25,14 @@ static const char *env_names[] = { GIT_PREFIX_ENVIRONMENT }; static char *orig_env[4]; -static int saved_env_before_alias; +static int save_restore_env_balance; static void save_env_before_alias(void) { int i; - if (saved_env_before_alias) - return; - saved_env_before_alias = 1; + + assert(save_restore_env_balance == 0); + save_restore_env_balance = 1; orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); @@ -44,6 +44,9 @@ static void save_env_before_alias(void) static void restore_env(int external_alias) { int i; + + assert(save_restore_env_balance == 1); + save_restore_env_balance = 0; if (!external_alias && orig_cwd && chdir(orig_cwd)) die_errno("could not move to %s", orig_cwd); free(orig_cwd); @@ -51,10 +54,12 @@ static void restore_env(int external_alias) if (external_alias && !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT)) continue; - if (orig_env[i]) + if (orig_env[i]) { setenv(env_names[i], orig_env[i], 1); - else + free(orig_env[i]); + } else { unsetenv(env_names[i]); + } } } @@ -531,16 +536,8 @@ static void handle_builtin(int argc, const char **argv) } builtin = get_builtin(cmd); - if (builtin) { - /* - * 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)); - } + if (builtin) + exit(run_builtin(builtin, argc, argv)); } static void execv_dashed_external(const char **argv) @@ -584,8 +581,17 @@ static int run_argv(int *argcp, const char ***argv) int done_alias = 0; while (1) { - /* See if it's a builtin */ - handle_builtin(*argcp, *argv); + /* + * If we tried alias and futzed with our environment, + * it no longer is safe to invoke builtins directly in + * general. We have to spawn them as dashed externals. + * + * NEEDSWORK: if we can figure out cases + * where it is safe to do, we can avoid spawning a new + * process. + */ + if (!done_alias) + handle_builtin(*argcp, *argv); /* .. then try the external ones */ execv_dashed_external(*argv); |