diff options
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_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 }, @@ -470,6 +472,7 @@ static struct cmd_struct commands[] = { { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, { "stripspace", cmd_stripspace }, + { "submodule--helper", cmd_submodule__helper, RUN_SETUP }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, { "tag", cmd_tag, RUN_SETUP }, { "unpack-file", cmd_unpack_file, RUN_SETUP }, @@ -529,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)); } } @@ -589,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; |