Merge branch 'ao/config-from-gitmodules'
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 Jul 2018 19:20:31 +0000 (12:20 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Jul 2018 19:20:31 +0000 (12:20 -0700)
Tighten the API to make it harder to misuse in-tree .gitmodules
file, even though it shares the same syntax with configuration
files, to read random configuration items from it.

* ao/config-from-gitmodules:
submodule-config: reuse config_from_gitmodules in repo_read_gitmodules
submodule-config: pass repository as argument to config_from_gitmodules
submodule-config: make 'config_from_gitmodules' private
submodule-config: add helper to get 'update-clone' config from .gitmodules
submodule-config: add helper function to get 'fetch' config from .gitmodules
config: move config_from_gitmodules to submodule-config.c

1  2 
builtin/fetch.c
builtin/submodule--helper.c
config.c
submodule-config.c
diff --combined builtin/fetch.c
index 83f36d7cdebdede92274e661d3c97d6b999a8518,92a5d235d9164a6b0f0414a0be6a22077bcc8e2f..d9bb72bf49c164762591cfe6db10d553413939af
@@@ -6,7 -6,6 +6,7 @@@
  #include "repository.h"
  #include "refs.h"
  #include "refspec.h"
 +#include "object-store.h"
  #include "commit.h"
  #include "builtin.h"
  #include "string-list.h"
@@@ -94,19 -93,6 +94,6 @@@ static int git_fetch_config(const char 
        return git_default_config(k, v, cb);
  }
  
- static int gitmodules_fetch_config(const char *var, const char *value, void *cb)
- {
-       if (!strcmp(var, "submodule.fetchjobs")) {
-               max_children = parse_submodule_fetchjobs(var, value);
-               return 0;
-       } else if (!strcmp(var, "fetch.recursesubmodules")) {
-               recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
-               return 0;
-       }
-       return 0;
- }
  static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
  {
        /*
@@@ -778,7 -764,7 +765,7 @@@ static int store_updated_refs(const cha
        const char *what, *kind;
        struct ref *rm;
        char *url;
 -      const char *filename = dry_run ? "/dev/null" : git_path_fetch_head();
 +      const char *filename = dry_run ? "/dev/null" : git_path_fetch_head(the_repository);
        int want_status;
        int summary_width = transport_summary_width(ref_map);
  
@@@ -1030,7 -1016,7 +1017,7 @@@ static void check_not_current_branch(st
  
  static int truncate_fetch_head(void)
  {
 -      const char *filename = git_path_fetch_head();
 +      const char *filename = git_path_fetch_head(the_repository);
        FILE *fp = fopen_for_writing(filename);
  
        if (!fp)
@@@ -1434,7 -1420,7 +1421,7 @@@ int cmd_fetch(int argc, const char **ar
        for (i = 1; i < argc; i++)
                strbuf_addf(&default_rla, " %s", argv[i]);
  
-       config_from_gitmodules(gitmodules_fetch_config, NULL);
+       fetch_config_from_gitmodules(&max_children, &recurse_submodules);
        git_config(git_fetch_config, NULL);
  
        argc = parse_options(argc, argv, prefix,
        if (unshallow) {
                if (depth)
                        die(_("--depth and --unshallow cannot be used together"));
 -              else if (!is_repository_shallow())
 +              else if (!is_repository_shallow(the_repository))
                        die(_("--unshallow on a complete repository does not make sense"));
                else
                        depth = xstrfmt("%d", INFINITE_DEPTH);
index 216e3daf5c9ea95d174efc89be2f42942d85472e,110a47eca2ffcbd9e656fc8d7b2c3c82b5c36697..a3c4564c6c87255449a0a4fc800e81d2915954e2
@@@ -1124,8 -1124,6 +1124,8 @@@ static void deinit_submodule(const cha
                if (!(flags & OPT_QUIET))
                        printf(format, displaypath);
  
 +              submodule_unset_core_worktree(sub);
 +
                strbuf_release(&sb_rm);
        }
  
@@@ -1708,8 -1706,8 +1708,8 @@@ static int update_clone_task_finished(i
        return 0;
  }
  
- static int gitmodules_update_clone_config(const char *var, const char *value,
-                                         void *cb)
+ static int git_update_clone_config(const char *var, const char *value,
+                                  void *cb)
  {
        int *max_jobs = cb;
        if (!strcmp(var, "submodule.fetchjobs"))
@@@ -1759,8 -1757,8 +1759,8 @@@ static int update_clone(int argc, cons
        };
        suc.prefix = prefix;
  
-       config_from_gitmodules(gitmodules_update_clone_config, &max_jobs);
-       git_config(gitmodules_update_clone_config, &max_jobs);
+       update_clone_config_from_gitmodules(&max_jobs);
+       git_config(git_update_clone_config, &max_jobs);
  
        argc = parse_options(argc, argv, prefix, module_update_clone_options,
                             git_submodule_helper_usage, 0);
@@@ -2006,29 -2004,6 +2006,29 @@@ static int check_name(int argc, const c
        return 0;
  }
  
 +static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
 +{
 +      struct strbuf sb = STRBUF_INIT;
 +      const char *name, *path;
 +      char *sm_gitdir;
 +
 +      if (argc != 3)
 +              BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
 +
 +      name = argv[1];
 +      path = argv[2];
 +
 +      strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
 +      sm_gitdir = absolute_pathdup(sb.buf);
 +
 +      connect_work_tree_and_git_dir(path, sm_gitdir, 0);
 +
 +      strbuf_release(&sb);
 +      free(sm_gitdir);
 +
 +      return 0;
 +}
 +
  #define SUPPORT_SUPER_PREFIX (1<<0)
  
  struct cmd_struct {
@@@ -2042,7 -2017,6 +2042,7 @@@ static struct cmd_struct commands[] = 
        {"name", module_name, 0},
        {"clone", module_clone, 0},
        {"update-clone", update_clone, 0},
 +      {"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
        {"relative-path", resolve_relative_path, 0},
        {"resolve-relative-url", resolve_relative_url, 0},
        {"resolve-relative-url-test", resolve_relative_url_test, 0},
diff --combined config.c
index 139c903f6b3f1f35f2a443ebcd8b09b74ffcb7b5,fa78b1ff9272d3a7038429a427c559cccfe804ed..7968ef7566a1fc28c5d8e2ba99ae87c52fe23ece
+++ b/config.c
@@@ -14,7 -14,6 +14,7 @@@
  #include "quote.h"
  #include "hashmap.h"
  #include "string-list.h"
 +#include "object-store.h"
  #include "utf8.h"
  #include "dir.h"
  #include "color.h"
@@@ -1234,7 -1233,7 +1234,7 @@@ static int git_default_core_config(cons
                }
                eol_rndtrp_die = git_config_bool(var, value);
                global_conv_flags_eol = eol_rndtrp_die ?
 -                      CONV_EOL_RNDTRP_DIE : CONV_EOL_RNDTRP_WARN;
 +                      CONV_EOL_RNDTRP_DIE : 0;
                return 0;
        }
  
@@@ -2173,23 -2172,6 +2173,6 @@@ int git_config_get_pathname(const char 
        return repo_config_get_pathname(the_repository, key, dest);
  }
  
- /*
-  * Note: This function exists solely to maintain backward compatibility with
-  * 'fetch' and 'update_clone' storing configuration in '.gitmodules' and should
-  * NOT be used anywhere else.
-  *
-  * Runs the provided config function on the '.gitmodules' file found in the
-  * working directory.
-  */
- void config_from_gitmodules(config_fn_t fn, void *data)
- {
-       if (the_repository->worktree) {
-               char *file = repo_worktree_path(the_repository, GITMODULES_FILE);
-               git_config_from_file(fn, file, data);
-               free(file);
-       }
- }
  int git_config_get_expiry(const char *key, const char **output)
  {
        int ret = git_config_get_string_const(key, output);
diff --combined submodule-config.c
index ca324a9e37d8ce738db417e2cb689cbe0508cff0,77421a49719ababeaa23e5dbde6015244abf01ff..2a7259ba8b5297091c1f1917952cdf560e88a646
@@@ -4,7 -4,6 +4,7 @@@
  #include "submodule-config.h"
  #include "submodule.h"
  #include "strbuf.h"
 +#include "object-store.h"
  #include "parse-options.h"
  
  /*
@@@ -592,6 -591,23 +592,23 @@@ static void submodule_cache_check_init(
        submodule_cache_init(repo->submodule_cache);
  }
  
+ /*
+  * Note: This function is private for a reason, the '.gitmodules' file should
+  * not be used as as a mechanism to retrieve arbitrary configuration stored in
+  * the repository.
+  *
+  * Runs the provided config function on the '.gitmodules' file found in the
+  * working directory.
+  */
+ static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
+ {
+       if (repo->worktree) {
+               char *file = repo_worktree_path(repo, GITMODULES_FILE);
+               git_config_from_file(fn, file, data);
+               free(file);
+       }
+ }
  static int gitmodules_cb(const char *var, const char *value, void *data)
  {
        struct repository *repo = data;
@@@ -609,19 -625,11 +626,11 @@@ void repo_read_gitmodules(struct reposi
  {
        submodule_cache_check_init(repo);
  
-       if (repo->worktree) {
-               char *gitmodules;
-               if (repo_read_index(repo) < 0)
-                       return;
-               gitmodules = repo_worktree_path(repo, GITMODULES_FILE);
-               if (!is_gitmodules_unmerged(repo->index))
-                       git_config_from_file(gitmodules_cb, gitmodules, repo);
+       if (repo_read_index(repo) < 0)
+               return;
  
-               free(gitmodules);
-       }
+       if (!is_gitmodules_unmerged(repo->index))
+               config_from_gitmodules(gitmodules_cb, repo, repo);
  
        repo->submodule_cache->gitmodules_read = 1;
  }
@@@ -672,3 -680,45 +681,45 @@@ void submodule_free(struct repository *
        if (r->submodule_cache)
                submodule_cache_clear(r->submodule_cache);
  }
+ struct fetch_config {
+       int *max_children;
+       int *recurse_submodules;
+ };
+ static int gitmodules_fetch_config(const char *var, const char *value, void *cb)
+ {
+       struct fetch_config *config = cb;
+       if (!strcmp(var, "submodule.fetchjobs")) {
+               *(config->max_children) = parse_submodule_fetchjobs(var, value);
+               return 0;
+       } else if (!strcmp(var, "fetch.recursesubmodules")) {
+               *(config->recurse_submodules) = parse_fetch_recurse_submodules_arg(var, value);
+               return 0;
+       }
+       return 0;
+ }
+ void fetch_config_from_gitmodules(int *max_children, int *recurse_submodules)
+ {
+       struct fetch_config config = {
+               .max_children = max_children,
+               .recurse_submodules = recurse_submodules
+       };
+       config_from_gitmodules(gitmodules_fetch_config, the_repository, &config);
+ }
+ static int gitmodules_update_clone_config(const char *var, const char *value,
+                                         void *cb)
+ {
+       int *max_jobs = cb;
+       if (!strcmp(var, "submodule.fetchjobs"))
+               *max_jobs = parse_submodule_fetchjobs(var, value);
+       return 0;
+ }
+ void update_clone_config_from_gitmodules(int *max_jobs)
+ {
+       config_from_gitmodules(gitmodules_update_clone_config, the_repository, &max_jobs);
+ }