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

1  2 
git.c
t/t0001-init.sh
diff --combined git.c
index 778057294892d68b3dee58869cf22265223cab83,8a19974611fe7492707392510da7656fe0d10ae2..d6b4a5543f77071aff977f6d58e3ab6c5495f19d
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -20,6 -20,43 +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 +309,7 @@@ static int handle_alias(int *argcp, con
   * 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;
@@@ -290,7 -328,7 +328,7 @@@ static int run_builtin(struct cmd_struc
        if (!help) {
                if (p->option & RUN_SETUP)
                        prefix = setup_git_directory();
 -              if (p->option & RUN_SETUP_GENTLY) {
 +              else if (p->option & RUN_SETUP_GENTLY) {
                        int nongit_ok;
                        prefix = setup_git_directory_gently(&nongit_ok);
                }
@@@ -352,7 -390,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 },
        { "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 +522,10 @@@ static void handle_builtin(int argc, co
                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 +581,10 @@@ static int run_argv(int *argcp, const c
                 * 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;
        }
diff --combined t/t0001-init.sh
index 2f3020342a75f0d382af88e6ad35691ad0f183d5,b8c0ffff8beb37131e39d33f36cf61d4b736c4e8..e62c0ffbc22cffffd9c29254a96222bfb5b85633
@@@ -56,7 -56,7 +56,7 @@@ test_expect_success 'plain through alia
        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 +68,7 @@@
        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 &&
@@@ -185,14 -185,14 +185,14 @@@ test_expect_success 'init --bare/--shar
        git init --bare --shared=0666 init-bare-shared-override &&
        check_config init-bare-shared-override true unset &&
        test x0666 = \
 -      x`git config -f init-bare-shared-override/config core.sharedRepository`
 +      x$(git config -f init-bare-shared-override/config core.sharedRepository)
  '
  
  test_expect_success 'init honors global core.sharedRepository' '
        test_config_global core.sharedRepository 0666 &&
        git init shared-honor-global &&
        test x0666 = \
 -      x`git config -f shared-honor-global/.git/config core.sharedRepository`
 +      x$(git config -f shared-honor-global/.git/config core.sharedRepository)
  '
  
  test_expect_success 'init rejects insanely long --template' '
@@@ -285,7 -285,7 +285,7 @@@ test_expect_success 'init prefers comma
  test_expect_success 'init with separate gitdir' '
        rm -rf newdir &&
        git init --separate-git-dir realgitdir newdir &&
 -      echo "gitdir: `pwd`/realgitdir" >expected &&
 +      echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir realgitdir/refs
  '
@@@ -299,7 -299,7 +299,7 @@@ test_expect_success 're-init to update 
        cd newdir &&
        git init --separate-git-dir ../surrealgitdir
        ) &&
 -      echo "gitdir: `pwd`/surrealgitdir" >expected &&
 +      echo "gitdir: $(pwd)/surrealgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir surrealgitdir/refs &&
        test_path_is_missing realgitdir/refs
@@@ -312,7 -312,7 +312,7 @@@ test_expect_success 're-init to move gi
        cd newdir &&
        git init --separate-git-dir ../realgitdir
        ) &&
 -      echo "gitdir: `pwd`/realgitdir" >expected &&
 +      echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir realgitdir/refs
  '
@@@ -326,7 -326,7 +326,7 @@@ test_expect_success SYMLINKS 're-init t
        ln -s here .git &&
        git init --separate-git-dir ../realgitdir
        ) &&
 -      echo "gitdir: `pwd`/realgitdir" >expected &&
 +      echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_cmp expected newdir/here &&
        test_path_is_dir realgitdir/refs