diff options
Diffstat (limited to 'submodule.c')
-rw-r--r-- | submodule.c | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/submodule.c b/submodule.c index 91a4758747..6f1c10722f 100644 --- a/submodule.c +++ b/submodule.c @@ -10,7 +10,9 @@ #include "string-list.h" struct string_list config_name_for_path; +struct string_list config_fetch_recurse_submodules_for_name; struct string_list config_ignore_for_name; +static int config_fetch_recurse_submodules; static int add_submodule_odb(const char *path) { @@ -63,10 +65,14 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, } } -static int submodule_config(const char *var, const char *value, void *cb) +int submodule_config(const char *var, const char *value, void *cb) { if (!prefixcmp(var, "submodule.")) return parse_submodule_config_option(var, value); + else if (!strcmp(var, "fetch.recursesubmodules")) { + config_fetch_recurse_submodules = git_config_bool(var, value); + return 0; + } return 0; } @@ -100,6 +106,14 @@ int parse_submodule_config_option(const char *var, const char *value) config = string_list_append(&config_name_for_path, xstrdup(value)); config->util = strbuf_detach(&submodname, NULL); strbuf_release(&submodname); + } else if ((len > 23) && !strcmp(var + len - 23, ".fetchrecursesubmodules")) { + strbuf_add(&submodname, var, len - 23); + config = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, submodname.buf); + if (!config) + config = string_list_append(&config_fetch_recurse_submodules_for_name, + strbuf_detach(&submodname, NULL)); + config->util = git_config_bool(var, value) ? (void *)1 : NULL; + strbuf_release(&submodname); } else if ((len > 7) && !strcmp(var + len - 7, ".ignore")) { if (strcmp(value, "untracked") && strcmp(value, "dirty") && strcmp(value, "all") && strcmp(value, "none")) { @@ -229,6 +243,89 @@ void show_submodule_summary(FILE *f, const char *path, strbuf_release(&sb); } +void set_config_fetch_recurse_submodules(int value) +{ + config_fetch_recurse_submodules = value; +} + +int fetch_populated_submodules(int num_options, const char **options, + const char *prefix, int ignore_config, + int quiet) +{ + int i, result = 0, argc = 0; + struct child_process cp; + const char **argv; + struct string_list_item *name_for_path; + const char *work_tree = get_git_work_tree(); + if (!work_tree) + return 0; + + if (!the_index.initialized) + if (read_cache() < 0) + die("index file corrupt"); + + /* 4: "fetch" (options) "--submodule-prefix" prefix NULL */ + argv = xcalloc(num_options + 4, sizeof(const char *)); + argv[argc++] = "fetch"; + for (i = 0; i < num_options; i++) + argv[argc++] = options[i]; + argv[argc++] = "--submodule-prefix"; + + memset(&cp, 0, sizeof(cp)); + cp.argv = argv; + cp.env = local_repo_env; + cp.git_cmd = 1; + cp.no_stdin = 1; + + for (i = 0; i < active_nr; i++) { + struct strbuf submodule_path = STRBUF_INIT; + struct strbuf submodule_git_dir = STRBUF_INIT; + struct strbuf submodule_prefix = STRBUF_INIT; + struct cache_entry *ce = active_cache[i]; + const char *git_dir, *name; + + if (!S_ISGITLINK(ce->ce_mode)) + continue; + + name = ce->name; + name_for_path = unsorted_string_list_lookup(&config_name_for_path, ce->name); + if (name_for_path) + name = name_for_path->util; + + if (!ignore_config) { + struct string_list_item *fetch_recurse_submodules_option; + fetch_recurse_submodules_option = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name); + if (fetch_recurse_submodules_option) { + if (!fetch_recurse_submodules_option->util) + continue; + } else { + if (!config_fetch_recurse_submodules) + continue; + } + } + + strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name); + strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf); + strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name); + git_dir = read_gitfile_gently(submodule_git_dir.buf); + if (!git_dir) + git_dir = submodule_git_dir.buf; + if (is_directory(git_dir)) { + if (!quiet) + printf("Fetching submodule %s%s\n", prefix, ce->name); + cp.dir = submodule_path.buf; + argv[argc] = submodule_prefix.buf; + if (run_command(&cp)) + result = 1; + } + strbuf_release(&submodule_path); + strbuf_release(&submodule_git_dir); + strbuf_release(&submodule_prefix); + } + free(argv); + return result; +} + unsigned is_submodule_modified(const char *path, int ignore_untracked) { ssize_t len; |