Merge branch 'nd/init-restore-env'
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 19:22:00 +0000 (12:22 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 19:22:00 +0000 (12:22 -0700)
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

git.c
t/t0001-init.sh
diff --git a/git.c b/git.c
index 778057294892d68b3dee58869cf22265223cab83..d6b4a5543f77071aff977f6d58e3ab6c5495f19d 100644 (file)
--- 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;
        }
index 2f3020342a75f0d382af88e6ad35691ad0f183d5..e62c0ffbc22cffffd9c29254a96222bfb5b85633 100755 (executable)
@@ -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 &&