]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'rs/strbuf-getcwd'
authorJunio C Hamano <gitster@pobox.com>
Tue, 2 Sep 2014 20:27:45 +0000 (13:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 2 Sep 2014 20:28:44 +0000 (13:28 -0700)
Reduce the use of fixed sized buffer passed to getcwd() calls
by introducing xgetcwd() helper.

* rs/strbuf-getcwd:
  use strbuf_add_absolute_path() to add absolute paths
  abspath: convert absolute_path() to strbuf
  use xgetcwd() to set $GIT_DIR
  use xgetcwd() to get the current directory or die
  wrapper: add xgetcwd()
  abspath: convert real_path_internal() to strbuf
  abspath: use strbuf_getcwd() to remember original working directory
  setup: convert setup_git_directory_gently_1 et al. to strbuf
  unix-sockets: use strbuf_getcwd()
  strbuf: add strbuf_getcwd()

12 files changed:
1  2 
Documentation/technical/api-strbuf.txt
builtin/init-db.c
builtin/rev-parse.c
dir.c
git-compat-util.h
git.c
setup.c
sha1_file.c
strbuf.c
strbuf.h
trace.c
unix-socket.c

index 6d8ac2cc33b25ebb29655742f241b5a61e7ca563,ab0ea02d25e817bb5bb4ee683336c76c867f250e..587a5055ed677c3541c85101d944ffb0a19b1962
@@@ -572,13 -573,10 +573,10 @@@ int cmd_init_db(int argc, const char **
                        git_work_tree_cfg = xstrdup(real_path(rel));
                        free(rel);
                }
-               if (!git_work_tree_cfg) {
-                       git_work_tree_cfg = xcalloc(PATH_MAX, 1);
-                       if (!getcwd(git_work_tree_cfg, PATH_MAX))
-                               die_errno (_("Cannot access current working directory"));
-               }
+               if (!git_work_tree_cfg)
+                       git_work_tree_cfg = xgetcwd();
                if (work_tree)
 -                      set_git_work_tree(real_path(work_tree));
 +                      set_git_work_tree(work_tree);
                else
                        set_git_work_tree(git_work_tree_cfg);
                if (access(get_git_work_tree(), X_OK))
Simple merge
diff --cc dir.c
Simple merge
Simple merge
diff --cc git.c
index 9c495198317bf31ff40785a48bf0a44253548098,c4e8c5cfdfadac8eb19a977854cf79cf2bce3881..210f1ae9d04dda4d16f9f072ef710bf630f6d52e
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -20,43 -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 char *orig_cwd;
 +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");
++      orig_cwd = xgetcwd();
 +      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))
++      if (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])
 +                      setenv(env_names[i], orig_env[i], 1);
 +              else
 +                      unsetenv(env_names[i]);
 +      }
 +}
  
  static void commit_pager_choice(void) {
        switch (use_pager) {
diff --cc setup.c
Simple merge
diff --cc sha1_file.c
index 3f70b1d86aaa8e0648d8a3c6ebb6aca701ae7475,a38854ce553c1e59294d5542a37a5404ccd66dc5..95afd209107277da3154226dd08bd8040a9097b5
@@@ -350,9 -352,6 +350,9 @@@ static void link_alt_odb_entries(const 
                return;
        }
  
-       strbuf_addstr(&objdirbuf, absolute_path(get_object_directory()));
++      strbuf_add_absolute_path(&objdirbuf, get_object_directory());
 +      normalize_path_copy(objdirbuf.buf, objdirbuf.buf);
 +
        alt_copy = xmemdupz(alt, len);
        string_list_split_in_place(&entries, alt_copy, sep, -1);
        for (i = 0; i < entries.nr; i++) {
diff --cc strbuf.c
Simple merge
diff --cc strbuf.h
Simple merge
diff --cc trace.c
index e583dc63bb8d7062f8b735e701978574e9fcbf25,3523667f6f6fb2c9ca38917f8e45144e99186dc7..54aaee58183f880365caa1986824054a4533797e
+++ b/trace.c
@@@ -296,15 -156,14 +296,14 @@@ static const char *quote_crnl(const cha
  /* FIXME: move prefix to startup_info struct and get rid of this arg */
  void trace_repo_setup(const char *prefix)
  {
 -      static const char *key = "GIT_TRACE_SETUP";
 +      static struct trace_key key = TRACE_KEY_INIT(SETUP);
        const char *git_work_tree;
-       char cwd[PATH_MAX];
+       char *cwd;
  
 -      if (!trace_want(key))
 +      if (!trace_want(&key))
                return;
  
-       if (!getcwd(cwd, PATH_MAX))
-               die("Unable to get current working directory");
+       cwd = xgetcwd();
  
        if (!(git_work_tree = get_git_work_tree()))
                git_work_tree = "(null)";
        if (!prefix)
                prefix = "(null)";
  
 -      trace_printf_key(key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
 -      trace_printf_key(key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
 -      trace_printf_key(key, "setup: cwd: %s\n", quote_crnl(cwd));
 -      trace_printf_key(key, "setup: prefix: %s\n", quote_crnl(prefix));
 +      trace_printf_key(&key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
 +      trace_printf_key(&key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
 +      trace_printf_key(&key, "setup: cwd: %s\n", quote_crnl(cwd));
 +      trace_printf_key(&key, "setup: prefix: %s\n", quote_crnl(prefix));
+       free(cwd);
  }
  
 -int trace_want(const char *key)
 +int trace_want(struct trace_key *key)
  {
 -      const char *trace = getenv(key);
 +      return !!get_trace_fd(key);
 +}
  
 -      if (!trace || !strcmp(trace, "") ||
 -          !strcmp(trace, "0") || !strcasecmp(trace, "false"))
 +#ifdef HAVE_CLOCK_GETTIME
 +
 +static inline uint64_t highres_nanos(void)
 +{
 +      struct timespec ts;
 +      if (clock_gettime(CLOCK_MONOTONIC, &ts))
                return 0;
 -      return 1;
 +      return (uint64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
 +}
 +
 +#elif defined (GIT_WINDOWS_NATIVE)
 +
 +static inline uint64_t highres_nanos(void)
 +{
 +      static uint64_t high_ns, scaled_low_ns;
 +      static int scale;
 +      LARGE_INTEGER cnt;
 +
 +      if (!scale) {
 +              if (!QueryPerformanceFrequency(&cnt))
 +                      return 0;
 +
 +              /* high_ns = number of ns per cnt.HighPart */
 +              high_ns = (1000000000LL << 32) / (uint64_t) cnt.QuadPart;
 +
 +              /*
 +               * Number of ns per cnt.LowPart is 10^9 / frequency (or
 +               * high_ns >> 32). For maximum precision, we scale this factor
 +               * so that it just fits within 32 bit (i.e. won't overflow if
 +               * multiplied with cnt.LowPart).
 +               */
 +              scaled_low_ns = high_ns;
 +              scale = 32;
 +              while (scaled_low_ns >= 0x100000000LL) {
 +                      scaled_low_ns >>= 1;
 +                      scale--;
 +              }
 +      }
 +
 +      /* if QPF worked on initialization, we expect QPC to work as well */
 +      QueryPerformanceCounter(&cnt);
 +
 +      return (high_ns * cnt.HighPart) +
 +             ((scaled_low_ns * cnt.LowPart) >> scale);
 +}
 +
 +#else
 +# define highres_nanos() 0
 +#endif
 +
 +static inline uint64_t gettimeofday_nanos(void)
 +{
 +      struct timeval tv;
 +      gettimeofday(&tv, NULL);
 +      return (uint64_t) tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
 +}
 +
 +/*
 + * Returns nanoseconds since the epoch (01/01/1970), for performance tracing
 + * (i.e. favoring high precision over wall clock time accuracy).
 + */
 +inline uint64_t getnanotime(void)
 +{
 +      static uint64_t offset;
 +      if (offset > 1) {
 +              /* initialization succeeded, return offset + high res time */
 +              return offset + highres_nanos();
 +      } else if (offset == 1) {
 +              /* initialization failed, fall back to gettimeofday */
 +              return gettimeofday_nanos();
 +      } else {
 +              /* initialize offset if high resolution timer works */
 +              uint64_t now = gettimeofday_nanos();
 +              uint64_t highres = highres_nanos();
 +              if (highres)
 +                      offset = now - highres;
 +              else
 +                      offset = 1;
 +              return now;
 +      }
 +}
 +
 +static uint64_t command_start_time;
 +static struct strbuf command_line = STRBUF_INIT;
 +
 +static void print_command_performance_atexit(void)
 +{
 +      trace_performance_since(command_start_time, "git command:%s",
 +                              command_line.buf);
 +}
 +
 +void trace_command_performance(const char **argv)
 +{
 +      if (!trace_want(&trace_perf_key))
 +              return;
 +
 +      if (!command_start_time)
 +              atexit(print_command_performance_atexit);
 +
 +      strbuf_reset(&command_line);
 +      sq_quote_argv(&command_line, argv, 0);
 +      command_start_time = getnanotime();
  }
diff --cc unix-socket.c
Simple merge