提交 614ea03a 编写于 作者: J Junio C Hamano

Merge branch 'bw/submodule-config-cleanup'

Code clean-up to avoid mixing values read from the .gitmodules file
and values read from the .git/config file.

* bw/submodule-config-cleanup:
  submodule: remove gitmodules_config
  unpack-trees: improve loading of .gitmodules
  submodule-config: lazy-load a repository's .gitmodules file
  submodule-config: move submodule-config functions to submodule-config.c
  submodule-config: remove support for overlaying repository config
  diff: stop allowing diff to have submodules configured in .git/config
  submodule: remove submodule_config callback routine
  unpack-trees: don't respect submodule.update
  submodule: don't rely on overlayed config when setting diffopts
  fetch: don't overlay config with submodule-config
  submodule--helper: don't overlay config in update-clone
  submodule--helper: don't overlay config in remote_submodule_branch
  add, reset: ensure submodules can be added or reset
  submodule: don't use submodule_from_name
  t7411: check configuration parsing errors
...@@ -116,6 +116,7 @@ int add_files_to_cache(const char *prefix, ...@@ -116,6 +116,7 @@ int add_files_to_cache(const char *prefix,
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback; rev.diffopt.format_callback = update_callback;
rev.diffopt.format_callback_data = &data; rev.diffopt.format_callback_data = &data;
rev.diffopt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
return !!data.add_errors; return !!data.add_errors;
......
...@@ -861,7 +861,7 @@ static int git_checkout_config(const char *var, const char *value, void *cb) ...@@ -861,7 +861,7 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
} }
if (starts_with(var, "submodule.")) if (starts_with(var, "submodule."))
return submodule_config(var, value, NULL); return git_default_submodule_config(var, value, NULL);
return git_xmerge_config(var, value, NULL); return git_xmerge_config(var, value, NULL);
} }
...@@ -1182,7 +1182,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) ...@@ -1182,7 +1182,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.prefix = prefix; opts.prefix = prefix;
opts.show_progress = -1; opts.show_progress = -1;
gitmodules_config();
git_config(git_checkout_config, &opts); git_config(git_checkout_config, &opts);
opts.track = BRANCH_TRACK_UNSPECIFIED; opts.track = BRANCH_TRACK_UNSPECIFIED;
......
...@@ -195,7 +195,6 @@ static void determine_whence(struct wt_status *s) ...@@ -195,7 +195,6 @@ static void determine_whence(struct wt_status *s)
static void status_init_config(struct wt_status *s, config_fn_t fn) static void status_init_config(struct wt_status *s, config_fn_t fn)
{ {
wt_status_prepare(s); wt_status_prepare(s);
gitmodules_config();
git_config(fn, s); git_config(fn, s);
determine_whence(s); determine_whence(s);
init_diff_ui_defaults(); init_diff_ui_defaults();
......
...@@ -26,7 +26,6 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) ...@@ -26,7 +26,6 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix); init_revisions(&rev, prefix);
gitmodules_config();
rev.abbrev = 0; rev.abbrev = 0;
precompose_argv(argc, argv); precompose_argv(argc, argv);
......
...@@ -23,7 +23,6 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) ...@@ -23,7 +23,6 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix); init_revisions(&rev, prefix);
gitmodules_config();
rev.abbrev = 0; rev.abbrev = 0;
precompose_argv(argc, argv); precompose_argv(argc, argv);
......
...@@ -110,7 +110,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) ...@@ -110,7 +110,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(opt, prefix); init_revisions(opt, prefix);
gitmodules_config();
opt->abbrev = 0; opt->abbrev = 0;
opt->diff = 1; opt->diff = 1;
opt->disable_stdin = 1; opt->disable_stdin = 1;
......
...@@ -315,8 +315,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix) ...@@ -315,8 +315,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
no_index = DIFF_NO_INDEX_IMPLICIT; no_index = DIFF_NO_INDEX_IMPLICIT;
} }
if (!no_index)
gitmodules_config();
init_diff_ui_defaults(); init_diff_ui_defaults();
git_config(git_diff_ui_config, NULL); git_config(git_diff_ui_config, NULL);
precompose_argv(argc, argv); precompose_argv(argc, argv);
......
...@@ -1360,11 +1360,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) ...@@ -1360,11 +1360,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (depth || deepen_since || deepen_not.nr) if (depth || deepen_since || deepen_not.nr)
deepen = 1; deepen = 1;
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
gitmodules_config();
git_config(submodule_config, NULL);
}
if (all) { if (all) {
if (argc == 1) if (argc == 1)
die(_("fetch --all does not take a repository argument")); die(_("fetch --all does not take a repository argument"));
......
...@@ -1048,10 +1048,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix) ...@@ -1048,10 +1048,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
} }
#endif #endif
if (recurse_submodules) {
gitmodules_config();
}
if (show_in_pager && (cached || list.nr)) if (show_in_pager && (cached || list.nr))
die(_("--open-files-in-pager only works on the worktree")); die(_("--open-files-in-pager only works on the worktree"));
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "pathspec.h" #include "pathspec.h"
#include "run-command.h" #include "run-command.h"
#include "submodule.h" #include "submodule.h"
#include "submodule-config.h"
static int abbrev; static int abbrev;
static int show_deleted; static int show_deleted;
...@@ -210,8 +211,6 @@ static void show_submodule(struct repository *superproject, ...@@ -210,8 +211,6 @@ static void show_submodule(struct repository *superproject,
if (repo_read_index(&submodule) < 0) if (repo_read_index(&submodule) < 0)
die("index file corrupt"); die("index file corrupt");
repo_read_gitmodules(&submodule);
show_files(&submodule, dir); show_files(&submodule, dir);
repo_clear(&submodule); repo_clear(&submodule);
...@@ -609,9 +608,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) ...@@ -609,9 +608,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
if (require_work_tree && !is_inside_work_tree()) if (require_work_tree && !is_inside_work_tree())
setup_work_tree(); setup_work_tree();
if (recurse_submodules)
repo_read_gitmodules(the_repository);
if (recurse_submodules && if (recurse_submodules &&
(show_stage || show_deleted || show_others || show_unmerged || (show_stage || show_deleted || show_others || show_unmerged ||
show_killed || show_modified || show_resolve_undo || with_tree)) show_killed || show_modified || show_resolve_undo || with_tree))
......
...@@ -131,7 +131,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) ...@@ -131,7 +131,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
struct stat st; struct stat st;
struct string_list src_for_dst = STRING_LIST_INIT_NODUP; struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
gitmodules_config();
git_config(git_default_config, NULL); git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_mv_options, argc = parse_options(argc, argv, prefix, builtin_mv_options,
......
...@@ -164,8 +164,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) ...@@ -164,8 +164,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
argc = parse_options(argc, argv, unused_prefix, read_tree_options, argc = parse_options(argc, argv, unused_prefix, read_tree_options,
read_tree_usage, 0); read_tree_usage, 0);
load_submodule_cache();
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
prefix_set = opts.prefix ? 1 : 0; prefix_set = opts.prefix ? 1 : 0;
......
...@@ -156,6 +156,7 @@ static int read_from_tree(const struct pathspec *pathspec, ...@@ -156,6 +156,7 @@ static int read_from_tree(const struct pathspec *pathspec,
opt.output_format = DIFF_FORMAT_CALLBACK; opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff; opt.format_callback = update_index_from_diff;
opt.format_callback_data = &intent_to_add; opt.format_callback_data = &intent_to_add;
opt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
if (do_diff_cache(tree_oid, &opt)) if (do_diff_cache(tree_oid, &opt))
return 1; return 1;
...@@ -308,8 +309,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix) ...@@ -308,8 +309,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH); PARSE_OPT_KEEP_DASHDASH);
parse_args(&pathspec, argv, prefix, patch_mode, &rev); parse_args(&pathspec, argv, prefix, patch_mode, &rev);
load_submodule_cache();
unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid); unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid);
if (unborn) { if (unborn) {
/* reset on unborn branch: treat as reset to empty tree */ /* reset on unborn branch: treat as reset to empty tree */
......
...@@ -255,7 +255,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix) ...@@ -255,7 +255,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
struct pathspec pathspec; struct pathspec pathspec;
char *seen; char *seen;
gitmodules_config();
git_config(git_default_config, NULL); git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_rm_options, argc = parse_options(argc, argv, prefix, builtin_rm_options,
......
...@@ -275,8 +275,6 @@ static void module_list_active(struct module_list *list) ...@@ -275,8 +275,6 @@ static void module_list_active(struct module_list *list)
int i; int i;
struct module_list active_modules = MODULE_LIST_INIT; struct module_list active_modules = MODULE_LIST_INIT;
gitmodules_config();
for (i = 0; i < list->nr; i++) { for (i = 0; i < list->nr; i++) {
const struct cache_entry *ce = list->entries[i]; const struct cache_entry *ce = list->entries[i];
...@@ -337,9 +335,6 @@ static void init_submodule(const char *path, const char *prefix, int quiet) ...@@ -337,9 +335,6 @@ static void init_submodule(const char *path, const char *prefix, int quiet)
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
char *upd = NULL, *url = NULL, *displaypath; char *upd = NULL, *url = NULL, *displaypath;
/* Only loads from .gitmodules, no overlay with .git/config */
gitmodules_config();
if (prefix && get_super_prefix()) if (prefix && get_super_prefix())
die("BUG: cannot have prefix and superprefix"); die("BUG: cannot have prefix and superprefix");
else if (prefix) else if (prefix)
...@@ -475,7 +470,6 @@ static int module_name(int argc, const char **argv, const char *prefix) ...@@ -475,7 +470,6 @@ static int module_name(int argc, const char **argv, const char *prefix)
if (argc != 2) if (argc != 2)
usage(_("git submodule--helper name <path>")); usage(_("git submodule--helper name <path>"));
gitmodules_config();
sub = submodule_from_path(&null_oid, argv[1]); sub = submodule_from_path(&null_oid, argv[1]);
if (!sub) if (!sub)
...@@ -780,6 +774,10 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, ...@@ -780,6 +774,10 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
struct strbuf *out) struct strbuf *out)
{ {
const struct submodule *sub = NULL; const struct submodule *sub = NULL;
const char *url = NULL;
const char *update_string;
enum submodule_update_type update_type;
char *key;
struct strbuf displaypath_sb = STRBUF_INIT; struct strbuf displaypath_sb = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
const char *displaypath = NULL; const char *displaypath = NULL;
...@@ -808,9 +806,17 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, ...@@ -808,9 +806,17 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup; goto cleanup;
} }
key = xstrfmt("submodule.%s.update", sub->name);
if (!repo_config_get_string_const(the_repository, key, &update_string)) {
update_type = parse_submodule_update_type(update_string);
} else {
update_type = sub->update_strategy.type;
}
free(key);
if (suc->update.type == SM_UPDATE_NONE if (suc->update.type == SM_UPDATE_NONE
|| (suc->update.type == SM_UPDATE_UNSPECIFIED || (suc->update.type == SM_UPDATE_UNSPECIFIED
&& sub->update_strategy.type == SM_UPDATE_NONE)) { && update_type == SM_UPDATE_NONE)) {
strbuf_addf(out, _("Skipping submodule '%s'"), displaypath); strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
strbuf_addch(out, '\n'); strbuf_addch(out, '\n');
goto cleanup; goto cleanup;
...@@ -822,6 +828,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, ...@@ -822,6 +828,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup; goto cleanup;
} }
strbuf_reset(&sb);
strbuf_addf(&sb, "submodule.%s.url", sub->name);
if (repo_config_get_string_const(the_repository, sb.buf, &url))
url = sub->url;
strbuf_reset(&sb); strbuf_reset(&sb);
strbuf_addf(&sb, "%s/.git", ce->name); strbuf_addf(&sb, "%s/.git", ce->name);
needs_cloning = !file_exists(sb.buf); needs_cloning = !file_exists(sb.buf);
...@@ -851,7 +862,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, ...@@ -851,7 +862,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
argv_array_push(&child->args, "--depth=1"); argv_array_push(&child->args, "--depth=1");
argv_array_pushl(&child->args, "--path", sub->path, NULL); argv_array_pushl(&child->args, "--path", sub->path, NULL);
argv_array_pushl(&child->args, "--name", sub->name, NULL); argv_array_pushl(&child->args, "--name", sub->name, NULL);
argv_array_pushl(&child->args, "--url", sub->url, NULL); argv_array_pushl(&child->args, "--url", url, NULL);
if (suc->references.nr) { if (suc->references.nr) {
struct string_list_item *item; struct string_list_item *item;
for_each_string_list_item(item, &suc->references) for_each_string_list_item(item, &suc->references)
...@@ -1025,10 +1036,6 @@ static int update_clone(int argc, const char **argv, const char *prefix) ...@@ -1025,10 +1036,6 @@ static int update_clone(int argc, const char **argv, const char *prefix)
if (pathspec.nr) if (pathspec.nr)
suc.warn_if_uninitialized = 1; suc.warn_if_uninitialized = 1;
/* Overlay the parsed .gitmodules file with .git/config */
gitmodules_config();
git_config(submodule_config, NULL);
run_processes_parallel(max_jobs, run_processes_parallel(max_jobs,
update_clone_get_next_task, update_clone_get_next_task,
update_clone_start_failure, update_clone_start_failure,
...@@ -1066,17 +1073,22 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix ...@@ -1066,17 +1073,22 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix
static const char *remote_submodule_branch(const char *path) static const char *remote_submodule_branch(const char *path)
{ {
const struct submodule *sub; const struct submodule *sub;
gitmodules_config(); const char *branch = NULL;
git_config(submodule_config, NULL); char *key;
sub = submodule_from_path(&null_oid, path); sub = submodule_from_path(&null_oid, path);
if (!sub) if (!sub)
return NULL; return NULL;
if (!sub->branch) key = xstrfmt("submodule.%s.branch", sub->name);
if (repo_config_get_string_const(the_repository, key, &branch))
branch = sub->branch;
free(key);
if (!branch)
return "master"; return "master";
if (!strcmp(sub->branch, ".")) { if (!strcmp(branch, ".")) {
unsigned char sha1[20]; unsigned char sha1[20];
const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
...@@ -1094,7 +1106,7 @@ static const char *remote_submodule_branch(const char *path) ...@@ -1094,7 +1106,7 @@ static const char *remote_submodule_branch(const char *path)
return refname; return refname;
} }
return sub->branch; return branch;
} }
static int resolve_remote_submodule_branch(int argc, const char **argv, static int resolve_remote_submodule_branch(int argc, const char **argv,
...@@ -1213,9 +1225,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix) ...@@ -1213,9 +1225,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, embed_gitdir_options, argc = parse_options(argc, argv, prefix, embed_gitdir_options,
git_submodule_helper_usage, 0); git_submodule_helper_usage, 0);
gitmodules_config();
git_config(submodule_config, NULL);
if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
return 1; return 1;
...@@ -1231,8 +1240,6 @@ static int is_active(int argc, const char **argv, const char *prefix) ...@@ -1231,8 +1240,6 @@ static int is_active(int argc, const char **argv, const char *prefix)
if (argc != 2) if (argc != 2)
die("submodule--helper is-active takes exactly 1 argument"); die("submodule--helper is-active takes exactly 1 argument");
gitmodules_config();
return !is_submodule_active(the_repository, argv[1]); return !is_submodule_active(the_repository, argv[1]);
} }
......
...@@ -401,9 +401,6 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) ...@@ -401,9 +401,6 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
return 0; return 0;
} }
if (starts_with(var, "submodule."))
return parse_submodule_config_option(var, value);
if (git_diff_heuristic_config(var, value, cb) < 0) if (git_diff_heuristic_config(var, value, cb) < 0)
return -1; return -1;
......
...@@ -18,6 +18,7 @@ struct submodule_cache { ...@@ -18,6 +18,7 @@ struct submodule_cache {
struct hashmap for_path; struct hashmap for_path;
struct hashmap for_name; struct hashmap for_name;
unsigned initialized:1; unsigned initialized:1;
unsigned gitmodules_read:1;
}; };
/* /*
...@@ -99,6 +100,7 @@ static void submodule_cache_clear(struct submodule_cache *cache) ...@@ -99,6 +100,7 @@ static void submodule_cache_clear(struct submodule_cache *cache)
hashmap_free(&cache->for_path, 1); hashmap_free(&cache->for_path, 1);
hashmap_free(&cache->for_name, 1); hashmap_free(&cache->for_name, 1);
cache->initialized = 0; cache->initialized = 0;
cache->gitmodules_read = 0;
} }
void submodule_cache_free(struct submodule_cache *cache) void submodule_cache_free(struct submodule_cache *cache)
...@@ -455,9 +457,9 @@ static int parse_config(const char *var, const char *value, void *data) ...@@ -455,9 +457,9 @@ static int parse_config(const char *var, const char *value, void *data)
return ret; return ret;
} }
int gitmodule_oid_from_commit(const struct object_id *treeish_name, static int gitmodule_oid_from_commit(const struct object_id *treeish_name,
struct object_id *gitmodules_oid, struct object_id *gitmodules_oid,
struct strbuf *rev) struct strbuf *rev)
{ {
int ret = 0; int ret = 0;
...@@ -558,13 +560,11 @@ static void submodule_cache_check_init(struct repository *repo) ...@@ -558,13 +560,11 @@ static void submodule_cache_check_init(struct repository *repo)
submodule_cache_init(repo->submodule_cache); submodule_cache_init(repo->submodule_cache);
} }
int submodule_config_option(struct repository *repo, static int gitmodules_cb(const char *var, const char *value, void *data)
const char *var, const char *value)
{ {
struct repository *repo = data;
struct parse_config_parameter parameter; struct parse_config_parameter parameter;
submodule_cache_check_init(repo);
parameter.cache = repo->submodule_cache; parameter.cache = repo->submodule_cache;
parameter.treeish_name = NULL; parameter.treeish_name = NULL;
parameter.gitmodules_sha1 = null_sha1; parameter.gitmodules_sha1 = null_sha1;
...@@ -573,22 +573,63 @@ int submodule_config_option(struct repository *repo, ...@@ -573,22 +573,63 @@ int submodule_config_option(struct repository *repo,
return parse_config(var, value, &parameter); return parse_config(var, value, &parameter);
} }
int parse_submodule_config_option(const char *var, const char *value) void repo_read_gitmodules(struct repository *repo)
{ {
return submodule_config_option(the_repository, var, value); 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);
free(gitmodules);
}
repo->submodule_cache->gitmodules_read = 1;
}
void gitmodules_config_oid(const struct object_id *commit_oid)
{
struct strbuf rev = STRBUF_INIT;
struct object_id oid;
submodule_cache_check_init(the_repository);
if (gitmodule_oid_from_commit(commit_oid, &oid, &rev)) {
git_config_from_blob_oid(gitmodules_cb, rev.buf,
&oid, the_repository);
}
strbuf_release(&rev);
the_repository->submodule_cache->gitmodules_read = 1;
}
static void gitmodules_read_check(struct repository *repo)
{
submodule_cache_check_init(repo);
/* read the repo's .gitmodules file if it hasn't been already */
if (!repo->submodule_cache->gitmodules_read)
repo_read_gitmodules(repo);
} }
const struct submodule *submodule_from_name(const struct object_id *treeish_name, const struct submodule *submodule_from_name(const struct object_id *treeish_name,
const char *name) const char *name)
{ {
submodule_cache_check_init(the_repository); gitmodules_read_check(the_repository);
return config_from(the_repository->submodule_cache, treeish_name, name, lookup_name); return config_from(the_repository->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(const struct object_id *treeish_name,
const char *path) const char *path)
{ {
submodule_cache_check_init(the_repository); gitmodules_read_check(the_repository);
return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path); return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path);
} }
...@@ -596,7 +637,7 @@ const struct submodule *submodule_from_cache(struct repository *repo, ...@@ -596,7 +637,7 @@ const struct submodule *submodule_from_cache(struct repository *repo,
const struct object_id *treeish_name, const struct object_id *treeish_name,
const char *key) const char *key)
{ {
submodule_cache_check_init(repo); gitmodules_read_check(repo);
return config_from(repo->submodule_cache, treeish_name, return config_from(repo->submodule_cache, treeish_name,
key, lookup_path); key, lookup_path);
} }
......
...@@ -34,9 +34,8 @@ extern int option_fetch_parse_recurse_submodules(const struct option *opt, ...@@ -34,9 +34,8 @@ extern int option_fetch_parse_recurse_submodules(const struct option *opt,
const char *arg, int unset); const char *arg, int unset);
extern int parse_update_recurse_submodules_arg(const char *opt, const char *arg); extern int parse_update_recurse_submodules_arg(const char *opt, const char *arg);
extern int parse_push_recurse_submodules_arg(const char *opt, const char *arg); extern int parse_push_recurse_submodules_arg(const char *opt, const char *arg);
extern int parse_submodule_config_option(const char *var, const char *value); extern void repo_read_gitmodules(struct repository *repo);
extern int submodule_config_option(struct repository *repo, extern void gitmodules_config_oid(const struct object_id *commit_oid);
const char *var, const char *value);
extern const struct submodule *submodule_from_name( extern const struct submodule *submodule_from_name(
const struct object_id *commit_or_tree, const char *name); const struct object_id *commit_or_tree, const char *name);
extern const struct submodule *submodule_from_path( extern const struct submodule *submodule_from_path(
...@@ -44,9 +43,6 @@ extern const struct submodule *submodule_from_path( ...@@ -44,9 +43,6 @@ extern const struct submodule *submodule_from_path(
extern const struct submodule *submodule_from_cache(struct repository *repo, extern const struct submodule *submodule_from_cache(struct repository *repo,
const struct object_id *treeish_name, const struct object_id *treeish_name,
const char *key); const char *key);
extern int gitmodule_oid_from_commit(const struct object_id *commit_oid,
struct object_id *gitmodules_oid,
struct strbuf *rev);
extern void submodule_free(void); extern void submodule_free(void);
#endif /* SUBMODULE_CONFIG_H */ #endif /* SUBMODULE_CONFIG_H */
...@@ -165,31 +165,18 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, ...@@ -165,31 +165,18 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
{ {
const struct submodule *submodule = submodule_from_path(&null_oid, path); const struct submodule *submodule = submodule_from_path(&null_oid, path);
if (submodule) { if (submodule) {
if (submodule->ignore) const char *ignore;
handle_ignore_submodules_arg(diffopt, submodule->ignore); char *key;
else if (is_gitmodules_unmerged(&the_index))
DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
}
}
/* For loading from the .gitmodules file. */ key = xstrfmt("submodule.%s.ignore", submodule->name);
static int git_modules_config(const char *var, const char *value, void *cb) if (repo_config_get_string_const(the_repository, key, &ignore))
{ ignore = submodule->ignore;
if (starts_with(var, "submodule.")) free(key);
return parse_submodule_config_option(var, value);
return 0;
}
/* Loads all submodule settings from the config. */ if (ignore)
int submodule_config(const char *var, const char *value, void *cb) handle_ignore_submodules_arg(diffopt, ignore);
{ else if (is_gitmodules_unmerged(&the_index))
if (!strcmp(var, "submodule.recurse")) { DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
int v = git_config_bool(var, value) ?
RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
config_update_recurse_submodules = v;
return 0;
} else {
return git_modules_config(var, value, cb);
} }
} }
...@@ -221,55 +208,6 @@ int option_parse_recurse_submodules_worktree_updater(const struct option *opt, ...@@ -221,55 +208,6 @@ int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
return 0; return 0;
} }
void load_submodule_cache(void)
{
if (config_update_recurse_submodules == RECURSE_SUBMODULES_OFF)
return;
gitmodules_config();
git_config(submodule_config, NULL);
}
static int gitmodules_cb(const char *var, const char *value, void *data)
{
struct repository *repo = data;
return submodule_config_option(repo, var, value);
}
void repo_read_gitmodules(struct repository *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);
free(gitmodules);
}
}
void gitmodules_config(void)
{
repo_read_gitmodules(the_repository);
}
void gitmodules_config_oid(const struct object_id *commit_oid)
{
struct strbuf rev = STRBUF_INIT;
struct object_id oid;
if (gitmodule_oid_from_commit(commit_oid, &oid, &rev)) {
git_config_from_blob_oid(submodule_config, rev.buf,
&oid, NULL);
}
strbuf_release(&rev);
}
/* /*
* Determine if a submodule has been initialized at a given 'path' * Determine if a submodule has been initialized at a given 'path'
*/ */
...@@ -398,24 +336,38 @@ void die_path_inside_submodule(const struct index_state *istate, ...@@ -398,24 +336,38 @@ void die_path_inside_submodule(const struct index_state *istate,
} }
} }
int parse_submodule_update_strategy(const char *value, enum submodule_update_type parse_submodule_update_type(const char *value)
struct submodule_update_strategy *dst)
{ {
free((void*)dst->command);
dst->command = NULL;
if (!strcmp(value, "none")) if (!strcmp(value, "none"))
dst->type = SM_UPDATE_NONE; return SM_UPDATE_NONE;
else if (!strcmp(value, "checkout")) else if (!strcmp(value, "checkout"))
dst->type = SM_UPDATE_CHECKOUT; return SM_UPDATE_CHECKOUT;
else if (!strcmp(value, "rebase")) else if (!strcmp(value, "rebase"))
dst->type = SM_UPDATE_REBASE; return SM_UPDATE_REBASE;
else if (!strcmp(value, "merge")) else if (!strcmp(value, "merge"))
dst->type = SM_UPDATE_MERGE; return SM_UPDATE_MERGE;
else if (skip_prefix(value, "!", &value)) { else if (*value == '!')
dst->type = SM_UPDATE_COMMAND; return SM_UPDATE_COMMAND;
dst->command = xstrdup(value); else
} else return SM_UPDATE_UNSPECIFIED;
}
int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst)
{
enum submodule_update_type type;
free((void*)dst->command);
dst->command = NULL;
type = parse_submodule_update_type(value);
if (type == SM_UPDATE_UNSPECIFIED)
return -1; return -1;
dst->type = type;
if (type == SM_UPDATE_COMMAND)
dst->command = xstrdup(value + 1);
return 0; return 0;
} }
...@@ -1130,7 +1082,6 @@ int submodule_touches_in_range(struct object_id *excl_oid, ...@@ -1130,7 +1082,6 @@ int submodule_touches_in_range(struct object_id *excl_oid,
struct argv_array args = ARGV_ARRAY_INIT; struct argv_array args = ARGV_ARRAY_INIT;
int ret; int ret;
gitmodules_config();
/* No need to check if there are no submodules configured */ /* No need to check if there are no submodules configured */
if (!submodule_from_path(NULL, NULL)) if (!submodule_from_path(NULL, NULL))
return 0; return 0;
...@@ -1179,19 +1130,27 @@ static int get_next_submodule(struct child_process *cp, ...@@ -1179,19 +1130,27 @@ static int get_next_submodule(struct child_process *cp,
continue; continue;
submodule = submodule_from_path(&null_oid, ce->name); submodule = submodule_from_path(&null_oid, ce->name);
if (!submodule)
submodule = submodule_from_name(&null_oid, ce->name);
default_argv = "yes"; default_argv = "yes";
if (spf->command_line_option == RECURSE_SUBMODULES_DEFAULT) { if (spf->command_line_option == RECURSE_SUBMODULES_DEFAULT) {
if (submodule && int fetch_recurse = RECURSE_SUBMODULES_NONE;
submodule->fetch_recurse !=
RECURSE_SUBMODULES_NONE) { if (submodule) {
if (submodule->fetch_recurse == char *key;
RECURSE_SUBMODULES_OFF) const char *value;
fetch_recurse = submodule->fetch_recurse;
key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name);
if (!repo_config_get_string_const(the_repository, key, &value)) {
fetch_recurse = parse_fetch_recurse_submodules_arg(key, value);
}
free(key);
}
if (fetch_recurse != RECURSE_SUBMODULES_NONE) {
if (fetch_recurse == RECURSE_SUBMODULES_OFF)
continue; continue;
if (submodule->fetch_recurse == if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND) {
RECURSE_SUBMODULES_ON_DEMAND) {
if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name)) if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
continue; continue;
default_argv = "on-demand"; default_argv = "on-demand";
...@@ -2029,7 +1988,6 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule) ...@@ -2029,7 +1988,6 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
strbuf_addstr(buf, git_dir); strbuf_addstr(buf, git_dir);
} }
if (!is_git_directory(buf->buf)) { if (!is_git_directory(buf->buf)) {
gitmodules_config();
sub = submodule_from_path(&null_oid, submodule); sub = submodule_from_path(&null_oid, submodule);
if (!sub) { if (!sub) {
ret = -1; ret = -1;
......
...@@ -40,16 +40,11 @@ extern int remove_path_from_gitmodules(const char *path); ...@@ -40,16 +40,11 @@ extern int remove_path_from_gitmodules(const char *path);
extern void stage_updated_gitmodules(void); extern void stage_updated_gitmodules(void);
extern void set_diffopt_flags_from_submodule_config(struct diff_options *, extern void set_diffopt_flags_from_submodule_config(struct diff_options *,
const char *path); const char *path);
extern int submodule_config(const char *var, const char *value, void *cb);
extern int git_default_submodule_config(const char *var, const char *value, void *cb); extern int git_default_submodule_config(const char *var, const char *value, void *cb);
struct option; struct option;
int option_parse_recurse_submodules_worktree_updater(const struct option *opt, int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
const char *arg, int unset); const char *arg, int unset);
void load_submodule_cache(void);
extern void gitmodules_config(void);
extern void repo_read_gitmodules(struct repository *repo);
extern void gitmodules_config_oid(const struct object_id *commit_oid);
extern int is_submodule_active(struct repository *repo, const char *path); extern int is_submodule_active(struct repository *repo, const char *path);
/* /*
* Determine if a submodule has been populated at a given 'path' by checking if * Determine if a submodule has been populated at a given 'path' by checking if
...@@ -62,6 +57,7 @@ extern void die_in_unpopulated_submodule(const struct index_state *istate, ...@@ -62,6 +57,7 @@ extern void die_in_unpopulated_submodule(const struct index_state *istate,
const char *prefix); const char *prefix);
extern void die_path_inside_submodule(const struct index_state *istate, extern void die_path_inside_submodule(const struct index_state *istate,
const struct pathspec *ps); const struct pathspec *ps);
extern enum submodule_update_type parse_submodule_update_type(const char *value);
extern int parse_submodule_update_strategy(const char *value, extern int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst); struct submodule_update_strategy *dst);
extern const char *submodule_strategy_to_string(const struct submodule_update_strategy *s); extern const char *submodule_strategy_to_string(const struct submodule_update_strategy *s);
......
...@@ -10,11 +10,6 @@ static void die_usage(int argc, const char **argv, const char *msg) ...@@ -10,11 +10,6 @@ static void die_usage(int argc, const char **argv, const char *msg)
exit(1); exit(1);
} }
static int git_test_config(const char *var, const char *value, void *cb)
{
return parse_submodule_config_option(var, value);
}
int cmd_main(int argc, const char **argv) int cmd_main(int argc, const char **argv)
{ {
const char **arg = argv; const char **arg = argv;
...@@ -37,8 +32,6 @@ int cmd_main(int argc, const char **argv) ...@@ -37,8 +32,6 @@ int cmd_main(int argc, const char **argv)
die_usage(argc, argv, "Wrong number of arguments."); die_usage(argc, argv, "Wrong number of arguments.");
setup_git_directory(); setup_git_directory();
gitmodules_config();
git_config(git_test_config, NULL);
while (*arg) { while (*arg) {
struct object_id commit_oid; struct object_id commit_oid;
......
...@@ -113,35 +113,6 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)' ...@@ -113,35 +113,6 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'
! test -s actual4 ! test -s actual4
' '
test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.git/config]' '
git config diff.ignoreSubmodules all &&
git diff HEAD >actual &&
! test -s actual &&
git config submodule.subname.ignore none &&
git config submodule.subname.path sub &&
git diff HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
test_cmp expect.body actual.body &&
git config submodule.subname.ignore all &&
git diff HEAD >actual2 &&
! test -s actual2 &&
git config submodule.subname.ignore untracked &&
git diff HEAD >actual3 &&
sed -e "1,/^@@/d" actual3 >actual3.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
test_cmp expect.body actual3.body &&
git config submodule.subname.ignore dirty &&
git diff HEAD >actual4 &&
! test -s actual4 &&
git diff HEAD --ignore-submodules=none >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
test_cmp expect.body actual.body &&
git config --remove-section submodule.subname &&
git config --unset diff.ignoreSubmodules
'
test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.gitmodules]' ' test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.gitmodules]' '
git config diff.ignoreSubmodules dirty && git config diff.ignoreSubmodules dirty &&
git diff HEAD >actual && git diff HEAD >actual &&
...@@ -208,24 +179,6 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)' ...@@ -208,24 +179,6 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'
! test -s actual4 ! test -s actual4
' '
test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.git/config]' '
git config submodule.subname.ignore all &&
git config submodule.subname.path sub &&
git diff HEAD >actual2 &&
! test -s actual2 &&
git config submodule.subname.ignore untracked &&
git diff HEAD >actual3 &&
! test -s actual3 &&
git config submodule.subname.ignore dirty &&
git diff HEAD >actual4 &&
! test -s actual4 &&
git diff --ignore-submodules=none HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
test_cmp expect.body actual.body &&
git config --remove-section submodule.subname
'
test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.gitmodules]' ' test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.gitmodules]' '
git config --add -f .gitmodules submodule.subname.ignore all && git config --add -f .gitmodules submodule.subname.ignore all &&
git config --add -f .gitmodules submodule.subname.path sub && git config --add -f .gitmodules submodule.subname.path sub &&
...@@ -261,26 +214,6 @@ test_expect_success 'git diff between submodule commits' ' ...@@ -261,26 +214,6 @@ test_expect_success 'git diff between submodule commits' '
! test -s actual ! test -s actual
' '
test_expect_success 'git diff between submodule commits [.git/config]' '
git diff HEAD^..HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subtip $subprev &&
test_cmp expect.body actual.body &&
git config submodule.subname.ignore dirty &&
git config submodule.subname.path sub &&
git diff HEAD^..HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subtip $subprev &&
test_cmp expect.body actual.body &&
git config submodule.subname.ignore all &&
git diff HEAD^..HEAD >actual &&
! test -s actual &&
git diff --ignore-submodules=dirty HEAD^..HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subtip $subprev &&
git config --remove-section submodule.subname
'
test_expect_success 'git diff between submodule commits [.gitmodules]' ' test_expect_success 'git diff between submodule commits [.gitmodules]' '
git diff HEAD^..HEAD >actual && git diff HEAD^..HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body && sed -e "1,/^@@/d" actual >actual.body &&
......
...@@ -46,16 +46,6 @@ test_expect_success 'submodule update aborts on missing gitmodules url' ' ...@@ -46,16 +46,6 @@ test_expect_success 'submodule update aborts on missing gitmodules url' '
test_must_fail git submodule init test_must_fail git submodule init
' '
test_expect_success 'configuration parsing' '
test_when_finished "rm -f .gitmodules" &&
cat >.gitmodules <<-\EOF &&
[submodule "s"]
path
ignore
EOF
test_must_fail git status
'
test_expect_success 'setup - repository in init subdirectory' ' test_expect_success 'setup - repository in init subdirectory' '
mkdir init && mkdir init &&
( (
......
...@@ -31,6 +31,21 @@ test_expect_success 'submodule config cache setup' ' ...@@ -31,6 +31,21 @@ test_expect_success 'submodule config cache setup' '
) )
' '
test_expect_success 'configuration parsing with error' '
test_when_finished "rm -rf repo" &&
test_create_repo repo &&
cat >repo/.gitmodules <<-\EOF &&
[submodule "s"]
path
ignore
EOF
(
cd repo &&
test_must_fail test-submodule-config "" s 2>actual &&
test_i18ngrep "bad config" actual
)
'
cat >super/expect <<EOF cat >super/expect <<EOF
Submodule name: 'a' for path 'a' Submodule name: 'a' for path 'a'
Submodule name: 'a' for path 'b' Submodule name: 'a' for path 'b'
...@@ -107,78 +122,6 @@ test_expect_success 'using different treeishs works' ' ...@@ -107,78 +122,6 @@ test_expect_success 'using different treeishs works' '
) )
' '
cat >super/expect_url <<EOF
Submodule url: 'git@somewhere.else.net:a.git' for path 'b'
Submodule url: 'git@somewhere.else.net:submodule.git' for path 'submodule'
EOF
cat >super/expect_local_path <<EOF
Submodule name: 'a' for path 'c'
Submodule name: 'submodule' for path 'submodule'
EOF
test_expect_success 'reading of local configuration' '
(cd super &&
old_a=$(git config submodule.a.url) &&
old_submodule=$(git config submodule.submodule.url) &&
git config submodule.a.url git@somewhere.else.net:a.git &&
git config submodule.submodule.url git@somewhere.else.net:submodule.git &&
test-submodule-config --url \
"" b \
"" submodule \
>actual &&
test_cmp expect_url actual &&
git config submodule.a.path c &&
test-submodule-config \
"" c \
"" submodule \
>actual &&
test_cmp expect_local_path actual &&
git config submodule.a.url "$old_a" &&
git config submodule.submodule.url "$old_submodule" &&
git config --unset submodule.a.path c
)
'
cat >super/expect_url <<EOF
Submodule url: '../submodule' for path 'b'
Submodule url: 'git@somewhere.else.net:submodule.git' for path 'submodule'
EOF
test_expect_success 'reading of local configuration for uninitialized submodules' '
(
cd super &&
git submodule deinit -f b &&
old_submodule=$(git config submodule.submodule.url) &&
git config submodule.submodule.url git@somewhere.else.net:submodule.git &&
test-submodule-config --url \
"" b \
"" submodule \
>actual &&
test_cmp expect_url actual &&
git config submodule.submodule.url "$old_submodule" &&
git submodule init b
)
'
cat >super/expect_fetchrecurse_die.err <<EOF
fatal: bad submodule.submodule.fetchrecursesubmodules argument: blabla
EOF
test_expect_success 'local error in fetchrecursesubmodule dies early' '
(cd super &&
git config submodule.submodule.fetchrecursesubmodules blabla &&
test_must_fail test-submodule-config \
"" b \
"" submodule \
>actual.out 2>actual.err &&
touch expect_fetchrecurse_die.out &&
test_cmp expect_fetchrecurse_die.out actual.out &&
test_cmp expect_fetchrecurse_die.err actual.err &&
git config --unset submodule.submodule.fetchrecursesubmodules
)
'
test_expect_success 'error in history in fetchrecursesubmodule lets continue' ' test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
(cd super && (cd super &&
git config -f .gitmodules \ git config -f .gitmodules \
......
#define NO_THE_INDEX_COMPATIBILITY_MACROS #define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h" #include "cache.h"
#include "repository.h"
#include "config.h" #include "config.h"
#include "dir.h" #include "dir.h"
#include "tree.h" #include "tree.h"
...@@ -255,47 +256,41 @@ static int check_submodule_move_head(const struct cache_entry *ce, ...@@ -255,47 +256,41 @@ static int check_submodule_move_head(const struct cache_entry *ce,
{ {
unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN; unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN;
const struct submodule *sub = submodule_from_ce(ce); const struct submodule *sub = submodule_from_ce(ce);
if (!sub) if (!sub)
return 0; return 0;
if (o->reset) if (o->reset)
flags |= SUBMODULE_MOVE_HEAD_FORCE; flags |= SUBMODULE_MOVE_HEAD_FORCE;
switch (sub->update_strategy.type) { if (submodule_move_head(ce->name, old_id, new_id, flags))
case SM_UPDATE_UNSPECIFIED: return o->gently ? -1 :
case SM_UPDATE_CHECKOUT: add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
if (submodule_move_head(ce->name, old_id, new_id, flags)) return 0;
return o->gently ? -1 :
add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
return 0;
case SM_UPDATE_NONE:
return 0;
case SM_UPDATE_REBASE:
case SM_UPDATE_MERGE:
case SM_UPDATE_COMMAND:
default:
warning(_("submodule update strategy not supported for submodule '%s'"), ce->name);
return -1;
}
} }
static void reload_gitmodules_file(struct index_state *index, /*
struct checkout *state) * Preform the loading of the repository's gitmodules file. This function is
* used by 'check_update()' to perform loading of the gitmodules file in two
* differnt situations:
* (1) before removing entries from the working tree if the gitmodules file has
* been marked for removal. This situation is specified by 'state' == NULL.
* (2) before checking out entries to the working tree if the gitmodules file
* has been marked for update. This situation is specified by 'state' != NULL.
*/
static void load_gitmodules_file(struct index_state *index,
struct checkout *state)
{ {
int i; int pos = index_name_pos(index, GITMODULES_FILE, strlen(GITMODULES_FILE));
for (i = 0; i < index->cache_nr; i++) {
struct cache_entry *ce = index->cache[i]; if (pos >= 0) {
if (ce->ce_flags & CE_UPDATE) { struct cache_entry *ce = index->cache[pos];
int r = strcmp(ce->name, GITMODULES_FILE); if (!state && ce->ce_flags & CE_WT_REMOVE) {
if (r < 0) repo_read_gitmodules(the_repository);
continue; } else if (state && (ce->ce_flags & CE_UPDATE)) {
else if (r == 0) { submodule_free();
submodule_free(); checkout_entry(ce, state, NULL);
checkout_entry(ce, state, NULL); repo_read_gitmodules(the_repository);
gitmodules_config();
git_config(submodule_config, NULL);
} else
break;
} }
} }
} }
...@@ -308,19 +303,9 @@ static void unlink_entry(const struct cache_entry *ce) ...@@ -308,19 +303,9 @@ static void unlink_entry(const struct cache_entry *ce)
{ {
const struct submodule *sub = submodule_from_ce(ce); const struct submodule *sub = submodule_from_ce(ce);
if (sub) { if (sub) {
switch (sub->update_strategy.type) { /* state.force is set at the caller. */
case SM_UPDATE_UNSPECIFIED: submodule_move_head(ce->name, "HEAD", NULL,
case SM_UPDATE_CHECKOUT: SUBMODULE_MOVE_HEAD_FORCE);
case SM_UPDATE_REBASE:
case SM_UPDATE_MERGE:
/* state.force is set at the caller. */
submodule_move_head(ce->name, "HEAD", NULL,
SUBMODULE_MOVE_HEAD_FORCE);
break;
case SM_UPDATE_NONE:
case SM_UPDATE_COMMAND:
return; /* Do not touch the submodule. */
}
} }
if (!check_leading_path(ce->name, ce_namelen(ce))) if (!check_leading_path(ce->name, ce_namelen(ce)))
return; return;
...@@ -364,6 +349,10 @@ static int check_updates(struct unpack_trees_options *o) ...@@ -364,6 +349,10 @@ static int check_updates(struct unpack_trees_options *o)
if (o->update) if (o->update)
git_attr_set_direction(GIT_ATTR_CHECKOUT, index); git_attr_set_direction(GIT_ATTR_CHECKOUT, index);
if (should_update_submodules() && o->update && !o->dry_run)
load_gitmodules_file(index, NULL);
for (i = 0; i < index->cache_nr; i++) { for (i = 0; i < index->cache_nr; i++) {
const struct cache_entry *ce = index->cache[i]; const struct cache_entry *ce = index->cache[i];
...@@ -377,7 +366,7 @@ static int check_updates(struct unpack_trees_options *o) ...@@ -377,7 +366,7 @@ static int check_updates(struct unpack_trees_options *o)
remove_scheduled_dirs(); remove_scheduled_dirs();
if (should_update_submodules() && o->update && !o->dry_run) if (should_update_submodules() && o->update && !o->dry_run)
reload_gitmodules_file(index, &state); load_gitmodules_file(index, &state);
enable_delayed_checkout(&state); enable_delayed_checkout(&state);
for (i = 0; i < index->cache_nr; i++) { for (i = 0; i < index->cache_nr; i++) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册