diff options
Diffstat (limited to 'submodule.c')
-rw-r--r-- | submodule.c | 108 |
1 files changed, 58 insertions, 50 deletions
diff --git a/submodule.c b/submodule.c index b958162d28..2e78f51349 100644 --- a/submodule.c +++ b/submodule.c @@ -1,5 +1,6 @@ - #include "cache.h" +#include "abspath.h" +#include "alloc.h" #include "repository.h" #include "config.h" #include "submodule-config.h" @@ -7,6 +8,9 @@ #include "dir.h" #include "diff.h" #include "commit.h" +#include "environment.h" +#include "gettext.h" +#include "hex.h" #include "revision.h" #include "run-command.h" #include "diffcore.h" @@ -20,9 +24,13 @@ #include "remote.h" #include "worktree.h" #include "parse-options.h" +#include "object-file.h" +#include "object-name.h" #include "object-store.h" #include "commit-reach.h" +#include "setup.h" #include "shallow.h" +#include "trace2.h" static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; static int initialized_fetch_ref_tips; @@ -65,7 +73,7 @@ int is_writing_gitmodules_ok(void) { struct object_id oid; return file_exists(GITMODULES_FILE) || - (get_oid(GITMODULES_INDEX, &oid) < 0 && get_oid(GITMODULES_HEAD, &oid) < 0); + (repo_get_oid(the_repository, GITMODULES_INDEX, &oid) < 0 && repo_get_oid(the_repository, GITMODULES_HEAD, &oid) < 0); } /* @@ -274,8 +282,7 @@ int is_tree_submodule_active(struct repository *repo, free(key); /* submodule.active is set */ - sl = repo_config_get_value_multi(repo, "submodule.active"); - if (sl) { + if (!repo_config_get_string_multi(repo, "submodule.active", &sl)) { struct pathspec ps; struct strvec args = STRVEC_INIT; const struct string_list_item *item; @@ -832,7 +839,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; @@ -1130,6 +1137,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"); @@ -1619,7 +1632,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf, if (!task->repo) { strbuf_addf(err, _("Could not access submodule '%s' at commit %s\n"), cs_data->path, - find_unique_abbrev(cs_data->super_oid, DEFAULT_ABBREV)); + repo_find_unique_abbrev(the_repository, cs_data->super_oid, DEFAULT_ABBREV)); fetch_task_release(task); free(task); @@ -1630,8 +1643,8 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf, strbuf_addf(err, _("Fetching submodule %s%s at commit %s\n"), spf->prefix, task->sub->path, - find_unique_abbrev(cs_data->super_oid, - DEFAULT_ABBREV)); + repo_find_unique_abbrev(the_repository, cs_data->super_oid, + DEFAULT_ABBREV)); spf->changed_count++; /* @@ -1733,7 +1746,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, return 0; } -static int fetch_start_failure(struct strbuf *err, +static int fetch_start_failure(struct strbuf *err UNUSED, void *cb, void *task_cb) { struct submodule_parallel_fetch *spf = cb; @@ -1754,7 +1767,7 @@ static int commit_missing_in_sub(const struct object_id *oid, void *data) return type != OBJ_COMMIT; } -static int fetch_finish(int retvalue, struct strbuf *err, +static int fetch_finish(int retvalue, struct strbuf *err UNUSED, void *cb, void *task_cb) { struct submodule_parallel_fetch *spf = cb; @@ -2048,14 +2061,6 @@ void submodule_unset_core_worktree(const struct submodule *sub) strbuf_release(&config_path); } -static const char *get_super_prefix_or_empty(void) -{ - const char *s = get_super_prefix(); - if (!s) - s = ""; - return s; -} - static int submodule_has_dirty_index(const struct submodule *sub) { struct child_process cp = CHILD_PROCESS_INIT; @@ -2074,7 +2079,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) return finish_command(&cp); } -static void submodule_reset_index(const char *path) +static void submodule_reset_index(const char *path, const char *super_prefix) { struct child_process cp = CHILD_PROCESS_INIT; prepare_submodule_repo_env(&cp.env); @@ -2083,10 +2088,10 @@ static void submodule_reset_index(const char *path) cp.no_stdin = 1; cp.dir = path; - strvec_pushf(&cp.args, "--super-prefix=%s%s/", - get_super_prefix_or_empty(), path); /* TODO: determine if this might overwright untracked files */ strvec_pushl(&cp.args, "read-tree", "-u", "--reset", NULL); + strvec_pushf(&cp.args, "--super-prefix=%s%s/", + (super_prefix ? super_prefix : ""), path); strvec_push(&cp.args, empty_tree_oid_hex()); @@ -2099,10 +2104,9 @@ static void submodule_reset_index(const char *path) * For edge cases (a submodule coming into existence or removing a submodule) * pass NULL for old or new respectively. */ -int submodule_move_head(const char *path, - const char *old_head, - const char *new_head, - unsigned flags) +int submodule_move_head(const char *path, const char *super_prefix, + const char *old_head, const char *new_head, + unsigned flags) { int ret = 0; struct child_process cp = CHILD_PROCESS_INIT; @@ -2140,7 +2144,7 @@ int submodule_move_head(const char *path, if (old_head) { if (!submodule_uses_gitfile(path)) absorb_git_dir_into_superproject(path, - ABSORB_GITDIR_RECURSE_SUBMODULES); + super_prefix); } else { struct strbuf gitdir = STRBUF_INIT; submodule_name_to_gitdir(&gitdir, the_repository, @@ -2149,7 +2153,7 @@ int submodule_move_head(const char *path, strbuf_release(&gitdir); /* make sure the index is clean as well */ - submodule_reset_index(path); + submodule_reset_index(path, super_prefix); } if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) { @@ -2167,9 +2171,9 @@ int submodule_move_head(const char *path, cp.no_stdin = 1; cp.dir = path; - strvec_pushf(&cp.args, "--super-prefix=%s%s/", - get_super_prefix_or_empty(), path); strvec_pushl(&cp.args, "read-tree", "--recurse-submodules", NULL); + strvec_pushf(&cp.args, "--super-prefix=%s%s/", + (super_prefix ? super_prefix : ""), path); if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN) strvec_push(&cp.args, "-n"); @@ -2269,7 +2273,8 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name) * Embeds a single submodules git directory into the superprojects git dir, * non recursively. */ -static void relocate_single_git_dir_into_superproject(const char *path) +static void relocate_single_git_dir_into_superproject(const char *path, + const char *super_prefix) { char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL; struct strbuf new_gitdir = STRBUF_INIT; @@ -2299,7 +2304,7 @@ static void relocate_single_git_dir_into_superproject(const char *path) real_new_git_dir = real_pathdup(new_gitdir.buf, 1); fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"), - get_super_prefix_or_empty(), path, + super_prefix ? super_prefix : "", path, real_old_git_dir, real_new_git_dir); relocate_gitdir(path, real_old_git_dir, real_new_git_dir); @@ -2310,13 +2315,32 @@ 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, + const char *super_prefix) +{ + + struct child_process cp = CHILD_PROCESS_INIT; + + cp.dir = path; + cp.git_cmd = 1; + cp.no_stdin = 1; + strvec_pushl(&cp.args, "submodule--helper", + "absorbgitdirs", NULL); + strvec_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ? + super_prefix : "", path); + + 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) + const char *super_prefix) { int err_code; const char *sub_git_dir; @@ -2358,30 +2382,14 @@ void absorb_git_dir_into_superproject(const char *path, char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1); if (!starts_with(real_sub_git_dir, real_common_git_dir)) - relocate_single_git_dir_into_superproject(path); + relocate_single_git_dir_into_superproject(path, super_prefix); free(real_sub_git_dir); free(real_common_git_dir); } strbuf_release(&gitdir); - if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) { - struct child_process cp = CHILD_PROCESS_INIT; - - if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES) - BUG("we don't know how to pass the flags down?"); - - 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); - } + absorb_git_dir_into_superproject_recurse(path, super_prefix); } int get_superproject_working_tree(struct strbuf *buf) |