summaryrefslogtreecommitdiff
path: root/git.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-06-25 12:22:00 -0700
committerJunio C Hamano <gitster@pobox.com>2014-06-25 12:22:00 -0700
commitb30adaac5238a611f12c407912b75112ad4cf186 (patch)
tree595abd7809c349c9a3791583c698af6de25b7a72 /git.c
parentb7ce583682e26910c98e71d55babd2ed23a006ad (diff)
parentc0562611c525bb3c564b79c345fc7e4f9e799e54 (diff)
downloadgit-b30adaac5238a611f12c407912b75112ad4cf186.tar.gz
Merge branch 'nd/init-restore-env'
Some subcommands do not want to be aliased because of the side effects that happens while the definitions of the aliases are looked up from configuration system. * nd/init-restore-env: git potty: restore environments after alias expansion
Diffstat (limited to 'git.c')
-rw-r--r--git.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/git.c b/git.c
index 7780572948..d6b4a5543f 100644
--- a/git.c
+++ b/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;
}