diff options
author | David Turner <dturner@twopensource.com> | 2016-02-24 17:58:56 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-02-25 16:01:03 -0800 |
commit | 908e95db308a9d5e24e9d547218f9ace3ad3f39b (patch) | |
tree | 968e4dafaf2c1aced39d117b49eb5b7ed119f661 | |
parent | 118e44df94cc53cd2db1d705d0cdc75b78a1c45b (diff) | |
download | git-908e95db308a9d5e24e9d547218f9ace3ad3f39b.tar.gz |
refs: check submodules' ref storage config
All submodules must have the same ref storage (for now). Confirm that
this is so before attempting to do anything with submodule refs.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | refs.c | 54 | ||||
-rw-r--r-- | refs.h | 2 | ||||
-rw-r--r-- | refs/files-backend.c | 8 |
3 files changed, 57 insertions, 7 deletions
@@ -302,6 +302,54 @@ int for_each_tag_ref(each_ref_fn fn, void *cb_data) return for_each_ref_in("refs/tags/", fn, cb_data); } +static int submodule_backend(const char *key, const char *value, void *data) +{ + const char **path = data; + char **old_path = data; + if (!strcmp(key, "extensions.refstorage") && + !git_config_string(path, key, "extensions.refstorage")) + free(*old_path); + + return 0; +} + +/* + * Check that a submodule exists. If its ref storage backend differs + * from the current backend, die. If the submodule exists, return + * 0. Else return -1. + */ +static int check_submodule_backend(const char *submodule) +{ + struct strbuf sb = STRBUF_INIT; + char *submodule_storage_backend; + int result = -1; + + if (!submodule) + return 0; + + submodule_storage_backend = xstrdup("files"); + + strbuf_addstr(&sb, submodule); + if (!is_nonbare_repository_dir(&sb)) + goto done; + + strbuf_reset(&sb); + strbuf_git_path_submodule(&sb, submodule, "config"); + + git_config_from_file(submodule_backend, sb.buf, + &submodule_storage_backend); + if (strcmp(submodule_storage_backend, ref_storage_backend)) + die(_("Ref storage '%s' for submodule '%s' does not match our storage, '%s'"), + submodule_storage_backend, submodule, ref_storage_backend); + + result = 0; +done: + free(submodule_storage_backend); + strbuf_release(&sb); + + return result; +} + int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) { return for_each_ref_in_submodule(submodule, "refs/tags/", fn, cb_data); @@ -314,6 +362,7 @@ int for_each_branch_ref(each_ref_fn fn, void *cb_data) int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) { + check_submodule_backend(submodule); return for_each_ref_in_submodule(submodule, "refs/heads/", fn, cb_data); } @@ -324,6 +373,7 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data) int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) { + check_submodule_backend(submodule); return for_each_ref_in_submodule(submodule, "refs/remotes/", fn, cb_data); } @@ -1135,6 +1185,7 @@ int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) int flag; if (submodule) { + check_submodule_backend(submodule); if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0) return fn("HEAD", &oid, 0, cb_data); @@ -1558,6 +1609,9 @@ int create_symref(const char *ref_target, const char *refs_heads_master, int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) { + if (check_submodule_backend(path)) + return -1; + return the_refs_backend->resolve_gitlink_ref(path, refname, sha1); } @@ -511,7 +511,7 @@ extern int reflog_expire(const char *refname, const unsigned char *sha1, void *policy_cb_data); /* - * Read the refdb storage backend name out of the config file + * Read the ref storage backend name out of the config file */ int ref_storage_backend_config(const char *var, const char *value, void *ptr); diff --git a/refs/files-backend.c b/refs/files-backend.c index 5821adb9bb..707f1ec9c1 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1355,13 +1355,9 @@ static int files_resolve_gitlink_ref(const char *path, const char *refname, strbuf_add(&submodule, path, len); refs = lookup_ref_cache(submodule.buf); - if (!refs) { - if (!is_nonbare_repository_dir(&submodule)) { - strbuf_release(&submodule); - return -1; - } + if (!refs) refs = create_ref_cache(submodule.buf); - } + strbuf_release(&submodule); retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0); |