git potty: restore environments after alias expansion
Commit 4ad8332
(t0001: test git init when run via an alias -
2010-11-26) noted breakages when running init via alias. The problem
is for alias to be used, $GIT_DIR must be searched, but 'init' and
'clone' are not happy with that. So we start a new process like an
external command, with clean environment in this case. Env variables
that are set by command line (e.g. "git --git-dir=.. ") are kept.
This should also fix autocorrecting a command typo to "init" because
it's the same problem: aliases are read, then "init" is unhappy with
$GIT_DIR already set up because of that.
Reminded-by: David Turner <dturner@twopensource.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
e156455ea4
commit
c0562611c5
53
git.c
53
git.c
@ -20,6 +20,43 @@ const char git_more_info_string[] =
|
||||
|
||||
static struct startup_info git_startup_info;
|
||||
static int use_pager = -1;
|
||||
static char orig_cwd[PATH_MAX];
|
||||
static const char *env_names[] = {
|
||||
GIT_DIR_ENVIRONMENT,
|
||||
GIT_WORK_TREE_ENVIRONMENT,
|
||||
GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
|
||||
GIT_PREFIX_ENVIRONMENT
|
||||
};
|
||||
static char *orig_env[4];
|
||||
static int saved_environment;
|
||||
|
||||
static void save_env(void)
|
||||
{
|
||||
int i;
|
||||
if (saved_environment)
|
||||
return;
|
||||
saved_environment = 1;
|
||||
if (!getcwd(orig_cwd, sizeof(orig_cwd)))
|
||||
die_errno("cannot getcwd");
|
||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
||||
orig_env[i] = getenv(env_names[i]);
|
||||
if (orig_env[i])
|
||||
orig_env[i] = xstrdup(orig_env[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_env(void)
|
||||
{
|
||||
int i;
|
||||
if (*orig_cwd && chdir(orig_cwd))
|
||||
die_errno("could not move to %s", orig_cwd);
|
||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
||||
if (orig_env[i])
|
||||
setenv(env_names[i], orig_env[i], 1);
|
||||
else
|
||||
unsetenv(env_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void commit_pager_choice(void) {
|
||||
switch (use_pager) {
|
||||
@ -272,6 +309,7 @@ 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;
|
||||
@ -352,7 +390,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 },
|
||||
{ "clone", cmd_clone, NO_SETUP },
|
||||
{ "column", cmd_column, RUN_SETUP_GENTLY },
|
||||
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
|
||||
@ -378,8 +416,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 },
|
||||
{ "init-db", cmd_init_db },
|
||||
{ "init", cmd_init_db, NO_SETUP },
|
||||
{ "init-db", cmd_init_db, NO_SETUP },
|
||||
{ "log", cmd_log, RUN_SETUP },
|
||||
{ "ls-files", cmd_ls_files, RUN_SETUP },
|
||||
{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
|
||||
@ -484,6 +522,10 @@ static void handle_builtin(int argc, const char **argv)
|
||||
struct cmd_struct *p = commands+i;
|
||||
if (strcmp(p->cmd, cmd))
|
||||
continue;
|
||||
if (saved_environment && (p->option & NO_SETUP)) {
|
||||
restore_env();
|
||||
break;
|
||||
}
|
||||
exit(run_builtin(p, argc, argv));
|
||||
}
|
||||
}
|
||||
@ -539,7 +581,10 @@ static int run_argv(int *argcp, const char ***argv)
|
||||
* of overriding "git log" with "git show" by having
|
||||
* alias.log = show
|
||||
*/
|
||||
if (done_alias || !handle_alias(argcp, argv))
|
||||
if (done_alias)
|
||||
break;
|
||||
save_env();
|
||||
if (!handle_alias(argcp, argv))
|
||||
break;
|
||||
done_alias = 1;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ test_expect_success 'plain through aliased command, outside any git repo' '
|
||||
check_config plain-aliased/.git false unset
|
||||
'
|
||||
|
||||
test_expect_failure 'plain nested through aliased command' '
|
||||
test_expect_success 'plain nested through aliased command' '
|
||||
(
|
||||
git init plain-ancestor-aliased &&
|
||||
cd plain-ancestor-aliased &&
|
||||
@ -68,7 +68,7 @@ test_expect_failure 'plain nested through aliased command' '
|
||||
check_config plain-ancestor-aliased/plain-nested/.git false unset
|
||||
'
|
||||
|
||||
test_expect_failure 'plain nested in bare through aliased command' '
|
||||
test_expect_success 'plain nested in bare through aliased command' '
|
||||
(
|
||||
git init --bare bare-ancestor-aliased.git &&
|
||||
cd bare-ancestor-aliased.git &&
|
||||
|
Loading…
Reference in New Issue
Block a user