diff options
Diffstat (limited to 'submodule.c')
| -rw-r--r-- | submodule.c | 148 |
1 files changed, 78 insertions, 70 deletions
diff --git a/submodule.c b/submodule.c index 86c8f0f89d..fae24ef34a 100644 --- a/submodule.c +++ b/submodule.c @@ -213,7 +213,8 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, } /* Cheap function that only determines if we're interested in submodules at all */ -int git_default_submodule_config(const char *var, const char *value, void *cb) +int git_default_submodule_config(const char *var, const char *value, + void *cb UNUSED) { if (!strcmp(var, "submodule.recurse")) { int v = git_config_bool(var, value) ? @@ -415,10 +416,9 @@ int parse_submodule_update_strategy(const char *value, return 0; } -const char *submodule_strategy_to_string(const struct submodule_update_strategy *s) +const char *submodule_update_type_to_string(enum submodule_update_type type) { - struct strbuf sb = STRBUF_INIT; - switch (s->type) { + switch (type) { case SM_UPDATE_CHECKOUT: return "checkout"; case SM_UPDATE_MERGE: @@ -428,12 +428,11 @@ const char *submodule_strategy_to_string(const struct submodule_update_strategy case SM_UPDATE_NONE: return "none"; case SM_UPDATE_UNSPECIFIED: - return NULL; case SM_UPDATE_COMMAND: - strbuf_addf(&sb, "!%s", s->command); - return strbuf_detach(&sb, NULL); + BUG("init_submodule() should handle type %d", type); + default: + BUG("unexpected update strategy type: %d", type); } - return NULL; } void handle_ignore_submodules_arg(struct diff_options *diffopt, @@ -619,7 +618,7 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path, struct object_id *one, struct object_id *two, unsigned dirty_submodule) { - struct rev_info rev; + struct rev_info rev = REV_INFO_INIT; struct commit *left = NULL, *right = NULL; struct commit_list *merge_bases = NULL; struct repository *sub; @@ -645,8 +644,8 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path, print_submodule_diff_summary(sub, &rev, o); out: - if (merge_bases) - free_commit_list(merge_bases); + free_commit_list(merge_bases); + release_revisions(&rev); clear_commit_marks(left, ~0); clear_commit_marks(right, ~0); if (sub) { @@ -711,15 +710,15 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, if (!(dirty_submodule & DIRTY_SUBMODULE_MODIFIED)) strvec_push(&cp.args, oid_to_hex(new_oid)); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); if (!is_directory(path)) { /* fall back to absorbed git dir, if any */ if (!sub) goto done; cp.dir = sub->gitdir; - strvec_push(&cp.env_array, GIT_DIR_ENVIRONMENT "=."); - strvec_push(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT "=."); + strvec_push(&cp.env, GIT_DIR_ENVIRONMENT "=."); + strvec_push(&cp.env, GIT_WORK_TREE_ENVIRONMENT "=."); } if (start_command(&cp)) { @@ -735,8 +734,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, done: strbuf_release(&sb); - if (merge_bases) - free_commit_list(merge_bases); + free_commit_list(merge_bases); if (left) clear_commit_marks(left, ~0); if (right) @@ -834,7 +832,7 @@ static void changed_submodule_data_clear(struct changed_submodule_data *cs_data) } static void collect_changed_submodules_cb(struct diff_queue_struct *q, - struct diff_options *options, + struct diff_options *options UNUSED, void *data) { struct collect_changed_submodules_cb_data *me = data; @@ -925,9 +923,11 @@ static void collect_changed_submodules(struct repository *r, diff_rev.diffopt.format_callback_data = &data; diff_rev.dense_combined_merges = 1; diff_tree_combined_merge(commit, &diff_rev); + release_revisions(&diff_rev); } reset_revision_walk(); + release_revisions(&rev); } static void free_submodules_data(struct string_list *submodules) @@ -939,8 +939,9 @@ static void free_submodules_data(struct string_list *submodules) string_list_clear(submodules, 1); } -static int has_remote(const char *refname, const struct object_id *oid, - int flags, void *cb_data) +static int has_remote(const char *refname UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, void *cb_data UNUSED) { return 1; } @@ -1019,7 +1020,7 @@ static int submodule_has_commits(struct repository *r, oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); strvec_pushl(&cp.args, "--not", "--all", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -1060,7 +1061,7 @@ static int submodule_needs_pushing(struct repository *r, oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); strvec_pushl(&cp.args, "--not", "--remotes", "-n", "1" , NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -1129,6 +1130,12 @@ static int push_submodule(const char *path, if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) { struct child_process cp = CHILD_PROCESS_INIT; strvec_push(&cp.args, "push"); + /* + * When recursing into a submodule, treat any "only" configurations as "on- + * demand", since "only" would not work (we need all submodules to be pushed + * in order to be able to push the superproject). + */ + strvec_push(&cp.args, "--recurse-submodules=only-is-on-demand"); if (dry_run) strvec_push(&cp.args, "--dry-run"); @@ -1146,7 +1153,7 @@ static int push_submodule(const char *path, strvec_push(&cp.args, rs->raw[i]); } - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -1177,7 +1184,7 @@ static void submodule_push_check(const char *path, const char *head, for (i = 0; i < rs->raw_nr; i++) strvec_push(&cp.args, rs->raw[i]); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stdout = 1; @@ -1242,8 +1249,9 @@ int push_unpushed_submodules(struct repository *r, return ret; } -static int append_oid_to_array(const char *ref, const struct object_id *oid, - int flags, void *data) +static int append_oid_to_array(const char *ref UNUSED, + const struct object_id *oid, + int flags UNUSED, void *data) { struct oid_array *array = data; oid_array_append(array, oid); @@ -1678,7 +1686,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, child_process_init(cp); cp->dir = task->repo->gitdir; - prepare_submodule_repo_env_in_gitdir(&cp->env_array); + prepare_submodule_repo_env_in_gitdir(&cp->env); cp->git_cmd = 1; strvec_init(&cp->args); if (task->git_args.nr) @@ -1708,7 +1716,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, spf->prefix, task->sub->path); child_process_init(cp); - prepare_submodule_repo_env_in_gitdir(&cp->env_array); + prepare_submodule_repo_env_in_gitdir(&cp->env); cp->git_cmd = 1; cp->dir = task->repo->gitdir; @@ -1817,6 +1825,17 @@ int fetch_submodules(struct repository *r, { int i; struct submodule_parallel_fetch spf = SPF_INIT; + const struct run_process_parallel_opts opts = { + .tr2_category = "submodule", + .tr2_label = "parallel/fetch", + + .processes = max_parallel_jobs, + + .get_next_task = get_next_submodule, + .start_failure = fetch_start_failure, + .task_finished = fetch_finish, + .data = &spf, + }; spf.r = r; spf.command_line_option = command_line_option; @@ -1838,12 +1857,7 @@ int fetch_submodules(struct repository *r, calculate_changed_submodule_paths(r, &spf.changed_submodule_names); string_list_sort(&spf.changed_submodule_names); - run_processes_parallel_tr2(max_parallel_jobs, - get_next_submodule, - fetch_start_failure, - fetch_finish, - &spf, - "submodule", "parallel/fetch"); + run_processes_parallel(&opts); if (spf.submodules_with_errors.len > 0) fprintf(stderr, _("Errors during submodule fetch:\n%s"), @@ -1882,7 +1896,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) if (ignore_untracked) strvec_push(&cp.args, "-uno"); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -1954,7 +1968,7 @@ int submodule_uses_gitfile(const char *path) "submodule", "foreach", "--quiet", "--recursive", "test -f .git", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stderr = 1; @@ -1997,7 +2011,7 @@ int bad_to_remove_submodule(const char *path, unsigned flags) if (!(flags & SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED)) strvec_push(&cp.args, "--ignored"); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -2052,7 +2066,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; strvec_pushl(&cp.args, "diff-index", "--quiet", @@ -2069,7 +2083,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) static void submodule_reset_index(const char *path) { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; @@ -2131,8 +2145,7 @@ int submodule_move_head(const char *path, if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) { if (old_head) { if (!submodule_uses_gitfile(path)) - absorb_git_dir_into_superproject(path, - ABSORB_GITDIR_RECURSE_SUBMODULES); + absorb_git_dir_into_superproject(path); } else { struct strbuf gitdir = STRBUF_INIT; submodule_name_to_gitdir(&gitdir, the_repository, @@ -2153,7 +2166,7 @@ int submodule_move_head(const char *path, } } - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; @@ -2191,7 +2204,7 @@ int submodule_move_head(const char *path, cp.no_stdin = 1; cp.dir = path; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); strvec_pushl(&cp.args, "update-ref", "HEAD", "--no-deref", new_head, NULL); @@ -2302,13 +2315,29 @@ static void relocate_single_git_dir_into_superproject(const char *path) strbuf_release(&new_gitdir); } +static void absorb_git_dir_into_superproject_recurse(const char *path) +{ + + struct child_process cp = CHILD_PROCESS_INIT; + + cp.dir = path; + cp.git_cmd = 1; + cp.no_stdin = 1; + strvec_pushf(&cp.args, "--super-prefix=%s%s/", + get_super_prefix_or_empty(), path); + strvec_pushl(&cp.args, "submodule--helper", + "absorbgitdirs", NULL); + prepare_submodule_repo_env(&cp.env); + if (run_command(&cp)) + die(_("could not recurse into submodule '%s'"), path); +} + /* * Migrate the git directory of the submodule given by path from * having its git directory within the working tree to the git dir nested * in its superprojects git dir under modules/. */ -void absorb_git_dir_into_superproject(const char *path, - unsigned flags) +void absorb_git_dir_into_superproject(const char *path) { int err_code; const char *sub_git_dir; @@ -2357,29 +2386,7 @@ void absorb_git_dir_into_superproject(const char *path, } strbuf_release(&gitdir); - if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) { - struct child_process cp = CHILD_PROCESS_INIT; - struct strbuf sb = STRBUF_INIT; - - if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES) - BUG("we don't know how to pass the flags down?"); - - strbuf_addstr(&sb, get_super_prefix_or_empty()); - strbuf_addstr(&sb, path); - strbuf_addch(&sb, '/'); - - cp.dir = path; - cp.git_cmd = 1; - cp.no_stdin = 1; - strvec_pushl(&cp.args, "--super-prefix", sb.buf, - "submodule--helper", - "absorb-git-dirs", NULL); - prepare_submodule_repo_env(&cp.env_array); - if (run_command(&cp)) - die(_("could not recurse into submodule '%s'"), path); - - strbuf_release(&sb); - } + absorb_git_dir_into_superproject_recurse(path); } int get_superproject_working_tree(struct strbuf *buf) @@ -2387,7 +2394,7 @@ int get_superproject_working_tree(struct strbuf *buf) struct child_process cp = CHILD_PROCESS_INIT; struct strbuf sb = STRBUF_INIT; struct strbuf one_up = STRBUF_INIT; - const char *cwd = xgetcwd(); + char *cwd = xgetcwd(); int ret = 0; const char *subpath; int code; @@ -2407,8 +2414,8 @@ int get_superproject_working_tree(struct strbuf *buf) subpath = relative_path(cwd, one_up.buf, &sb); strbuf_release(&one_up); - prepare_submodule_repo_env(&cp.env_array); - strvec_pop(&cp.env_array); + prepare_submodule_repo_env(&cp.env); + strvec_pop(&cp.env); strvec_pushl(&cp.args, "--literal-pathspecs", "-C", "..", "ls-files", "-z", "--stage", "--full-name", "--", @@ -2450,6 +2457,7 @@ int get_superproject_working_tree(struct strbuf *buf) ret = 1; free(super_wt); } + free(cwd); strbuf_release(&sb); code = finish_command(&cp); |
