]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Sync with 2.17.2
authorJunio C Hamano <gitster@pobox.com>
Thu, 27 Sep 2018 18:45:01 +0000 (11:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 27 Sep 2018 18:45:01 +0000 (11:45 -0700)
* maint-2.17:
  Git 2.17.2
  fsck: detect submodule paths starting with dash
  fsck: detect submodule urls starting with dash
  Git 2.16.5
  Git 2.15.3
  Git 2.14.5
  submodule-config: ban submodule paths that start with a dash
  submodule-config: ban submodule urls that start with dash
  submodule--helper: use "--" to signal end of clone options

1  2 
builtin/submodule--helper.c
fsck.c
submodule-config.c

index bd250ca2164b31356fb42406351761cd2381d115,a9187c6f0cba9bc56739f2c5a46030fbf7688f30..1902b6c3199e104416b430d5a1ae2ac06d7c899d
  #include "run-command.h"
  #include "remote.h"
  #include "refs.h"
 +#include "refspec.h"
  #include "connect.h"
  #include "revision.h"
  #include "diffcore.h"
  #include "diff.h"
 +#include "object-store.h"
  
  #define OPT_QUIET (1 << 0)
  #define OPT_CACHED (1 << 1)
@@@ -456,7 -454,7 +456,7 @@@ static void init_submodule(const char *
  
        displaypath = get_submodule_displaypath(path, prefix);
  
 -      sub = submodule_from_path(&null_oid, path);
 +      sub = submodule_from_path(the_repository, &null_oid, path);
  
        if (!sub)
                die(_("No url found for submodule path '%s' in .gitmodules"),
@@@ -597,12 -595,8 +597,12 @@@ static void print_status(unsigned int f
  
        printf("%c%s %s", state, oid_to_hex(oid), displaypath);
  
 -      if (state == ' ' || state == '+')
 -              printf(" (%s)", compute_rev_name(path, oid_to_hex(oid)));
 +      if (state == ' ' || state == '+') {
 +              const char *name = compute_rev_name(path, oid_to_hex(oid));
 +
 +              if (name)
 +                      printf(" (%s)", name);
 +      }
  
        printf("\n");
  }
@@@ -627,7 -621,7 +627,7 @@@ static void status_submodule(const cha
        struct rev_info rev;
        int diff_files_result;
  
 -      if (!submodule_from_path(&null_oid, path))
 +      if (!submodule_from_path(the_repository, &null_oid, path))
                die(_("no submodule mapping found in .gitmodules for path '%s'"),
                      path);
  
                             displaypath);
        } else if (!(flags & OPT_CACHED)) {
                struct object_id oid;
 +              struct ref_store *refs = get_submodule_ref_store(path);
  
 -              if (refs_head_ref(get_submodule_ref_store(path),
 -                                handle_submodule_head_ref, &oid))
 +              if (!refs) {
 +                      print_status(flags, '-', path, ce_oid, displaypath);
 +                      goto cleanup;
 +              }
 +              if (refs_head_ref(refs, handle_submodule_head_ref, &oid))
                        die(_("could not resolve HEAD ref inside the "
                              "submodule '%s'"), path);
  
@@@ -751,7 -741,7 +751,7 @@@ static int module_name(int argc, const 
        if (argc != 2)
                usage(_("git submodule--helper name <path>"));
  
 -      sub = submodule_from_path(&null_oid, argv[1]);
 +      sub = submodule_from_path(the_repository, &null_oid, argv[1]);
  
        if (!sub)
                die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@@ -782,7 -772,7 +782,7 @@@ static void sync_submodule(const char *
        if (!is_submodule_active(the_repository, path))
                return;
  
 -      sub = submodule_from_path(&null_oid, path);
 +      sub = submodule_from_path(the_repository, &null_oid, path);
  
        if (sub && sub->url) {
                if (starts_with_dot_dot_slash(sub->url) ||
@@@ -935,7 -925,7 +935,7 @@@ static void deinit_submodule(const cha
        struct strbuf sb_config = STRBUF_INIT;
        char *sub_git_dir = xstrfmt("%s/.git", path);
  
 -      sub = submodule_from_path(&null_oid, path);
 +      sub = submodule_from_path(the_repository, &null_oid, path);
  
        if (!sub || !sub->name)
                goto cleanup;
@@@ -1066,7 -1056,7 +1066,7 @@@ static int module_deinit(int argc, cons
  }
  
  static int clone_submodule(const char *path, const char *gitdir, const char *url,
 -                         const char *depth, struct string_list *reference,
 +                         const char *depth, struct string_list *reference, int dissociate,
                           int quiet, int progress)
  {
        struct child_process cp = CHILD_PROCESS_INIT;
                        argv_array_pushl(&cp.args, "--reference",
                                         item->string, NULL);
        }
 +      if (dissociate)
 +              argv_array_push(&cp.args, "--dissociate");
        if (gitdir && *gitdir)
                argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
  
+       argv_array_push(&cp.args, "--");
        argv_array_push(&cp.args, url);
        argv_array_push(&cp.args, path);
  
@@@ -1202,7 -1191,6 +1203,7 @@@ static int module_clone(int argc, cons
        char *p, *path = NULL, *sm_gitdir;
        struct strbuf sb = STRBUF_INIT;
        struct string_list reference = STRING_LIST_INIT_NODUP;
 +      int dissociate = 0;
        char *sm_alternate = NULL, *error_strategy = NULL;
  
        struct option module_clone_options[] = {
                OPT_STRING_LIST(0, "reference", &reference,
                           N_("repo"),
                           N_("reference repository")),
 +              OPT_BOOL(0, "dissociate", &dissociate,
 +                         N_("use --reference only while cloning")),
                OPT_STRING(0, "depth", &depth,
                           N_("string"),
                           N_("depth for shallow clones")),
  
                prepare_possible_alternates(name, &reference);
  
 -              if (clone_submodule(path, sm_gitdir, url, depth, &reference,
 +              if (clone_submodule(path, sm_gitdir, url, depth, &reference, dissociate,
                                    quiet, progress))
                        die(_("clone of '%s' into submodule path '%s' failed"),
                            url, path);
                strbuf_reset(&sb);
        }
  
 -      /* Connect module worktree and git dir */
 -      connect_work_tree_and_git_dir(path, sm_gitdir);
 +      connect_work_tree_and_git_dir(path, sm_gitdir, 0);
  
        p = git_pathdup_submodule(path, "config");
        if (!p)
@@@ -1314,7 -1301,6 +1315,7 @@@ struct submodule_update_clone 
        int quiet;
        int recommend_shallow;
        struct string_list references;
 +      int dissociate;
        const char *depth;
        const char *recursive_prefix;
        const char *prefix;
        int failed_clones_nr, failed_clones_alloc;
  };
  #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 -      SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, \
 +      SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
        NULL, NULL, NULL, \
        STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
  
@@@ -1382,7 -1368,7 +1383,7 @@@ static int prepare_to_clone_next_submod
                goto cleanup;
        }
  
 -      sub = submodule_from_path(&null_oid, ce->name);
 +      sub = submodule_from_path(the_repository, &null_oid, ce->name);
  
        if (suc->recursive_prefix)
                displaypath = relative_path(suc->recursive_prefix,
                for_each_string_list_item(item, &suc->references)
                        argv_array_pushl(&child->args, "--reference", item->string, NULL);
        }
 +      if (suc->dissociate)
 +              argv_array_push(&child->args, "--dissociate");
        if (suc->depth)
                argv_array_push(&child->args, suc->depth);
  
@@@ -1592,8 -1576,6 +1593,8 @@@ static int update_clone(int argc, cons
                           N_("rebase, merge, checkout or none")),
                OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
                           N_("reference repository")),
 +              OPT_BOOL(0, "dissociate", &suc.dissociate,
 +                         N_("use --reference only while cloning")),
                OPT_STRING(0, "depth", &suc.depth, "<depth>",
                           N_("Create a shallow clone truncated to the "
                              "specified number of revisions")),
@@@ -1669,7 -1651,7 +1670,7 @@@ static const char *remote_submodule_bra
        const char *branch = NULL;
        char *key;
  
 -      sub = submodule_from_path(&null_oid, path);
 +      sub = submodule_from_path(the_repository, &null_oid, path);
        if (!sub)
                return NULL;
  
@@@ -1754,14 -1736,13 +1755,14 @@@ static int push_check(int argc, const c
  
        /* Check the refspec */
        if (argc > 2) {
 -              int i, refspec_nr = argc - 2;
 +              int i;
                struct ref *local_refs = get_local_heads();
 -              struct refspec *refspec = parse_push_refspec(refspec_nr,
 -                                                           argv + 2);
 +              struct refspec refspec = REFSPEC_INIT_PUSH;
 +
 +              refspec_appendn(&refspec, argv + 2, argc - 2);
  
 -              for (i = 0; i < refspec_nr; i++) {
 -                      struct refspec *rs = refspec + i;
 +              for (i = 0; i < refspec.nr; i++) {
 +                      const struct refspec_item *rs = &refspec.items[i];
  
                        if (rs->pattern || rs->matching)
                                continue;
                                    rs->src);
                        }
                }
 -              free_refspec(refspec_nr, refspec);
 +              refspec_clear(&refspec);
        }
        free(head);
  
diff --combined fsck.c
index 48e7e36869a7cbcb47e2e2a0401dd1047612e5d7,5d9b25fac0aebe677dcde3181d7edb3eff820515..51f61ffbc21918361111a2e1069be3aac54b6584
--- 1/fsck.c
--- 2/fsck.c
+++ b/fsck.c
@@@ -64,6 -64,8 +64,8 @@@ static struct oidset gitmodules_done = 
        FUNC(GITMODULES_PARSE, ERROR) \
        FUNC(GITMODULES_NAME, ERROR) \
        FUNC(GITMODULES_SYMLINK, ERROR) \
+       FUNC(GITMODULES_URL, ERROR) \
+       FUNC(GITMODULES_PATH, ERROR) \
        /* warnings */ \
        FUNC(BAD_FILEMODE, WARN) \
        FUNC(EMPTY_NAME, WARN) \
@@@ -409,11 -411,9 +411,11 @@@ static int fsck_walk_commit(struct comm
  
        name = get_object_name(options, &commit->object);
        if (name)
 -              put_object_name(options, &commit->tree->object, "%s:", name);
 +              put_object_name(options, &get_commit_tree(commit)->object,
 +                              "%s:", name);
  
 -      result = options->walk((struct object *)commit->tree, OBJ_TREE, data, options);
 +      result = options->walk((struct object *)get_commit_tree(commit),
 +                             OBJ_TREE, data, options);
        if (result < 0)
                return result;
        res = result;
@@@ -734,31 -734,30 +736,31 @@@ static int fsck_ident(const char **iden
  static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        unsigned long size, struct fsck_options *options)
  {
 -      unsigned char tree_sha1[20], sha1[20];
 +      struct object_id tree_oid, oid;
        struct commit_graft *graft;
        unsigned parent_count, parent_line_count = 0, author_count;
        int err;
        const char *buffer_begin = buffer;
 +      const char *p;
  
        if (verify_headers(buffer, size, &commit->object, options))
                return -1;
  
        if (!skip_prefix(buffer, "tree ", &buffer))
                return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
 -      if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') {
 +      if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') {
                err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
                if (err)
                        return err;
        }
 -      buffer += 41;
 +      buffer = p + 1;
        while (skip_prefix(buffer, "parent ", &buffer)) {
 -              if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') {
 +              if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
                        err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
                        if (err)
                                return err;
                }
 -              buffer += 41;
 +              buffer = p + 1;
                parent_line_count++;
        }
        graft = lookup_commit_graft(&commit->object.oid);
        err = fsck_ident(&buffer, &commit->object, options);
        if (err)
                return err;
 -      if (!commit->tree) {
 -              err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
 +      if (!get_commit_tree(commit)) {
 +              err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", oid_to_hex(&tree_oid));
                if (err)
                        return err;
        }
@@@ -823,12 -822,11 +825,12 @@@ static int fsck_commit(struct commit *c
  static int fsck_tag_buffer(struct tag *tag, const char *data,
        unsigned long size, struct fsck_options *options)
  {
 -      unsigned char sha1[20];
 +      struct object_id oid;
        int ret = 0;
        const char *buffer;
        char *to_free = NULL, *eol;
        struct strbuf sb = STRBUF_INIT;
 +      const char *p;
  
        if (data)
                buffer = data;
                enum object_type type;
  
                buffer = to_free =
 -                      read_sha1_file(tag->object.oid.hash, &type, &size);
 +                      read_object_file(&tag->object.oid, &type, &size);
                if (!buffer)
                        return report(options, &tag->object,
                                FSCK_MSG_MISSING_TAG_OBJECT,
                ret = report(options, &tag->object, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
                goto done;
        }
 -      if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') {
 +      if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
                ret = report(options, &tag->object, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
                if (ret)
                        goto done;
        }
 -      buffer += 41;
 +      buffer = p + 1;
  
        if (!skip_prefix(buffer, "type ", &buffer)) {
                ret = report(options, &tag->object, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line");
@@@ -949,6 -947,18 +951,18 @@@ static int fsck_gitmodules_fn(const cha
                                    FSCK_MSG_GITMODULES_NAME,
                                    "disallowed submodule name: %s",
                                    name);
+       if (!strcmp(key, "url") && value &&
+           looks_like_command_line_option(value))
+               data->ret |= report(data->options, data->obj,
+                                   FSCK_MSG_GITMODULES_URL,
+                                   "disallowed submodule url: %s",
+                                   value);
+       if (!strcmp(key, "path") && value &&
+           looks_like_command_line_option(value))
+               data->ret |= report(data->options, data->obj,
+                                   FSCK_MSG_GITMODULES_PATH,
+                                   "disallowed submodule path: %s",
+                                   value);
        free(name);
  
        return 0;
@@@ -1036,14 -1046,13 +1050,14 @@@ int fsck_finish(struct fsck_options *op
  
                blob = lookup_blob(oid);
                if (!blob) {
 -                      ret |= report(options, &blob->object,
 +                      struct object *obj = lookup_unknown_object(oid->hash);
 +                      ret |= report(options, obj,
                                      FSCK_MSG_GITMODULES_BLOB,
                                      "non-blob found at .gitmodules");
                        continue;
                }
  
 -              buf = read_sha1_file(oid->hash, &type, &size);
 +              buf = read_object_file(oid, &type, &size);
                if (!buf) {
                        if (is_promisor_object(&blob->object.oid))
                                continue;
diff --combined submodule-config.c
index 388ef1f892bdd63a485d9c93810a945fc3eab46f,3c40f1f1c5c96e00534ccc4e917a381b933006e8..6b212bae31c31edb651a381cfb473d3de7ae7ca6
@@@ -44,7 -44,7 +44,7 @@@ static int config_path_cmp(const void *
        const struct submodule_entry *b = entry_or_key;
  
        return strcmp(a->config->path, b->config->path) ||
 -             hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1);
 +             oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
  }
  
  static int config_name_cmp(const void *unused_cmp_data,
@@@ -56,7 -56,7 +56,7 @@@
        const struct submodule_entry *b = entry_or_key;
  
        return strcmp(a->config->name, b->config->name) ||
 -             hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1);
 +             oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
  }
  
  static struct submodule_cache *submodule_cache_alloc(void)
@@@ -109,17 -109,17 +109,17 @@@ void submodule_cache_free(struct submod
        free(cache);
  }
  
 -static unsigned int hash_sha1_string(const unsigned char *sha1,
 -                                   const char *string)
 +static unsigned int hash_oid_string(const struct object_id *oid,
 +                                  const char *string)
  {
 -      return memhash(sha1, 20) + strhash(string);
 +      return memhash(oid->hash, the_hash_algo->rawsz) + strhash(string);
  }
  
  static void cache_put_path(struct submodule_cache *cache,
                           struct submodule *submodule)
  {
 -      unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
 -                                           submodule->path);
 +      unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
 +                                          submodule->path);
        struct submodule_entry *e = xmalloc(sizeof(*e));
        hashmap_entry_init(e, hash);
        e->config = submodule;
  static void cache_remove_path(struct submodule_cache *cache,
                              struct submodule *submodule)
  {
 -      unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
 -                                           submodule->path);
 +      unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
 +                                          submodule->path);
        struct submodule_entry e;
        struct submodule_entry *removed;
        hashmap_entry_init(&e, hash);
  static void cache_add(struct submodule_cache *cache,
                      struct submodule *submodule)
  {
 -      unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
 -                                           submodule->name);
 +      unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
 +                                          submodule->name);
        struct submodule_entry *e = xmalloc(sizeof(*e));
        hashmap_entry_init(e, hash);
        e->config = submodule;
  }
  
  static const struct submodule *cache_lookup_path(struct submodule_cache *cache,
 -              const unsigned char *gitmodules_sha1, const char *path)
 +              const struct object_id *gitmodules_oid, const char *path)
  {
        struct submodule_entry *entry;
 -      unsigned int hash = hash_sha1_string(gitmodules_sha1, path);
 +      unsigned int hash = hash_oid_string(gitmodules_oid, path);
        struct submodule_entry key;
        struct submodule key_config;
  
 -      hashcpy(key_config.gitmodules_sha1, gitmodules_sha1);
 +      oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
        key_config.path = path;
  
        hashmap_entry_init(&key, hash);
  }
  
  static struct submodule *cache_lookup_name(struct submodule_cache *cache,
 -              const unsigned char *gitmodules_sha1, const char *name)
 +              const struct object_id *gitmodules_oid, const char *name)
  {
        struct submodule_entry *entry;
 -      unsigned int hash = hash_sha1_string(gitmodules_sha1, name);
 +      unsigned int hash = hash_oid_string(gitmodules_oid, name);
        struct submodule_entry key;
        struct submodule key_config;
  
 -      hashcpy(key_config.gitmodules_sha1, gitmodules_sha1);
 +      oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
        key_config.name = name;
  
        hashmap_entry_init(&key, hash);
@@@ -238,12 -238,12 +238,12 @@@ static int name_and_item_from_var(cons
  }
  
  static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
 -              const unsigned char *gitmodules_sha1, const char *name)
 +              const struct object_id *gitmodules_oid, const char *name)
  {
        struct submodule *submodule;
        struct strbuf name_buf = STRBUF_INIT;
  
 -      submodule = cache_lookup_name(cache, gitmodules_sha1, name);
 +      submodule = cache_lookup_name(cache, gitmodules_oid, name);
        if (submodule)
                return submodule;
  
        submodule->branch = NULL;
        submodule->recommend_shallow = -1;
  
 -      hashcpy(submodule->gitmodules_sha1, gitmodules_sha1);
 +      oidcpy(&submodule->gitmodules_oid, gitmodules_oid);
  
        cache_add(cache, submodule);
  
@@@ -372,21 -372,27 +372,27 @@@ int parse_push_recurse_submodules_arg(c
        return parse_push_recurse(opt, arg, 1);
  }
  
 -static void warn_multiple_config(const unsigned char *treeish_name,
 +static void warn_multiple_config(const struct object_id *treeish_name,
                                 const char *name, const char *option)
  {
        const char *commit_string = "WORKTREE";
        if (treeish_name)
 -              commit_string = sha1_to_hex(treeish_name);
 +              commit_string = oid_to_hex(treeish_name);
        warning("%s:.gitmodules, multiple configurations found for "
                        "'submodule.%s.%s'. Skipping second one!",
                        commit_string, name, option);
  }
  
+ static void warn_command_line_option(const char *var, const char *value)
+ {
+       warning(_("ignoring '%s' which may be interpreted as"
+                 " a command-line option: %s"), var, value);
+ }
  struct parse_config_parameter {
        struct submodule_cache *cache;
 -      const unsigned char *treeish_name;
 -      const unsigned char *gitmodules_sha1;
 +      const struct object_id *treeish_name;
 +      const struct object_id *gitmodules_oid;
        int overwrite;
  };
  
@@@ -402,12 -408,14 +408,14 @@@ static int parse_config(const char *var
                return 0;
  
        submodule = lookup_or_create_by_name(me->cache,
 -                                           me->gitmodules_sha1,
 +                                           me->gitmodules_oid,
                                             name.buf);
  
        if (!strcmp(item.buf, "path")) {
                if (!value)
                        ret = config_error_nonbool(var);
+               else if (looks_like_command_line_option(value))
+                       warn_command_line_option(var, value);
                else if (!me->overwrite && submodule->path)
                        warn_multiple_config(me->treeish_name, submodule->name,
                                        "path");
                }
        } else if (!strcmp(item.buf, "fetchrecursesubmodules")) {
                /* when parsing worktree configurations we can die early */
 -              int die_on_error = is_null_sha1(me->gitmodules_sha1);
 +              int die_on_error = is_null_oid(me->gitmodules_oid);
                if (!me->overwrite &&
                    submodule->fetch_recurse != RECURSE_SUBMODULES_NONE)
                        warn_multiple_config(me->treeish_name, submodule->name,
        } else if (!strcmp(item.buf, "url")) {
                if (!value) {
                        ret = config_error_nonbool(var);
+               } else if (looks_like_command_line_option(value)) {
+                       warn_command_line_option(var, value);
                } else if (!me->overwrite && submodule->url) {
                        warn_multiple_config(me->treeish_name, submodule->name,
                                        "url");
@@@ -542,23 -552,23 +552,23 @@@ static const struct submodule *config_f
  
        switch (lookup_type) {
        case lookup_name:
 -              submodule = cache_lookup_name(cache, oid.hash, key);
 +              submodule = cache_lookup_name(cache, &oid, key);
                break;
        case lookup_path:
 -              submodule = cache_lookup_path(cache, oid.hash, key);
 +              submodule = cache_lookup_path(cache, &oid, key);
                break;
        }
        if (submodule)
                goto out;
  
 -      config = read_sha1_file(oid.hash, &type, &config_size);
 +      config = read_object_file(&oid, &type, &config_size);
        if (!config || type != OBJ_BLOB)
                goto out;
  
        /* fill the submodule config into the cache */
        parameter.cache = cache;
 -      parameter.treeish_name = treeish_name->hash;
 -      parameter.gitmodules_sha1 = oid.hash;
 +      parameter.treeish_name = treeish_name;
 +      parameter.gitmodules_oid = &oid;
        parameter.overwrite = 0;
        git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,
                        config, config_size, &parameter);
  
        switch (lookup_type) {
        case lookup_name:
 -              return cache_lookup_name(cache, oid.hash, key);
 +              return cache_lookup_name(cache, &oid, key);
        case lookup_path:
 -              return cache_lookup_path(cache, oid.hash, key);
 +              return cache_lookup_path(cache, &oid, key);
        default:
                return NULL;
        }
@@@ -598,7 -608,7 +608,7 @@@ static int gitmodules_cb(const char *va
  
        parameter.cache = repo->submodule_cache;
        parameter.treeish_name = NULL;
 -      parameter.gitmodules_sha1 = null_sha1;
 +      parameter.gitmodules_oid = &null_oid;
        parameter.overwrite = 1;
  
        return parse_config(var, value, &parameter);
@@@ -650,24 -660,31 +660,24 @@@ static void gitmodules_read_check(struc
                repo_read_gitmodules(repo);
  }
  
 -const struct submodule *submodule_from_name(const struct object_id *treeish_name,
 +const struct submodule *submodule_from_name(struct repository *r,
 +                                          const struct object_id *treeish_name,
                const char *name)
  {
 -      gitmodules_read_check(the_repository);
 -      return config_from(the_repository->submodule_cache, treeish_name, name, lookup_name);
 +      gitmodules_read_check(r);
 +      return config_from(r->submodule_cache, treeish_name, name, lookup_name);
  }
  
 -const struct submodule *submodule_from_path(const struct object_id *treeish_name,
 +const struct submodule *submodule_from_path(struct repository *r,
 +                                          const struct object_id *treeish_name,
                const char *path)
  {
 -      gitmodules_read_check(the_repository);
 -      return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path);
 +      gitmodules_read_check(r);
 +      return config_from(r->submodule_cache, treeish_name, path, lookup_path);
  }
  
 -const struct submodule *submodule_from_cache(struct repository *repo,
 -                                           const struct object_id *treeish_name,
 -                                           const char *key)
 +void submodule_free(struct repository *r)
  {
 -      gitmodules_read_check(repo);
 -      return config_from(repo->submodule_cache, treeish_name,
 -                         key, lookup_path);
 -}
 -
 -void submodule_free(void)
 -{
 -      if (the_repository->submodule_cache)
 -              submodule_cache_clear(the_repository->submodule_cache);
 +      if (r->submodule_cache)
 +              submodule_cache_clear(r->submodule_cache);
  }