1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 21:07:52 +01:00

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()
This commit is contained in:
Junio C Hamano 2016-02-17 10:13:31 -08:00
commit dbda66b0e2
2 changed files with 76 additions and 18 deletions

42
git.c
View file

@ -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);

52
t/t9003-help-autocorrect.sh Executable file
View file

@ -0,0 +1,52 @@
#!/bin/sh
test_description='help.autocorrect finding a match'
. ./test-lib.sh
test_expect_success 'setup' '
# An alias
git config alias.lgf "log --format=%s --first-parent" &&
# A random user-defined command
write_script git-distimdistim <<-EOF &&
echo distimdistim was called
EOF
PATH="$PATH:." &&
export PATH &&
git commit --allow-empty -m "a single log entry" &&
# Sanity check
git lgf >actual &&
echo "a single log entry" >expect &&
test_cmp expect actual &&
git distimdistim >actual &&
echo "distimdistim was called" >expect &&
test_cmp expect actual
'
test_expect_success 'autocorrect showing candidates' '
git config help.autocorrect 0 &&
test_must_fail git lfg 2>actual &&
sed -e "1,/^Did you mean this/d" actual | grep lgf &&
test_must_fail git distimdist 2>actual &&
sed -e "1,/^Did you mean this/d" actual | grep distimdistim
'
test_expect_success 'autocorrect running commands' '
git config help.autocorrect -1 &&
git lfg >actual &&
echo "a single log entry" >expect &&
test_cmp expect actual &&
git distimdist >actual &&
echo "distimdistim was called" >expect &&
test_cmp expect actual
'
test_done