Merge branch 'mk/submodule-gitdir-path' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 3 Nov 2015 23:32:34 +0000 (15:32 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 3 Nov 2015 23:32:35 +0000 (15:32 -0800)
The submodule code has been taught to work better with separate
work trees created via "git worktree add".

* mk/submodule-gitdir-path:
path: implement common_dir handling in git_pathdup_submodule()
submodule refactor: use strbuf_git_path_submodule() in add_submodule_odb()

1  2 
cache.h
path.c
setup.c
diff --combined cache.h
index df3192144a365ba8eaa1dbf20213793b706c035c,5eb36b413ce9a26851687d89d49fc964ed745098..d941224de5952292050bee72fea1e9ec2b1376c6
+++ b/cache.h
@@@ -443,6 -443,7 +443,7 @@@ extern char *get_object_directory(void)
  extern char *get_index_file(void);
  extern char *get_graft_file(void);
  extern int set_git_dir(const char *path);
+ extern int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
  extern int get_common_dir(struct strbuf *sb, const char *gitdir);
  extern const char *get_git_namespace(void);
  extern const char *strip_namespace(const char *namespaced_ref);
@@@ -696,15 -697,8 +697,15 @@@ extern char *notes_ref_name
  
  extern int grafts_replace_parents;
  
 +/*
 + * GIT_REPO_VERSION is the version we write by default. The
 + * _READ variant is the highest number we know how to
 + * handle.
 + */
  #define GIT_REPO_VERSION 0
 +#define GIT_REPO_VERSION_READ 1
  extern int repository_format_version;
 +extern int repository_format_precious_objects;
  extern int check_repository_format(void);
  
  #define MTIME_CHANGED 0x0001
@@@ -1282,7 -1276,6 +1283,7 @@@ extern void close_pack_index(struct pac
  
  extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
  extern void close_pack_windows(struct packed_git *);
 +extern void close_all_packs(void);
  extern void unuse_pack(struct pack_window **);
  extern void free_pack_by_name(const char *);
  extern void clear_delta_base_cache(void);
diff --combined path.c
index 58d5620b98c22f85e252f48817e8cf58ffcf4dd3,22b9e0b8d8d392a31cb61a91fb9aeb32529e2d5b..69265f42cec4cfb19f6651b0dc845d2ab744711d
--- 1/path.c
--- 2/path.c
+++ b/path.c
@@@ -98,7 -98,7 +98,7 @@@ static const char *common_list[] = 
        NULL
  };
  
- static void update_common_dir(struct strbuf *buf, int git_dir_len)
+ static void update_common_dir(struct strbuf *buf, int git_dir_len, const char *common_dir)
  {
        char *base = buf->buf + git_dir_len;
        const char **p;
                        path++;
                        is_dir = 1;
                }
+               if (!common_dir)
+                       common_dir = get_git_common_dir();
                if (is_dir && dir_prefix(base, path)) {
-                       replace_dir(buf, git_dir_len, get_git_common_dir());
+                       replace_dir(buf, git_dir_len, common_dir);
                        return;
                }
                if (!is_dir && !strcmp(base, path)) {
-                       replace_dir(buf, git_dir_len, get_git_common_dir());
+                       replace_dir(buf, git_dir_len, common_dir);
                        return;
                }
        }
@@@ -160,7 -164,7 +164,7 @@@ static void adjust_git_path(struct strb
        else if (git_db_env && dir_prefix(base, "objects"))
                replace_dir(buf, git_dir_len + 7, get_object_directory());
        else if (git_common_dir_env)
-               update_common_dir(buf, git_dir_len);
+               update_common_dir(buf, git_dir_len, NULL);
  }
  
  static void do_git_path(struct strbuf *buf, const char *fmt, va_list args)
@@@ -228,6 -232,8 +232,8 @@@ static void do_submodule_path(struct st
                              const char *fmt, va_list args)
  {
        const char *git_dir;
+       struct strbuf git_submodule_common_dir = STRBUF_INIT;
+       struct strbuf git_submodule_dir = STRBUF_INIT;
  
        strbuf_addstr(buf, path);
        if (buf->len && buf->buf[buf->len - 1] != '/')
                strbuf_addstr(buf, git_dir);
        }
        strbuf_addch(buf, '/');
+       strbuf_addstr(&git_submodule_dir, buf->buf);
  
        strbuf_vaddf(buf, fmt, args);
+       if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf))
+               update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf);
        strbuf_cleanup_path(buf);
+       strbuf_release(&git_submodule_dir);
+       strbuf_release(&git_submodule_common_dir);
  }
  
  char *git_pathdup_submodule(const char *path, const char *fmt, ...)
@@@ -676,11 -690,6 +690,11 @@@ const char *remove_leading_path(const c
   * normalized, any time "../" eats up to the prefix_len part,
   * prefix_len is reduced. In the end prefix_len is the remaining
   * prefix that has not been overridden by user pathspec.
 + *
 + * NEEDSWORK: This function doesn't perform normalization w.r.t. trailing '/'.
 + * For everything but the root folder itself, the normalized path should not
 + * end with a '/', then the callers need to be fixed up accordingly.
 + *
   */
  int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
  {
diff --combined setup.c
index 3324014cb7ac825fa9703cc6568190460e9cd87d,e41e5e1a82e3cbd9e0168e158b336f621116adc7..1a374f2bf4f986b00727ee04da6a65f8f914e35f
+++ b/setup.c
@@@ -5,7 -5,6 +5,7 @@@
  static int inside_git_dir = -1;
  static int inside_work_tree = -1;
  static int work_tree_config_is_bogus;
 +static struct string_list unknown_extensions = STRING_LIST_INIT_DUP;
  
  /*
   * The input parameter must contain an absolute path, and it must already be
@@@ -229,15 -228,22 +229,22 @@@ void verify_non_filename(const char *pr
  }
  
  int get_common_dir(struct strbuf *sb, const char *gitdir)
+ {
+       const char *git_env_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+       if (git_env_common_dir) {
+               strbuf_addstr(sb, git_env_common_dir);
+               return 1;
+       } else {
+               return get_common_dir_noenv(sb, gitdir);
+       }
+ }
+ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
  {
        struct strbuf data = STRBUF_INIT;
        struct strbuf path = STRBUF_INIT;
-       const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
        int ret = 0;
-       if (git_common_dir) {
-               strbuf_addstr(sb, git_common_dir);
-               return 1;
-       }
        strbuf_addf(&path, "%s/commondir", gitdir);
        if (file_exists(path.buf)) {
                if (strbuf_read_file(&data, path.buf, 0) <= 0)
@@@ -353,25 -359,10 +360,25 @@@ void setup_work_tree(void
  
  static int check_repo_format(const char *var, const char *value, void *cb)
  {
 +      const char *ext;
 +
        if (strcmp(var, "core.repositoryformatversion") == 0)
                repository_format_version = git_config_int(var, value);
        else if (strcmp(var, "core.sharedrepository") == 0)
                shared_repository = git_config_perm(var, value);
 +      else if (skip_prefix(var, "extensions.", &ext)) {
 +              /*
 +               * record any known extensions here; otherwise,
 +               * we fall through to recording it as unknown, and
 +               * check_repository_format will complain
 +               */
 +              if (!strcmp(ext, "noop"))
 +                      ;
 +              else if (!strcmp(ext, "preciousobjects"))
 +                      repository_format_precious_objects = git_config_bool(var, value);
 +              else
 +                      string_list_append(&unknown_extensions, ext);
 +      }
        return 0;
  }
  
@@@ -382,8 -373,6 +389,8 @@@ static int check_repository_format_gent
        config_fn_t fn;
        int ret = 0;
  
 +      string_list_clear(&unknown_extensions, 0);
 +
        if (get_common_dir(&sb, gitdir))
                fn = check_repo_format;
        else
         * is a good one.
         */
        git_config_early(fn, NULL, repo_config);
 -      if (GIT_REPO_VERSION < repository_format_version) {
 +      if (GIT_REPO_VERSION_READ < repository_format_version) {
                if (!nongit_ok)
                        die ("Expected git repo version <= %d, found %d",
 -                           GIT_REPO_VERSION, repository_format_version);
 +                           GIT_REPO_VERSION_READ, repository_format_version);
                warning("Expected git repo version <= %d, found %d",
 -                      GIT_REPO_VERSION, repository_format_version);
 +                      GIT_REPO_VERSION_READ, repository_format_version);
                warning("Please upgrade Git");
                *nongit_ok = -1;
                ret = -1;
        }
 +
 +      if (repository_format_version >= 1 && unknown_extensions.nr) {
 +              int i;
 +
 +              if (!nongit_ok)
 +                      die("unknown repository extension: %s",
 +                          unknown_extensions.items[0].string);
 +
 +              for (i = 0; i < unknown_extensions.nr; i++)
 +                      warning("unknown repository extension: %s",
 +                              unknown_extensions.items[i].string);
 +              *nongit_ok = -1;
 +              ret = -1;
 +      }
 +
        strbuf_release(&sb);
        return ret;
  }