Merge branch 'ak/git-strip-extension-from-dashed-command'
authorJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:13 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:13 +0000 (13:37 -0800)
Code simplification.

* ak/git-strip-extension-from-dashed-command:
git.c: simplify stripping extension of a file in handle_builtin()

1  2 
git-compat-util.h
git.c
diff --combined git-compat-util.h
index 693a336ff52ffc5acfaaa114829008de21b0a651,b7fcbd4b86664854a71128864ae41ae55a7d633d..2acef3f113f64cc3491f085b6535353d16f9a7c8
@@@ -229,7 -229,7 +229,7 @@@ typedef unsigned long uintptr_t
  #else
  #define precompose_str(in,i_nfd2nfc)
  #define precompose_argv(c,v)
 -#define probe_utf8_pathname_composition(a,b)
 +#define probe_utf8_pathname_composition()
  #endif
  
  #ifdef MKDIR_WO_TRAILING_SLASH
@@@ -253,8 -253,6 +253,8 @@@ struct itimerval 
  #else
  #define basename gitbasename
  extern char *gitbasename(char *);
 +#define dirname gitdirname
 +extern char *gitdirname(char *);
  #endif
  
  #ifndef NO_ICONV
  #define PRIuMAX "llu"
  #endif
  
 +#ifndef SCNuMAX
 +#define SCNuMAX PRIuMAX
 +#endif
 +
  #ifndef PRIu32
  #define PRIu32 "u"
  #endif
  #define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin"
  #endif
  
- #ifndef STRIP_EXTENSION
- #define STRIP_EXTENSION ""
- #endif
  #ifndef has_dos_drive_prefix
  static inline int git_has_dos_drive_prefix(const char *path)
  {
  #define has_dos_drive_prefix git_has_dos_drive_prefix
  #endif
  
 +#ifndef skip_dos_drive_prefix
 +static inline int git_skip_dos_drive_prefix(char **path)
 +{
 +      return 0;
 +}
 +#define skip_dos_drive_prefix git_skip_dos_drive_prefix
 +#endif
 +
  #ifndef is_dir_sep
  static inline int git_is_dir_sep(int c)
  {
@@@ -582,7 -564,7 +578,7 @@@ extern int git_lstat(const char *, stru
  #endif
  
  #define DEFAULT_PACKED_GIT_LIMIT \
 -      ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
 +      ((1024L * 1024L) * (size_t)(sizeof(void*) >= 8 ? 8192 : 256))
  
  #ifdef NO_PREAD
  #define pread git_pread
@@@ -743,7 -725,6 +739,7 @@@ extern int xmkstemp_mode(char *template
  extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
  extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
  extern char *xgetcwd(void);
 +extern FILE *fopen_for_writing(const char *path);
  
  #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
  
@@@ -759,9 -740,6 +755,9 @@@ static inline size_t xsize_t(off_t len
        return (size_t)len;
  }
  
 +__attribute__((format (printf, 3, 4)))
 +extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
 +
  /* in ctype.c, for kwset users */
  extern const unsigned char tolower_trans_tbl[256];
  
@@@ -832,9 -810,6 +828,9 @@@ static inline int strtoul_ui(char cons
        char *p;
  
        errno = 0;
 +      /* negative values would be accepted by strtoul */
 +      if (strchr(s, '-'))
 +              return -1;
        ul = strtoul(s, &p, base);
        if (errno || *p || p == s || (unsigned int) ul != ul)
                return -1;
@@@ -940,6 -915,9 +936,6 @@@ int access_or_die(const char *path, in
  /* Warn on an inaccessible file that ought to be accessible */
  void warn_on_inaccessible(const char *path);
  
 -/* Get the passwd entry for the UID of the current process. */
 -struct passwd *xgetpwuid_self(void);
 -
  #ifdef GMTIME_UNRELIABLE_ERRORS
  struct tm *git_gmtime(const time_t *);
  struct tm *git_gmtime_r(const time_t *, struct tm *);
diff --combined git.c
index 6c64c9430e8e5ae3130b0c97e90bcbad29625b1e,a9dc2e8b492589e1f41d2c91cf4149aefe25c872..9bc04fd5285ff8c16d92554e0248e90f416089e7
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -25,14 -25,14 +25,14 @@@ static const char *env_names[] = 
        GIT_PREFIX_ENVIRONMENT
  };
  static char *orig_env[4];
 -static int saved_environment;
 +static int save_restore_env_balance;
  
 -static void save_env(void)
 +static void save_env_before_alias(void)
  {
        int i;
 -      if (saved_environment)
 -              return;
 -      saved_environment = 1;
 +
 +      assert(save_restore_env_balance == 0);
 +      save_restore_env_balance = 1;
        orig_cwd = xgetcwd();
        for (i = 0; i < ARRAY_SIZE(env_names); i++) {
                orig_env[i] = getenv(env_names[i]);
        }
  }
  
 -static void restore_env(void)
 +static void restore_env(int external_alias)
  {
        int i;
 -      if (orig_cwd && chdir(orig_cwd))
 +
 +      assert(save_restore_env_balance == 1);
 +      save_restore_env_balance = 0;
 +      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 (orig_env[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
 +                      free(orig_env[i]);
 +              } else {
                        unsetenv(env_names[i]);
 +              }
        }
  }
  
@@@ -234,14 -226,14 +234,14 @@@ static int handle_options(const char **
  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);
                        int argc = *argcp, i;
  
                        commit_pager_choice();
 +                      restore_env(1);
  
                        /* build alias_argv */
                        alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
                ret = 1;
        }
  
 -      if (subdir && chdir(subdir))
 -              die_errno("Cannot change to '%s'", subdir);
 +      restore_env(0);
  
        errno = saved_errno;
  
   * 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;
@@@ -396,7 -389,7 +396,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 },
        { "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 },
 -      { "interpret-trailers", cmd_interpret_trailers, RUN_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 },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
        { "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 },
@@@ -513,21 -505,25 +513,25 @@@ int is_builtin(const char *s
        return !!get_builtin(s);
  }
  
+ #ifdef STRIP_EXTENSION
+ static void strip_extension(const char **argv)
+ {
+       size_t len;
+       if (strip_suffix(argv[0], STRIP_EXTENSION, &len))
+               argv[0] = xmemdupz(argv[0], len);
+ }
+ #else
+ #define strip_extension(cmd)
+ #endif
  static void handle_builtin(int argc, const char **argv)
  {
-       const char *cmd = argv[0];
-       int i;
-       static const char ext[] = STRIP_EXTENSION;
+       const char *cmd;
        struct cmd_struct *builtin;
  
-       if (sizeof(ext) > 1) {
-               i = strlen(argv[0]) - strlen(ext);
-               if (i > 0 && !strcmp(argv[0] + i, ext)) {
-                       char *argv0 = xstrdup(argv[0]);
-                       argv[0] = cmd = argv0;
-                       argv0[i] = '\0';
-               }
-       }
+       strip_extension(argv);
+       cmd = argv[0];
  
        /* Turn "git cmd --help" into "git help cmd" */
        if (argc > 1 && !strcmp(argv[1], "--help")) {
        }
  
        builtin = get_builtin(cmd);
 -      if (builtin) {
 -              if (saved_environment && (builtin->option & NO_SETUP))
 -                      restore_env();
 -              else
 -                      exit(run_builtin(builtin, argc, argv));
 -      }
 +      if (builtin)
 +              exit(run_builtin(builtin, argc, argv));
  }
  
  static void execv_dashed_external(const char **argv)
@@@ -581,17 -581,8 +585,17 @@@ static int run_argv(int *argcp, const c
        int done_alias = 0;
  
        while (1) {
 -              /* See if it's a builtin */
 -              handle_builtin(*argcp, *argv);
 +              /*
 +               * If we tried alias and futzed with our environment,
 +               * it no longer is safe to invoke builtins directly in
 +               * general.  We have to spawn them as dashed externals.
 +               *
 +               * NEEDSWORK: if we can figure out cases
 +               * where it is safe to do, we can avoid spawning a new
 +               * process.
 +               */
 +              if (!done_alias)
 +                      handle_builtin(*argcp, *argv);
  
                /* .. then try the external ones */
                execv_dashed_external(*argv);
                 */
                if (done_alias)
                        break;
 -              save_env();
                if (!handle_alias(argcp, argv))
                        break;
                done_alias = 1;