* [PATCH 00/13] submodule: convert the rest of 'update' to C @ 2021-09-07 11:59 Atharva Raykar 2021-09-07 11:59 ` [PATCH 01/13] submodule--helper: split up ensure_core_worktree() Atharva Raykar ` (15 more replies) 0 siblings, 16 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar NOTE: This series uses ar/submodule-run-update-procedure [1] This series builds upon the previous conversion work on 'submodule update' and moves out all of that shell logic in 'git-submodule.sh' into 'builtin/submodule--helper.c'. Even though this patch series looks long, a lot of it is preparatory patches and cleanup of unused functions that result from this conversion. The real action happens at [6/8]. As with the other series, the goal is to be a faithful conversion, with no change in behaviour. This would be the last command whose logic would be moved into C, other than 'submodule add', whose patches have been sent already. After this works out, we can invert the shell-C relationship and make 'submodule' a proper C builtin. Fetch-it-Via: git fetch https://github.com/tfidfwastaken/git submodule-update-list-1 [1] https://lore.kernel.org/git/20210824140609.1496-1-raykar.ath@gmail.com/ Atharva Raykar (13): submodule--helper: split up ensure_core_worktree() submodule--helper: get remote names from any repository submodule--helper: introduce get_default_remote_submodule() submodule--helper: rename helpers for update-clone submodule--helper: refactor get_submodule_displaypath() submodule: move core cmd_update() logic to C submodule: remove fetch_in_submodule shell function submodule--helper: remove update-clone subcommand submodule--helper: remove update-module-mode subcommand submodule--helper: remove shell interface to ensure_core_worktree() submodule--helper: remove print-default-remote subcommand submodule--helper: remove relative-path subcommand submodule--helper: remove run-update-procedure subcommand builtin/submodule--helper.c | 764 +++++++++++++++++++++--------------- git-submodule.sh | 145 +------ 2 files changed, 455 insertions(+), 454 deletions(-) -- 2.32.0 ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 01/13] submodule--helper: split up ensure_core_worktree() 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 02/13] submodule--helper: get remote names from any repository Atharva Raykar ` (14 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar Let's split up `ensure_core_worktree()` so that we can call it from C code without needing to deal with command line arguments. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 80619361fc..97512ccf0b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2794,18 +2794,12 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void do_ensure_core_worktree(const char *path) { const struct submodule *sub; - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - sub = submodule_from_path(the_repository, null_oid(), path); if (!sub) BUG("We could get the submodule handle before?"); @@ -2829,6 +2823,17 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } +} + +static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +{ + const char *path; + + if (argc != 2) + BUG("submodule--helper ensure-core-worktree <path>"); + + path = argv[1]; + do_ensure_core_worktree(path); return 0; } -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 02/13] submodule--helper: get remote names from any repository 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar 2021-09-07 11:59 ` [PATCH 01/13] submodule--helper: split up ensure_core_worktree() Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:37 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 03/13] submodule--helper: introduce get_default_remote_submodule() Atharva Raykar ` (13 subsequent siblings) 15 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 97512ccf0b..1a65de4fa4 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,10 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo, const char *refname) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +45,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +54,12 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote(void) +{ + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + return repo_get_default_remote(the_repository, refname); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 02/13] submodule--helper: get remote names from any repository 2021-09-07 11:59 ` [PATCH 02/13] submodule--helper: get remote names from any repository Atharva Raykar @ 2021-09-07 12:37 ` Ævar Arnfjörð Bjarmason 2021-09-07 13:33 ` Atharva Raykar 0 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:37 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > `get_default_remote()` retrieves the name of a remote by resolving the > refs from of the current repository's ref store. > > Thus in order to use it for retrieving the remote name of a submodule, > we have to start a new subprocess which runs from the submodule > directory. > > Let's instead introduce a function called `repo_get_default_remote()` > which takes any repository object and retrieves the remote accordingly. > > `get_default_remote()` is then defined as a call to > `repo_get_default_remote()` with 'the_repository' passed to it. I'd find this easier to follow if this were just squashed into the next commit. Both are rather small, but following the context of first adding a function, then using it, instead of just adding it, changing the old users etc. is harder than just having it in one commit. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH 02/13] submodule--helper: get remote names from any repository 2021-09-07 12:37 ` Ævar Arnfjörð Bjarmason @ 2021-09-07 13:33 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 13:33 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, Sep 07 2021, Atharva Raykar wrote: > >> `get_default_remote()` retrieves the name of a remote by resolving the >> refs from of the current repository's ref store. >> >> Thus in order to use it for retrieving the remote name of a submodule, >> we have to start a new subprocess which runs from the submodule >> directory. >> >> Let's instead introduce a function called `repo_get_default_remote()` >> which takes any repository object and retrieves the remote accordingly. >> >> `get_default_remote()` is then defined as a call to >> `repo_get_default_remote()` with 'the_repository' passed to it. > > I'd find this easier to follow if this were just squashed into the next > commit. Both are rather small, but following the context of first adding > a function, then using it, instead of just adding it, changing the old > users etc. is harder than just having it in one commit. I am in two minds about this. I initially had both these changes in one commit, but Christian suggested I split the changes into a part that refactors existing code (this commit), and one that introduces a new helper (the next commit). I guess I will squash it for now and see how it is received. Maybe bringing down the "/13" might help get more reviews ;-) ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 03/13] submodule--helper: introduce get_default_remote_submodule() 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar 2021-09-07 11:59 ` [PATCH 01/13] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-09-07 11:59 ` [PATCH 02/13] submodule--helper: get remote names from any repository Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 04/13] submodule--helper: rename helpers for update-clone Atharva Raykar ` (12 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar Before 8ef1d2b549 (submodule--helper: get remote names from any repository, 2021-07-20), it was not possible to directly retrieve a submodule's remote name within the same process, because `get_default_remote()` used only knew about the current repository. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. Let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 1a65de4fa4..f6c4fc349b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -54,6 +54,19 @@ static char *repo_get_default_remote(struct repository *repo, const char *refnam return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + const char *refname; + const struct submodule *sub; + struct repository subrepo; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), + "HEAD", 0, NULL, NULL); + sub = submodule_from_path(the_repository, null_oid(), module_path); + repo_submodule_init(&subrepo, the_repository, sub); + return repo_get_default_remote(&subrepo, refname); +} + static char *get_default_remote(void) { const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); @@ -1374,7 +1387,6 @@ static void sync_submodule(const char *path, const char *prefix, char *remote_key = NULL; char *sub_origin_url, *super_config_url, *displaypath; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1423,14 +1435,9 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + strbuf_addstr(&sb, get_default_remote_submodule(path)); + if (!sb.buf) die(_("failed to get the default remote for submodule '%s'"), path); -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 04/13] submodule--helper: rename helpers for update-clone 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (2 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 03/13] submodule--helper: introduce get_default_remote_submodule() Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 05/13] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar ` (11 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar The `update-clone` subcommand helpers that perform the parallel clone and printing to stdout for shell script consumption, are renamed. This lets us use the names `update_submodules()` and `update_submodule()` for the helpers in the next patch, when we create an `update` subcommand that does a full conversion. We will get rid of these helpers in a cleanup patch at the end of this series, when the `update-clone` command is no longer useful to us. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f6c4fc349b..b0336b0377 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2499,7 +2499,7 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) +static void update_clone_submodule(struct update_clone_data *ucd) { fprintf(stdout, "dummy %s %d\t%s\n", oid_to_hex(&ucd->oid), @@ -2507,7 +2507,7 @@ static void update_submodule(struct update_clone_data *ucd) ucd->sub->path); } -static int update_submodules(struct submodule_update_clone *suc) +static int update_clone_submodules(struct submodule_update_clone *suc) { int i; @@ -2528,7 +2528,7 @@ static int update_submodules(struct submodule_update_clone *suc) return 1; for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); + update_clone_submodule(&suc->update_clone[i]); return 0; } @@ -2593,7 +2593,7 @@ static int update_clone(int argc, const char **argv, const char *prefix) if (pathspec.nr) suc.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_clone_submodules(&suc); } static int run_update_procedure(int argc, const char **argv, const char *prefix) -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 05/13] submodule--helper: refactor get_submodule_displaypath() 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (3 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 04/13] submodule--helper: rename helpers for update-clone Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Atharva Raykar ` (10 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b0336b0377..10de01a1f7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -269,11 +269,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -289,6 +286,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 06/13] submodule: move core cmd_update() logic to C 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (4 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 05/13] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:40 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 07/13] submodule: remove fetch_in_submodule shell function Atharva Raykar ` (9 subsequent siblings) 15 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. We also introduce `update_submodules()` and `update_submodule()` which are quite similar to `update_clone_submodules()` and `update_clone_submodule()`, and will supersede them. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the `init_submodule_cb()` callback over each submodule directly. This introduces another problem, because there is no mechanism to pass the superproject path prefix (ie, `--super-prefix`) without starting a new git process. This field is required for obtaining the display path for that is used by the command's output messages. So let's add a field into the `init_cb` struct that lets us pass this information to `init_submodule()`, which will now also take an explicit 'superprefix' argument. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 502 ++++++++++++++++++++++++++++++------ git-submodule.sh | 131 +--------- 2 files changed, 430 insertions(+), 203 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 10de01a1f7..2cccb9a9ab 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -634,18 +634,22 @@ static char *compute_submodule_clone_url(const char *rel_url) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; -#define INIT_CB_INIT { NULL, 0 } +#define INIT_CB_INIT { NULL, NULL, 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -719,7 +723,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) @@ -2039,7 +2043,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -2062,19 +2065,63 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; struct object_id oid; struct object_id suboid; - struct submodule_update_strategy update_strategy; + int max_jobs; int depth; + int recommend_shallow; + int single_branch; + unsigned int init: 1; unsigned int force: 1; unsigned int quiet: 1; unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int remote: 1; + unsigned int recursive: 1; + unsigned int progress: 1; + unsigned int dissociate: 1; + unsigned int require_init: 1; + unsigned warn_if_uninitialized : 1; + unsigned int just_cloned : 1; + struct submodule_update_strategy update_strategy; + struct string_list references; + struct module_list list; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -2369,111 +2416,113 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str return run_command(&cp); } -static int run_update_command(struct update_data *ud, int subforce) +static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); + struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; - int git_cmd; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; + + cp.dir = xstrdup(ud->sm_path); + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.git_cmd = 0; + cp.use_shell = 1; + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + prepare_submodule_repo_env(&cp.env_array); + if (capture_command(&cp, &out, 0)) { + if (must_die_on_failure) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + die(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_REBASE: + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_MERGE: + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_COMMAND: + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + + /* the command failed, but update must continue */ + string_list_append(err, out.buf); return 1; } - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_REBASE: - printf(_("Submodule path '%s': rebased into '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_MERGE: - printf(_("Submodule path '%s': merged in '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_COMMAND: - printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + if (!ud->quiet) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + printf(_("Submodule path '%s': checked out '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_REBASE: + printf(_("Submodule path '%s': rebased into '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_MERGE: + printf(_("Submodule path '%s': merged in '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_COMMAND: + printf(_("Submodule path '%s': '%s %s'\n"), + ud->displaypath, strategy.command, oid); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int do_run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2500,7 +2549,7 @@ static int do_run_update_procedure(struct update_data *ud) ud->displaypath, oid_to_hex(&ud->oid)); } - return run_update_command(ud, subforce); + return run_update_command(ud, subforce, err); } static void update_clone_submodule(struct update_clone_data *ucd) @@ -2605,6 +2654,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data update_data = UPDATE_DATA_INIT; + struct string_list err = STRING_LIST_INIT_DUP; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2662,7 +2712,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) free(prefixed_path); if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + return do_run_update_procedure(&update_data, &err); return 3; } @@ -3038,6 +3088,288 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; + struct string_list err = STRING_LIST_INIT_DUP; + + do_ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if(fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + if (do_run_update_procedure(update_data, &err)) + return 1; + + if (update_data->recursive) { + int res; + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + if ((res = run_command(&cp)) == 128) + die("%s", die_msg); + if (res) + string_list_append(&err, die_msg); + + free(die_msg); + } + + if (err.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &err) + fputs(item->string, stderr); + return 1; + } + + return 0; +} + +static int update_submodules(struct update_data *update_data) +{ + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, &suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) + return 1; + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; + + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ + int init = 0, force = 0, quiet = 0, nofetch = 0; + int remote = 0, recursive = 0, dissociate = 0; + int progress = 0, require_init = 0; + const char *update = NULL; + struct pathspec pathspec; + struct update_data update_data = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { + OPT__FORCE(&force, N_("force checkout updates"), 0), + OPT_BOOL(0, "init", &init, + N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "remote", &remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &update_data.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &dissociate, + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &update_data.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &update_data.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &update_data.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &update_data.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + + update_clone_config_from_gitmodules(&update_data.max_jobs); + git_config(git_update_clone_config, &update_data.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + update_data.prefix = prefix; + + update_data.force = !!force; + update_data.quiet = !!quiet; + update_data.nofetch = !!nofetch; + update_data.init = !!init; + update_data.require_init = !!require_init; + update_data.remote = !!remote; + update_data.recursive = !!recursive; + update_data.progress = !!progress; + update_data.dissociate = !!dissociate; + oidcpy(&update_data.oid, null_oid()); + oidcpy(&update_data.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, + &update_data.update_strategy) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &update_data.list) < 0) + return 1; + + if (pathspec.nr) + update_data.warn_if_uninitialized = 1; + + if (update_data.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, update_data.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = update_data.prefix; + info.superprefix = update_data.recursive_prefix; + if (update_data.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&update_data); +} + struct add_data { const char *prefix; const char *branch; @@ -3213,6 +3545,7 @@ static int add_clone(int argc, const char **argv, const char *prefix) return 0; } + #define SUPPORT_SUPER_PREFIX (1<<0) struct cmd_struct { @@ -3226,6 +3559,7 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, + {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, diff --git a/git-submodule.sh b/git-submodule.sh index f703cddce8..4e21d9715c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -484,133 +484,26 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + ${GIT_QUIET:+--quiet} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 1 - then - subsha1= - else - just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" - fi - - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 06/13] submodule: move core cmd_update() logic to C 2021-09-07 11:59 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Atharva Raykar @ 2021-09-07 12:40 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:40 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > struct init_cb { > const char *prefix; > + const char *superprefix; > unsigned int flags; > }; > -#define INIT_CB_INIT { NULL, 0 } > +#define INIT_CB_INIT { NULL, NULL, 0 } Since you're doing some cleanup while you're at it, just changing this in some earlier step to: define INIT_CB_INIT { 0 } Is better, i.e. the NULL-ing out is implicit here. I have an unsubmitted series that does that across the codebase. > + .references = STRING_LIST_INIT_DUP, \ We do inits here, and append, but it seems nothing clears this string_list. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 07/13] submodule: remove fetch_in_submodule shell function 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (5 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:44 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 08/13] submodule--helper: remove update-clone subcommand Atharva Raykar ` (8 subsequent siblings) 15 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar This function has no more use in 'git-submodule.sh' after bd82d7d467 (submodule: move core cmd_update() logic to C, 2021-07-20), where we moved all of its uses to C, which has its own version for the same. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- git-submodule.sh | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 4e21d9715c..5197de4551 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -369,20 +369,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 07/13] submodule: remove fetch_in_submodule shell function 2021-09-07 11:59 ` [PATCH 07/13] submodule: remove fetch_in_submodule shell function Atharva Raykar @ 2021-09-07 12:44 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:44 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > This function has no more use in 'git-submodule.sh' after > bd82d7d467 (submodule: move core cmd_update() logic to C, 2021-07-20), > where we moved all of its uses to C, which has its own version for the > same. This commit ID appears to be a reference to your own 06/13, so the OID won't work once this is merged to git.git. Perhaps just squash this into 06/13 instead? ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 08/13] submodule--helper: remove update-clone subcommand 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (6 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 07/13] submodule: remove fetch_in_submodule shell function Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:46 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 09/13] submodule--helper: remove update-module-mode subcommand Atharva Raykar ` (7 subsequent siblings) 15 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar We no longer need this subcommand as the shell version calls the 'update' subcommand instead, which does all the cloning within C itself. We also no longer need the 'update_clone_submodules()' and 'update_clone_submodule()' functions, so we remove those as well. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 98 ------------------------------------- 1 file changed, 98 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 2cccb9a9ab..a628660d6b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2552,103 +2552,6 @@ static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } -static void update_clone_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -static int update_clone_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_clone_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - suc.prefix = prefix; - - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) - return 1; - - if (pathspec.nr) - suc.warn_if_uninitialized = 1; - - return update_clone_submodules(&suc); -} - static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; @@ -3561,7 +3464,6 @@ static struct cmd_struct commands[] = { {"add-clone", add_clone, 0}, {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 08/13] submodule--helper: remove update-clone subcommand 2021-09-07 11:59 ` [PATCH 08/13] submodule--helper: remove update-clone subcommand Atharva Raykar @ 2021-09-07 12:46 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:46 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > We no longer need this subcommand as the shell version calls the > 'update' subcommand instead, which does all the cloning within C itself. > > We also no longer need the 'update_clone_submodules()' and > 'update_clone_submodule()' functions, so we remove those as well. So in 04/13 update_clone_submodules() was renamed, but now we're getting rid of it. Maybe there's not an easy way to avoid this churn, but if there is... ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 09/13] submodule--helper: remove update-module-mode subcommand 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (7 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 08/13] submodule--helper: remove update-clone subcommand Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:49 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 10/13] submodule--helper: remove shell interface to ensure_core_worktree() Atharva Raykar ` (6 subsequent siblings) 15 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar This subcommand was once useful for 'submodule update', but now that we have converted the shell code to C, it is no longer used. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a628660d6b..e3e85600c3 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1993,29 +1993,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -3463,7 +3440,6 @@ static struct cmd_struct commands[] = { {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, {"update", module_update, 0}, - {"update-module-mode", module_update_module_mode, 0}, {"run-update-procedure", run_update_procedure, 0}, {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 09/13] submodule--helper: remove update-module-mode subcommand 2021-09-07 11:59 ` [PATCH 09/13] submodule--helper: remove update-module-mode subcommand Atharva Raykar @ 2021-09-07 12:49 ` Ævar Arnfjörð Bjarmason 2021-09-07 13:50 ` Atharva Raykar 0 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:49 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > This subcommand was once useful for 'submodule update', but now that we > have converted the shell code to C, it is no longer used. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- > builtin/submodule--helper.c | 24 ------------------------ > 1 file changed, 24 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index a628660d6b..e3e85600c3 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -1993,29 +1993,6 @@ static void determine_submodule_update_strategy(struct repository *r, > free(key); > } > > -static int module_update_module_mode(int argc, const char **argv, const char *prefix) > -{ > - const char *path, *update = NULL; > - int just_cloned; > - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; > - > - if (argc < 3 || argc > 4) > - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); > - > - just_cloned = git_config_int("just_cloned", argv[1]); > - path = argv[2]; > - > - if (argc == 4) > - update = argv[3]; > - > - determine_submodule_update_strategy(the_repository, > - just_cloned, path, update, > - &update_strategy); > - fputs(submodule_strategy_to_string(&update_strategy), stdout); > - > - return 0; > -} > - > struct update_clone_data { > const struct submodule *sub; > struct object_id oid; > @@ -3463,7 +3440,6 @@ static struct cmd_struct commands[] = { > {"clone", module_clone, 0}, > {"add-clone", add_clone, 0}, > {"update", module_update, 0}, > - {"update-module-mode", module_update_module_mode, 0}, > {"run-update-procedure", run_update_procedure, 0}, > {"ensure-core-worktree", ensure_core_worktree, 0}, > {"relative-path", resolve_relative_path, 0}, So in https://lore.kernel.org/git/87sfyglfl9.fsf@evledraar.gmail.com I suggested squashing the shell removal, but I see now that here later in 09-13/13. So yeah, having 08/13 stand-alone is easier to read then, but I think then squashing all of 09-13 together is better. I.e. there's no reason to remove these one at a time, let's just remove them all at once. That also makes it clear that it's a remove-only change aside from your "refactor while at it" of renaming this function: -static int do_run_update_procedure(struct update_data *ud, struct string_list *err) +static int run_update_procedure(struct update_data *ud, struct string_list *err) We could either skip that, or split that later refactoring into another commit. Thanks for working on this, I'm exciting to see more of git-submodule.sh go away. Hopefully these comments I left are useful / will aid future reviewer readability of this series. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH 09/13] submodule--helper: remove update-module-mode subcommand 2021-09-07 12:49 ` Ævar Arnfjörð Bjarmason @ 2021-09-07 13:50 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 13:50 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, Sep 07 2021, Atharva Raykar wrote: > >> This subcommand was once useful for 'submodule update', but now that we >> have converted the shell code to C, it is no longer used. >> >> Mentored-by: Christian Couder <christian.couder@gmail.com> >> Mentored-by: Shourya Shukla <periperidip@gmail.com> >> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> >> --- >> builtin/submodule--helper.c | 24 ------------------------ >> 1 file changed, 24 deletions(-) >> >> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c >> index a628660d6b..e3e85600c3 100644 >> --- a/builtin/submodule--helper.c >> +++ b/builtin/submodule--helper.c >> @@ -1993,29 +1993,6 @@ static void determine_submodule_update_strategy(struct repository *r, >> free(key); >> } >> >> -static int module_update_module_mode(int argc, const char **argv, const char *prefix) >> -{ >> - const char *path, *update = NULL; >> - int just_cloned; >> - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; >> - >> - if (argc < 3 || argc > 4) >> - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); >> - >> - just_cloned = git_config_int("just_cloned", argv[1]); >> - path = argv[2]; >> - >> - if (argc == 4) >> - update = argv[3]; >> - >> - determine_submodule_update_strategy(the_repository, >> - just_cloned, path, update, >> - &update_strategy); >> - fputs(submodule_strategy_to_string(&update_strategy), stdout); >> - >> - return 0; >> -} >> - >> struct update_clone_data { >> const struct submodule *sub; >> struct object_id oid; >> @@ -3463,7 +3440,6 @@ static struct cmd_struct commands[] = { >> {"clone", module_clone, 0}, >> {"add-clone", add_clone, 0}, >> {"update", module_update, 0}, >> - {"update-module-mode", module_update_module_mode, 0}, >> {"run-update-procedure", run_update_procedure, 0}, >> {"ensure-core-worktree", ensure_core_worktree, 0}, >> {"relative-path", resolve_relative_path, 0}, > > So in https://lore.kernel.org/git/87sfyglfl9.fsf@evledraar.gmail.com I > suggested squashing the shell removal, but I see now that here later in > 09-13/13. > > So yeah, having 08/13 stand-alone is easier to read then, but I think > then squashing all of 09-13 together is better. I.e. there's no reason > to remove these one at a time, let's just remove them all at once. Okay, I shall do this. > That also makes it clear that it's a remove-only change aside from your > "refactor while at it" of renaming this function: > > -static int do_run_update_procedure(struct update_data *ud, struct string_list *err) > +static int run_update_procedure(struct update_data *ud, struct string_list *err) > > We could either skip that, or split that later refactoring into another > commit. > > Thanks for working on this, I'm exciting to see more of git-submodule.sh > go away. Hopefully these comments I left are useful / will aid future > reviewer readability of this series. Thanks for your suggestions. I've gone through all of them, and I'll reroll soon. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH 10/13] submodule--helper: remove shell interface to ensure_core_worktree() 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (8 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 09/13] submodule--helper: remove update-module-mode subcommand Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 11/13] submodule--helper: remove print-default-remote subcommand Atharva Raykar ` (5 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar The 'ensure-core-worktree' subcommand is no longer needed since the conversion of the update code from shell to C. Let's remove the subcommand, and while we are at it, let's rename 'do_ensure_core_worktree()' to 'ensure_core_worktree()' to signal that it is no longer a utility function meant to be called by another function. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index e3e85600c3..597e303889 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2740,7 +2740,7 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static void do_ensure_core_worktree(const char *path) +static void ensure_core_worktree(const char *path) { const struct submodule *sub; const char *cw; @@ -2771,19 +2771,6 @@ static void do_ensure_core_worktree(const char *path) } } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) -{ - const char *path; - - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - do_ensure_core_worktree(path); - - return 0; -} - static int absorb_git_dirs(int argc, const char **argv, const char *prefix) { int i; @@ -3017,7 +3004,7 @@ static int update_submodule(struct update_data *update_data) char *prefixed_path; struct string_list err = STRING_LIST_INIT_DUP; - do_ensure_core_worktree(update_data->sm_path); + ensure_core_worktree(update_data->sm_path); if (update_data->recursive_prefix) prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, @@ -3441,7 +3428,6 @@ static struct cmd_struct commands[] = { {"add-clone", add_clone, 0}, {"update", module_update, 0}, {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 11/13] submodule--helper: remove print-default-remote subcommand 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (9 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 10/13] submodule--helper: remove shell interface to ensure_core_worktree() Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 12/13] submodule--helper: remove relative-path subcommand Atharva Raykar ` (4 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar This subcommand was once useful for submodule functionality, but after the various conversions of shell code to C, it is no longer used. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 597e303889..9470ff3de0 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -73,21 +73,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository, refname); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -3434,7 +3419,6 @@ static struct cmd_struct commands[] = { {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 12/13] submodule--helper: remove relative-path subcommand 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (10 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 11/13] submodule--helper: remove print-default-remote subcommand Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 13/13] submodule--helper: remove run-update-procedure subcommand Atharva Raykar ` (3 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar This subcommand was once used extensively for submodule functionality when it was written in shell, but now that we have converted the shell code to C, it is no longer used. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9470ff3de0..7622d6bd24 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2582,17 +2582,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) return 3; } -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -3413,7 +3402,6 @@ static struct cmd_struct commands[] = { {"add-clone", add_clone, 0}, {"update", module_update, 0}, {"run-update-procedure", run_update_procedure, 0}, - {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH 13/13] submodule--helper: remove run-update-procedure subcommand 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (11 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 12/13] submodule--helper: remove relative-path subcommand Atharva Raykar @ 2021-09-07 11:59 ` Atharva Raykar 2021-09-07 12:34 ` [PATCH 00/13] submodule: convert the rest of 'update' to C Ævar Arnfjörð Bjarmason ` (2 subsequent siblings) 15 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 11:59 UTC (permalink / raw) To: git Cc: christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip, avarab, Atharva Raykar The subcommand 'submodule--helper run-update-procedure' is no longer needed after the conversion of the bulk of 'update' to C. While we are at it, let's rename 'do_run_update_procedure()' to 'run_update_procedure()' to reflect the fact that it is no longer a utility function meant to be wrapped in another function. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 73 +------------------------------------ 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 7622d6bd24..6565e2cd78 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2484,7 +2484,7 @@ static int run_update_command(struct update_data *ud, int subforce, struct strin return 0; } -static int do_run_update_procedure(struct update_data *ud, struct string_list *err) +static int run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2514,74 +2514,6 @@ static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; - struct string_list err = STRING_LIST_INIT_DUP; - - struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; - - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); - else - prefixed_path = xstrdup(update_data.sm_path); - - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); - - free(prefixed_path); - - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data, &err); - - return 3; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -3018,7 +2950,7 @@ static int update_submodule(struct update_data *update_data) } if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) - if (do_run_update_procedure(update_data, &err)) + if (run_update_procedure(update_data, &err)) return 1; if (update_data->recursive) { @@ -3401,7 +3333,6 @@ static struct cmd_struct commands[] = { {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, {"update", module_update, 0}, - {"run-update-procedure", run_update_procedure, 0}, {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH 00/13] submodule: convert the rest of 'update' to C 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (12 preceding siblings ...) 2021-09-07 11:59 ` [PATCH 13/13] submodule--helper: remove run-update-procedure subcommand Atharva Raykar @ 2021-09-07 12:34 ` Ævar Arnfjörð Bjarmason 2021-09-07 12:53 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar 2021-10-14 21:50 ` [PATCH 00/13] " Glen Choo 15 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-09-07 12:34 UTC (permalink / raw) To: Atharva Raykar Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip On Tue, Sep 07 2021, Atharva Raykar wrote: > NOTE: This series uses ar/submodule-run-update-procedure [1] > > This series builds upon the previous conversion work on 'submodule update' and > moves out all of that shell logic in 'git-submodule.sh' into > 'builtin/submodule--helper.c'. Even though this patch series looks long, a lot > of it is preparatory patches and cleanup of unused functions that result from > this conversion. The real action happens at [6/8]. It looks like the 6/x part of that still applies, but not the "/8", i.e. this is now a 13-part series. Is this summary otherwise still current with what's being submitted here? ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH 00/13] submodule: convert the rest of 'update' to C 2021-09-07 12:34 ` [PATCH 00/13] submodule: convert the rest of 'update' to C Ævar Arnfjörð Bjarmason @ 2021-09-07 12:53 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-07 12:53 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, christian.couder, emilyshaffer, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, Sep 07 2021, Atharva Raykar wrote: > >> NOTE: This series uses ar/submodule-run-update-procedure [1] >> >> This series builds upon the previous conversion work on 'submodule update' and >> moves out all of that shell logic in 'git-submodule.sh' into >> 'builtin/submodule--helper.c'. Even though this patch series looks long, a lot >> of it is preparatory patches and cleanup of unused functions that result from >> this conversion. The real action happens at [6/8]. > > It looks like the 6/x part of that still applies, but not the "/8", > i.e. this is now a 13-part series. Is this summary otherwise still > current with what's being submitted here? Sorry, I meant [6/13], this is meant to be 13 parts only. Other than that typo, the summary is up-to-date with what the series contains (I wrote all of it today). ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v2 0/8] submodule: convert the rest of 'update' to C 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (13 preceding siblings ...) 2021-09-07 12:34 ` [PATCH 00/13] submodule: convert the rest of 'update' to C Ævar Arnfjörð Bjarmason @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() Atharva Raykar ` (8 more replies) 2021-10-14 21:50 ` [PATCH 00/13] " Glen Choo 15 siblings, 9 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip NOTE: This series uses ar/submodule-run-update-procedure, which is now part of 'next'. [1] Since v1: I have incorporated Ævar's suggestions, and attempted to make this easier to review. This series builds upon the previous conversion work on 'submodule update' and moves out all of that shell logic in 'git-submodule.sh' into 'builtin/submodule--helper.c'. Even though this patch series looks a bit long, a lot of it is preparatory patches and cleanup of unused functions that result from this conversion. The real action happens at [5/8]. As with the other series, the goal is to be a faithful conversion, with no change in behaviour. This would be the last command whose logic would be moved into C, other than 'submodule add', whose patches have been sent already. After this works out, we can invert the shell-C relationship and make 'submodule' a proper C builtin. Fetch-it-Via: git fetch https://github.com/tfidfwastaken/git submodule-update-list-2 [1] https://lore.kernel.org/git/20210824140609.1496-1-raykar.ath@gmail.com/ Atharva Raykar (8): submodule--helper: split up ensure_core_worktree() submodule--helper: get remote names from any repository submodule--helper: rename helpers for update-clone submodule--helper: refactor get_submodule_displaypath() submodule: move core cmd_update() logic to C submodule--helper: remove update-clone subcommand submodule--helper: remove unused helpers submodule--helper: rename helper functions builtin/submodule--helper.c | 767 +++++++++++++++++++++--------------- git-submodule.sh | 145 +------ 2 files changed, 458 insertions(+), 454 deletions(-) Range-diff against v1: 1: 2cfdc0e10a < -: ---------- submodule--helper: get remote names from any repository -: ---------- > 1: f83a5b7f34 submodule--helper: split up ensure_core_worktree() 2: be83ba7fdb ! 2: 7f4e24ce25 submodule--helper: introduce get_default_remote_submodule() @@ Metadata Author: Atharva Raykar <raykar.ath@gmail.com> ## Commit message ## - submodule--helper: introduce get_default_remote_submodule() + submodule--helper: get remote names from any repository - Before 8ef1d2b549 (submodule--helper: get remote names from any - repository, 2021-07-20), it was not possible to directly retrieve a - submodule's remote name within the same process, because - `get_default_remote()` used only knew about the current repository. + `get_default_remote()` retrieves the name of a remote by resolving the + refs from of the current repository's ref store. + + Thus in order to use it for retrieving the remote name of a submodule, + we have to start a new subprocess which runs from the submodule + directory. + + Let's instead introduce a function called `repo_get_default_remote()` + which takes any repository object and retrieves the remote accordingly. + + `get_default_remote()` is then defined as a call to + `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. - Let's make a function called `get_default_remote_submodule()` which + So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. @@ Commit message Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> ## builtin/submodule--helper.c ## -@@ builtin/submodule--helper.c: static char *repo_get_default_remote(struct repository *repo, const char *refnam +@@ + typedef void (*each_submodule_fn)(const struct cache_entry *list_item, + void *cb_data); + +-static char *get_default_remote(void) ++static char *repo_get_default_remote(struct repository *repo, const char *refname) + { + char *dest = NULL, *ret; + struct strbuf sb = STRBUF_INIT; +- const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + + if (!refname) + die(_("No such ref: %s"), "HEAD"); +@@ builtin/submodule--helper.c: static char *get_default_remote(void) + die(_("Expecting a full ref name, got %s"), refname); + + strbuf_addf(&sb, "branch.%s.remote", refname); +- if (git_config_get_string(sb.buf, &dest)) ++ if (repo_config_get_string(repo, sb.buf, &dest)) + ret = xstrdup("origin"); + else + ret = dest; +@@ builtin/submodule--helper.c: static char *get_default_remote(void) return ret; } @@ builtin/submodule--helper.c: static char *repo_get_default_remote(struct reposit + return repo_get_default_remote(&subrepo, refname); +} + - static char *get_default_remote(void) ++static char *get_default_remote(void) ++{ ++ const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); ++ return repo_get_default_remote(the_repository, refname); ++} ++ + static int print_default_remote(int argc, const char **argv, const char *prefix) { - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + char *remote; @@ builtin/submodule--helper.c: static void sync_submodule(const char *path, const char *prefix, char *remote_key = NULL; char *sub_origin_url, *super_config_url, *displaypath; 3: 8981b2c4c5 = 3: 390596ee7c submodule--helper: rename helpers for update-clone 4: 420d792f99 = 4: 2a2ddcac91 submodule--helper: refactor get_submodule_displaypath() 5: 6c4696b70a ! 5: 832020a290 submodule: move core cmd_update() logic to C @@ Commit message `init_submodule()`, which will now also take an explicit 'superprefix' argument. + While we are at it, we also remove the fetch_in_submodule() shell + function since it is no longer used anywhere. + [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> @@ builtin/submodule--helper.c: static char *compute_submodule_clone_url(const char unsigned int flags; }; -#define INIT_CB_INIT { NULL, 0 } -+#define INIT_CB_INIT { NULL, NULL, 0 } ++#define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ -+ if (suc.quickstop) ++ if (suc.quickstop) { ++ string_list_clear(&update_data->references, 0); + return 1; ++ } + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + res = 1; + } + ++ string_list_clear(&update_data->references, 0); + return res; +} + @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"run-update-procedure", run_update_procedure, 0}, ## git-submodule.sh ## +@@ git-submodule.sh: cmd_deinit() + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" + } + +-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] +-# Because arguments are positional, use an empty string to omit <depth> +-# but include <sha1>. +-fetch_in_submodule () ( +- sanitize_submodule_env && +- cd "$1" && +- if test $# -eq 3 +- then +- echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} +- else +- git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} +- fi +-) +- + # + # Update each submodule path to correct revision, using clone and checkout as needed + # @@ git-submodule.sh: cmd_update() shift done 6: 524ae77c3f < -: ---------- submodule: remove fetch_in_submodule shell function 7: ea56f7319a = 6: fb3fa8174a submodule--helper: remove update-clone subcommand 8: 10a62172a2 < -: ---------- submodule--helper: remove update-module-mode subcommand 9: dbbe5d3f53 < -: ---------- submodule--helper: remove shell interface to ensure_core_worktree() 10: a015af3a16 < -: ---------- submodule--helper: remove print-default-remote subcommand 11: f5a7ba1405 < -: ---------- submodule--helper: remove relative-path subcommand 12: 9f54eb5972 ! 7: 364f72f870 submodule--helper: remove run-update-procedure subcommand @@ Metadata Author: Atharva Raykar <raykar.ath@gmail.com> ## Commit message ## - submodule--helper: remove run-update-procedure subcommand + submodule--helper: remove unused helpers - The subcommand 'submodule--helper run-update-procedure' is no longer - needed after the conversion of the bulk of 'update' to C. - - While we are at it, let's rename 'do_run_update_procedure()' to - 'run_update_procedure()' to reflect the fact that it is no longer a - utility function meant to be wrapped in another function. + These helpers were useful back when 'submodule update' had most of its + logic in shell. Now that they will never be invoked, let us remove them. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> ## builtin/submodule--helper.c ## -@@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce, struct strin - return 0; +@@ builtin/submodule--helper.c: static char *get_default_remote(void) + return repo_get_default_remote(the_repository, refname); } --static int do_run_update_procedure(struct update_data *ud, struct string_list *err) -+static int run_update_procedure(struct update_data *ud, struct string_list *err) +-static int print_default_remote(int argc, const char **argv, const char *prefix) +-{ +- char *remote; +- +- if (argc != 1) +- die(_("submodule--helper print-default-remote takes no arguments")); +- +- remote = get_default_remote(); +- if (remote) +- printf("%s\n", remote); +- +- free(remote); +- return 0; +-} +- + static int starts_with_dot_slash(const char *str) { - int subforce = is_null_oid(&ud->suboid) || ud->force; + return str[0] == '.' && is_dir_sep(str[1]); +@@ builtin/submodule--helper.c: static void determine_submodule_update_strategy(struct repository *r, + free(key); + } +-static int module_update_module_mode(int argc, const char **argv, const char *prefix) +-{ +- const char *path, *update = NULL; +- int just_cloned; +- struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; +- +- if (argc < 3 || argc > 4) +- die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); +- +- just_cloned = git_config_int("just_cloned", argv[1]); +- path = argv[2]; +- +- if (argc == 4) +- update = argv[3]; +- +- determine_submodule_update_strategy(the_repository, +- just_cloned, path, update, +- &update_strategy); +- fputs(submodule_strategy_to_string(&update_strategy), stdout); +- +- return 0; +-} +- + struct update_clone_data { + const struct submodule *sub; + struct object_id oid; @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - - return 3; -} +- +-static int resolve_relative_path(int argc, const char **argv, const char *prefix) +-{ +- struct strbuf sb = STRBUF_INIT; +- if (argc != 3) +- die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); +- +- printf("%s", relative_path(argv[1], argv[2], &sb)); +- strbuf_release(&sb); +- return 0; +-} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; -@@ builtin/submodule--helper.c: static int update_submodule(struct update_data *update_data) +@@ builtin/submodule--helper.c: static void do_ensure_core_worktree(const char *path) } + } - if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) -- if (do_run_update_procedure(update_data, &err)) -+ if (run_update_procedure(update_data, &err)) - return 1; - - if (update_data->recursive) { +-static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +-{ +- const char *path; +- +- if (argc != 2) +- BUG("submodule--helper ensure-core-worktree <path>"); +- +- path = argv[1]; +- do_ensure_core_worktree(path); +- +- return 0; +-} +- + static int absorb_git_dirs(int argc, const char **argv, const char *prefix) + { + int i; @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, {"update", module_update, 0}, +- {"update-module-mode", module_update_module_mode, 0}, - {"run-update-procedure", run_update_procedure, 0}, +- {"ensure-core-worktree", ensure_core_worktree, 0}, +- {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, + {"init", module_init, SUPPORT_SUPER_PREFIX}, + {"status", module_status, SUPPORT_SUPER_PREFIX}, +- {"print-default-remote", print_default_remote, 0}, + {"sync", module_sync, SUPPORT_SUPER_PREFIX}, + {"deinit", module_deinit, 0}, + {"summary", module_summary, SUPPORT_SUPER_PREFIX}, -: ---------- > 8: ca48dd452c submodule--helper: rename helper functions -- 2.32.0 ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar ` (7 subsequent siblings) 8 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Let's split up `ensure_core_worktree()` so that we can call it from C code without needing to deal with command line arguments. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 80619361fc..97512ccf0b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2794,18 +2794,12 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void do_ensure_core_worktree(const char *path) { const struct submodule *sub; - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - sub = submodule_from_path(the_repository, null_oid(), path); if (!sub) BUG("We could get the submodule handle before?"); @@ -2829,6 +2823,17 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } +} + +static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +{ + const char *path; + + if (argc != 2) + BUG("submodule--helper ensure-core-worktree <path>"); + + path = argv[1]; + do_ensure_core_worktree(path); return 0; } -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v2 2/8] submodule--helper: get remote names from any repository 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-20 16:52 ` Junio C Hamano 2021-09-20 21:28 ` Junio C Hamano 2021-09-16 10:32 ` [PATCH v2 3/8] submodule--helper: rename helpers for update-clone Atharva Raykar ` (6 subsequent siblings) 8 siblings, 2 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 97512ccf0b..f6c4fc349b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,10 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo, const char *refname) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +45,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +54,25 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + const char *refname; + const struct submodule *sub; + struct repository subrepo; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), + "HEAD", 0, NULL, NULL); + sub = submodule_from_path(the_repository, null_oid(), module_path); + repo_submodule_init(&subrepo, the_repository, sub); + return repo_get_default_remote(&subrepo, refname); +} + +static char *get_default_remote(void) +{ + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + return repo_get_default_remote(the_repository, refname); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1369,7 +1387,6 @@ static void sync_submodule(const char *path, const char *prefix, char *remote_key = NULL; char *sub_origin_url, *super_config_url, *displaypath; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1418,14 +1435,9 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + strbuf_addstr(&sb, get_default_remote_submodule(path)); + if (!sb.buf) die(_("failed to get the default remote for submodule '%s'"), path); -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v2 2/8] submodule--helper: get remote names from any repository 2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar @ 2021-09-20 16:52 ` Junio C Hamano 2021-10-03 13:22 ` Atharva Raykar 2021-09-20 21:28 ` Junio C Hamano 1 sibling, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 16:52 UTC (permalink / raw) To: Atharva Raykar Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > `get_default_remote()` retrieves the name of a remote by resolving the > refs from of the current repository's ref store. > > Thus in order to use it for retrieving the remote name of a submodule, > we have to start a new subprocess which runs from the submodule > directory. > > Let's instead introduce a function called `repo_get_default_remote()` > which takes any repository object and retrieves the remote accordingly. > > `get_default_remote()` is then defined as a call to > `repo_get_default_remote()` with 'the_repository' passed to it. > > Now that we have `repo_get_default_remote()`, we no longer have to start > a subprocess that called `submodule--helper get-default-remote` from > within the submodule directory. > > So let's make a function called `get_default_remote_submodule()` which > takes a submodule path, and returns the default remote for that > submodule, all within the same process. > > We can now use this function to save an unnecessary subprocess spawn in > `sync_submodule()`, and also in the next patch, which will require this > functionality. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- > builtin/submodule--helper.c | 34 +++++++++++++++++++++++----------- > 1 file changed, 23 insertions(+), 11 deletions(-) The above covers a lot of stuff, because this change does a lot of things ;-) The commit could be split into 3 logically distinct phases (two independent, the third depends on the other two): - extract the part that uses the run-command() API to run "submodule--helper print-default-remote" from sync_submodule() and create get_default_remote_submodule() function out of it. - move bulk of get_default_remote() into repo_get_default_remote() and reimplement the former as a thin wrapper of the latter. - using the repo_get_default_remote() created in the second step, update the get_default_remote_submodule() created in the first step to work in-process without a subprocess. but a bit larger granularity used here is probably OK. > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 97512ccf0b..f6c4fc349b 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -29,11 +29,10 @@ > typedef void (*each_submodule_fn)(const struct cache_entry *list_item, > void *cb_data); > > -static char *get_default_remote(void) > +static char *repo_get_default_remote(struct repository *repo, const char *refname) > { > char *dest = NULL, *ret; > struct strbuf sb = STRBUF_INIT; > - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); > > if (!refname) > die(_("No such ref: %s"), "HEAD"); > @@ -46,7 +45,7 @@ static char *get_default_remote(void) > die(_("Expecting a full ref name, got %s"), refname); > > strbuf_addf(&sb, "branch.%s.remote", refname); > - if (git_config_get_string(sb.buf, &dest)) > + if (repo_config_get_string(repo, sb.buf, &dest)) > ret = xstrdup("origin"); > else > ret = dest; > @@ -55,6 +54,25 @@ static char *get_default_remote(void) > return ret; > } > > +static char *get_default_remote_submodule(const char *module_path) > +{ > + const char *refname; > + const struct submodule *sub; > + struct repository subrepo; > + > + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), > + "HEAD", 0, NULL, NULL); > + sub = submodule_from_path(the_repository, null_oid(), module_path); > + repo_submodule_init(&subrepo, the_repository, sub); > + return repo_get_default_remote(&subrepo, refname); > +} > + > +static char *get_default_remote(void) > +{ > + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); > + return repo_get_default_remote(the_repository, refname); > +} > + > static int print_default_remote(int argc, const char **argv, const char *prefix) > { > char *remote; > @@ -1369,7 +1387,6 @@ static void sync_submodule(const char *path, const char *prefix, > char *remote_key = NULL; > char *sub_origin_url, *super_config_url, *displaypath; > struct strbuf sb = STRBUF_INIT; > - struct child_process cp = CHILD_PROCESS_INIT; > char *sub_config_path = NULL; > > if (!is_submodule_active(the_repository, path)) > @@ -1418,14 +1435,9 @@ static void sync_submodule(const char *path, const char *prefix, > if (!is_submodule_populated_gently(path, NULL)) > goto cleanup; > > - prepare_submodule_repo_env(&cp.env_array); > - cp.git_cmd = 1; > - cp.dir = path; > - strvec_pushl(&cp.args, "submodule--helper", > - "print-default-remote", NULL); > - > strbuf_reset(&sb); > - if (capture_command(&cp, &sb, 0)) > + strbuf_addstr(&sb, get_default_remote_submodule(path)); > + if (!sb.buf) > die(_("failed to get the default remote for submodule '%s'"), > path); There is this line after the post context presented here: strbuf_strip_suffix(&sb, "\n"); remote_key = xstrfmt("remote.%s.url", sb.buf); The LF was expected to come from the capture_command(), but it no longer is needed after get_default_remote_submodule() switches to use the in-process method. In fact, the use of sb for the purpose of forming remote_key is not needed. tmp = get_default_remote_submodule(path); if (!tmp) die(_("failed to get...")); remote_key = xstrfmt("remote.%s.url", tmp); free(tmp); Yes, I think the new code leaks, and makes it impossible not to leak, the returned value from get_default_remote_submodule() by passing the call as an argument to strbuf_addstr(). Both of the two bugs pointed out here would have been easier to spot if the commits were smaller, I would think, but as I said, a bit larger granularity used here was still manageable. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 2/8] submodule--helper: get remote names from any repository 2021-09-20 16:52 ` Junio C Hamano @ 2021-10-03 13:22 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-03 13:22 UTC (permalink / raw) To: Junio C Hamano Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Junio C Hamano <gitster@pobox.com> writes: > Atharva Raykar <raykar.ath@gmail.com> writes: > >> `get_default_remote()` retrieves the name of a remote by resolving the >> refs from of the current repository's ref store. >> >> Thus in order to use it for retrieving the remote name of a submodule, >> we have to start a new subprocess which runs from the submodule >> directory. >> >> Let's instead introduce a function called `repo_get_default_remote()` >> which takes any repository object and retrieves the remote accordingly. >> >> `get_default_remote()` is then defined as a call to >> `repo_get_default_remote()` with 'the_repository' passed to it. >> >> Now that we have `repo_get_default_remote()`, we no longer have to start >> a subprocess that called `submodule--helper get-default-remote` from >> within the submodule directory. >> >> So let's make a function called `get_default_remote_submodule()` which >> takes a submodule path, and returns the default remote for that >> submodule, all within the same process. >> >> We can now use this function to save an unnecessary subprocess spawn in >> `sync_submodule()`, and also in the next patch, which will require this >> functionality. >> >> Mentored-by: Christian Couder <christian.couder@gmail.com> >> Mentored-by: Shourya Shukla <periperidip@gmail.com> >> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> >> --- >> builtin/submodule--helper.c | 34 +++++++++++++++++++++++----------- >> 1 file changed, 23 insertions(+), 11 deletions(-) > > The above covers a lot of stuff, because this change does a lot of > things ;-) > > The commit could be split into 3 logically distinct phases (two > independent, the third depends on the other two): > > - extract the part that uses the run-command() API to run > "submodule--helper print-default-remote" from sync_submodule() > and create get_default_remote_submodule() function out of it. > > - move bulk of get_default_remote() into repo_get_default_remote() > and reimplement the former as a thin wrapper of the latter. > > - using the repo_get_default_remote() created in the second step, > update the get_default_remote_submodule() created in the first > step to work in-process without a subprocess. > > but a bit larger granularity used here is probably OK. > [...] >> strbuf_reset(&sb); >> - if (capture_command(&cp, &sb, 0)) >> + strbuf_addstr(&sb, get_default_remote_submodule(path)); >> + if (!sb.buf) >> die(_("failed to get the default remote for submodule '%s'"), >> path); > > There is this line after the post context presented here: > > strbuf_strip_suffix(&sb, "\n"); > remote_key = xstrfmt("remote.%s.url", sb.buf); > > The LF was expected to come from the capture_command(), but it no > longer is needed after get_default_remote_submodule() switches to > use the in-process method. In fact, the use of sb for the purpose > of forming remote_key is not needed. > > tmp = get_default_remote_submodule(path); > if (!tmp) > die(_("failed to get...")); > remote_key = xstrfmt("remote.%s.url", tmp); > free(tmp); > > Yes, I think the new code leaks, and makes it impossible not to > leak, the returned value from get_default_remote_submodule() by > passing the call as an argument to strbuf_addstr(). Thanks, this was a good catch. > Both of the two bugs pointed out here would have been easier to spot > if the commits were smaller, I would think, but as I said, a bit > larger granularity used here was still manageable. My initial series had this patch split up similar to what you suggested, but I ultimately chose to favour the larger granularity to make the whole series a bit shorter. This patch definitely towed the line a bit. > Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 2/8] submodule--helper: get remote names from any repository 2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar 2021-09-20 16:52 ` Junio C Hamano @ 2021-09-20 21:28 ` Junio C Hamano 2021-09-21 16:33 ` Jonathan Tan 1 sibling, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 21:28 UTC (permalink / raw) To: Atharva Raykar, Jonathan Tan Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > +static char *get_default_remote_submodule(const char *module_path) > +{ > + const char *refname; > + const struct submodule *sub; > + struct repository subrepo; > + > + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), > + "HEAD", 0, NULL, NULL); > + sub = submodule_from_path(the_repository, null_oid(), module_path); > + repo_submodule_init(&subrepo, the_repository, sub); > + return repo_get_default_remote(&subrepo, refname); > +} This call (and I think there is another call in this file) to repo_submodule_init() is affected by what Jonathan's 8eb8dcf9 (repository: support unabsorbed in repo_submodule_init, 2021-09-09) wants to do, namely to lose "struct submodule sub" as a parameter and instead take the path to the module and the treeish name as parameters to repo_submodule_init(). I _think_ I resolved the conflict correctly, but please double check the result when it is pushed out later today, both of you. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 2/8] submodule--helper: get remote names from any repository 2021-09-20 21:28 ` Junio C Hamano @ 2021-09-21 16:33 ` Jonathan Tan 0 siblings, 0 replies; 142+ messages in thread From: Jonathan Tan @ 2021-09-21 16:33 UTC (permalink / raw) To: gitster; +Cc: raykar.ath, jonathantanmy, git > Atharva Raykar <raykar.ath@gmail.com> writes: > > > +static char *get_default_remote_submodule(const char *module_path) > > +{ > > + const char *refname; > > + const struct submodule *sub; > > + struct repository subrepo; > > + > > + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), > > + "HEAD", 0, NULL, NULL); > > + sub = submodule_from_path(the_repository, null_oid(), module_path); > > + repo_submodule_init(&subrepo, the_repository, sub); > > + return repo_get_default_remote(&subrepo, refname); > > +} > > This call (and I think there is another call in this file) to > repo_submodule_init() is affected by what Jonathan's 8eb8dcf9 > (repository: support unabsorbed in repo_submodule_init, 2021-09-09) > wants to do, namely to lose "struct submodule sub" as a parameter > and instead take the path to the module and the treeish name as > parameters to repo_submodule_init(). > > I _think_ I resolved the conflict correctly, but please double check > the result when it is pushed out later today, both of you. > > Thanks. Thanks for calling this out. There are indeed 2 such calls in 33cfc43433 ("Merge branch 'ar/submodule-update' into seen", 2021-09-20) and both look correct. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v2 3/8] submodule--helper: rename helpers for update-clone 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 4/8] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar ` (5 subsequent siblings) 8 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip The `update-clone` subcommand helpers that perform the parallel clone and printing to stdout for shell script consumption, are renamed. This lets us use the names `update_submodules()` and `update_submodule()` for the helpers in the next patch, when we create an `update` subcommand that does a full conversion. We will get rid of these helpers in a cleanup patch at the end of this series, when the `update-clone` command is no longer useful to us. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f6c4fc349b..b0336b0377 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2499,7 +2499,7 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) +static void update_clone_submodule(struct update_clone_data *ucd) { fprintf(stdout, "dummy %s %d\t%s\n", oid_to_hex(&ucd->oid), @@ -2507,7 +2507,7 @@ static void update_submodule(struct update_clone_data *ucd) ucd->sub->path); } -static int update_submodules(struct submodule_update_clone *suc) +static int update_clone_submodules(struct submodule_update_clone *suc) { int i; @@ -2528,7 +2528,7 @@ static int update_submodules(struct submodule_update_clone *suc) return 1; for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); + update_clone_submodule(&suc->update_clone[i]); return 0; } @@ -2593,7 +2593,7 @@ static int update_clone(int argc, const char **argv, const char *prefix) if (pathspec.nr) suc.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_clone_submodules(&suc); } static int run_update_procedure(int argc, const char **argv, const char *prefix) -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v2 4/8] submodule--helper: refactor get_submodule_displaypath() 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (2 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 3/8] submodule--helper: rename helpers for update-clone Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar ` (4 subsequent siblings) 8 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b0336b0377..10de01a1f7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -269,11 +269,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -289,6 +286,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v2 5/8] submodule: move core cmd_update() logic to C 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (3 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 4/8] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-20 17:13 ` Junio C Hamano ` (2 more replies) 2021-09-16 10:32 ` [PATCH v2 6/8] submodule--helper: remove update-clone subcommand Atharva Raykar ` (3 subsequent siblings) 8 siblings, 3 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. We also introduce `update_submodules()` and `update_submodule()` which are quite similar to `update_clone_submodules()` and `update_clone_submodule()`, and will supersede them. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the `init_submodule_cb()` callback over each submodule directly. This introduces another problem, because there is no mechanism to pass the superproject path prefix (ie, `--super-prefix`) without starting a new git process. This field is required for obtaining the display path for that is used by the command's output messages. So let's add a field into the `init_cb` struct that lets us pass this information to `init_submodule()`, which will now also take an explicit 'superprefix' argument. While we are at it, we also remove the fetch_in_submodule() shell function since it is no longer used anywhere. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 505 ++++++++++++++++++++++++++++++------ git-submodule.sh | 145 +---------- 2 files changed, 433 insertions(+), 217 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 10de01a1f7..1eea626864 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -634,18 +634,22 @@ static char *compute_submodule_clone_url(const char *rel_url) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; -#define INIT_CB_INIT { NULL, 0 } +#define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -719,7 +723,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) @@ -2039,7 +2043,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -2062,19 +2065,63 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; struct object_id oid; struct object_id suboid; - struct submodule_update_strategy update_strategy; + int max_jobs; int depth; + int recommend_shallow; + int single_branch; + unsigned int init: 1; unsigned int force: 1; unsigned int quiet: 1; unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int remote: 1; + unsigned int recursive: 1; + unsigned int progress: 1; + unsigned int dissociate: 1; + unsigned int require_init: 1; + unsigned warn_if_uninitialized : 1; + unsigned int just_cloned : 1; + struct submodule_update_strategy update_strategy; + struct string_list references; + struct module_list list; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -2369,111 +2416,113 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str return run_command(&cp); } -static int run_update_command(struct update_data *ud, int subforce) +static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); + struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; - int git_cmd; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; + + cp.dir = xstrdup(ud->sm_path); + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.git_cmd = 0; + cp.use_shell = 1; + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + prepare_submodule_repo_env(&cp.env_array); + if (capture_command(&cp, &out, 0)) { + if (must_die_on_failure) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + die(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_REBASE: + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_MERGE: + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_COMMAND: + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + + /* the command failed, but update must continue */ + string_list_append(err, out.buf); return 1; } - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_REBASE: - printf(_("Submodule path '%s': rebased into '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_MERGE: - printf(_("Submodule path '%s': merged in '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_COMMAND: - printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + if (!ud->quiet) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + printf(_("Submodule path '%s': checked out '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_REBASE: + printf(_("Submodule path '%s': rebased into '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_MERGE: + printf(_("Submodule path '%s': merged in '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_COMMAND: + printf(_("Submodule path '%s': '%s %s'\n"), + ud->displaypath, strategy.command, oid); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int do_run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2500,7 +2549,7 @@ static int do_run_update_procedure(struct update_data *ud) ud->displaypath, oid_to_hex(&ud->oid)); } - return run_update_command(ud, subforce); + return run_update_command(ud, subforce, err); } static void update_clone_submodule(struct update_clone_data *ucd) @@ -2605,6 +2654,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data update_data = UPDATE_DATA_INIT; + struct string_list err = STRING_LIST_INIT_DUP; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2662,7 +2712,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) free(prefixed_path); if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + return do_run_update_procedure(&update_data, &err); return 3; } @@ -3038,6 +3088,291 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; + struct string_list err = STRING_LIST_INIT_DUP; + + do_ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if(fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + if (do_run_update_procedure(update_data, &err)) + return 1; + + if (update_data->recursive) { + int res; + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + if ((res = run_command(&cp)) == 128) + die("%s", die_msg); + if (res) + string_list_append(&err, die_msg); + + free(die_msg); + } + + if (err.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &err) + fputs(item->string, stderr); + return 1; + } + + return 0; +} + +static int update_submodules(struct update_data *update_data) +{ + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, &suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) { + string_list_clear(&update_data->references, 0); + return 1; + } + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; + + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + + string_list_clear(&update_data->references, 0); + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ + int init = 0, force = 0, quiet = 0, nofetch = 0; + int remote = 0, recursive = 0, dissociate = 0; + int progress = 0, require_init = 0; + const char *update = NULL; + struct pathspec pathspec; + struct update_data update_data = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { + OPT__FORCE(&force, N_("force checkout updates"), 0), + OPT_BOOL(0, "init", &init, + N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "remote", &remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &update_data.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &dissociate, + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &update_data.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &update_data.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &update_data.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &update_data.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + + update_clone_config_from_gitmodules(&update_data.max_jobs); + git_config(git_update_clone_config, &update_data.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + update_data.prefix = prefix; + + update_data.force = !!force; + update_data.quiet = !!quiet; + update_data.nofetch = !!nofetch; + update_data.init = !!init; + update_data.require_init = !!require_init; + update_data.remote = !!remote; + update_data.recursive = !!recursive; + update_data.progress = !!progress; + update_data.dissociate = !!dissociate; + oidcpy(&update_data.oid, null_oid()); + oidcpy(&update_data.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, + &update_data.update_strategy) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &update_data.list) < 0) + return 1; + + if (pathspec.nr) + update_data.warn_if_uninitialized = 1; + + if (update_data.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, update_data.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = update_data.prefix; + info.superprefix = update_data.recursive_prefix; + if (update_data.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&update_data); +} + struct add_data { const char *prefix; const char *branch; @@ -3213,6 +3548,7 @@ static int add_clone(int argc, const char **argv, const char *prefix) return 0; } + #define SUPPORT_SUPER_PREFIX (1<<0) struct cmd_struct { @@ -3226,6 +3562,7 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, + {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, diff --git a/git-submodule.sh b/git-submodule.sh index f703cddce8..5197de4551 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -369,20 +369,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -484,133 +470,26 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + ${GIT_QUIET:+--quiet} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 1 - then - subsha1= - else - just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" - fi - - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v2 5/8] submodule: move core cmd_update() logic to C 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar @ 2021-09-20 17:13 ` Junio C Hamano 2021-10-03 10:38 ` Atharva Raykar 2021-09-20 19:58 ` Junio C Hamano 2021-09-20 21:28 ` Junio C Hamano 2 siblings, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 17:13 UTC (permalink / raw) To: Atharva Raykar Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > This patch completes the conversion past the flag parsing of > `submodule update` by introducing a helper subcommand called > `submodule--helper update`. The behaviour of `submodule update` should > remain the same after this patch. > > We add more fields to the `struct update_data` that are required by > `struct submodule_update_clone` to be able to perform a clone, when that > is needed to be done. > > Recursing on a submodule is done by calling a subprocess that launches > `submodule--helper update`, with a modified `--recursive-prefix` and > `--prefix` parameter. > > We also introduce `update_submodules()` and `update_submodule()` which > are quite similar to `update_clone_submodules()` and > `update_clone_submodule()`, and will supersede them. > > When the `--init` flag is passed to the subcommand, we do not spawn a > new subprocess and call `submodule--helper init` on the submodule paths, > because the Git machinery is not able to pick up the configuration > changes introduced by that init call[1]. So we instead run the > `init_submodule_cb()` callback over each submodule directly. > > This introduces another problem, because there is no mechanism to pass > the superproject path prefix (ie, `--super-prefix`) without starting a > new git process. This field is required for obtaining the display path > for that is used by the command's output messages. So let's add a field > into the `init_cb` struct that lets us pass this information to > `init_submodule()`, which will now also take an explicit 'superprefix' > argument. > > While we are at it, we also remove the fetch_in_submodule() shell > function since it is no longer used anywhere. > > [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- > builtin/submodule--helper.c | 505 ++++++++++++++++++++++++++++++------ > git-submodule.sh | 145 +---------- > 2 files changed, 433 insertions(+), 217 deletions(-) It seems that this step does too many things in one step and makes it harder than necessary for readers to understand what is going on. For example, as far as I can see, the change to optionally allow passing superprefix to init_submodule() can be made without anything else in this step (i.e. "we allow superprefix from the parameter to override what get_super_prefix() would give us, but at this step, everybody passes NULL and the behaviour is unchanged" would be one such step), later to be followed by a change that involves passing a non-NULL value there, and it would become a lot easier to see who passes a non-NULL super prefix, what value is passed and for what purpose, with such an organization. A 650+ lines single patch like this buries the details and forces the readers to disect them out. The change that teaches run_update_command() to instead use capture_command() and gives the error message to its callers may be another example of what may be better done as an independent step before tying the whole thing together. It is larger than what I comfortably can spend my time on while tending patches from other topics, so I'll skip reviewing this step for now. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 5/8] submodule: move core cmd_update() logic to C 2021-09-20 17:13 ` Junio C Hamano @ 2021-10-03 10:38 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-03 10:38 UTC (permalink / raw) To: Junio C Hamano Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Junio C Hamano <gitster@pobox.com> writes: > > It seems that this step does too many things in one step and makes > it harder than necessary for readers to understand what is going on. > > For example, as far as I can see, the change to optionally allow > passing superprefix to init_submodule() can be made without anything > else in this step (i.e. "we allow superprefix from the parameter to > override what get_super_prefix() would give us, but at this step, > everybody passes NULL and the behaviour is unchanged" would be one > such step), later to be followed by a change that involves passing a > non-NULL value there, and it would become a lot easier to see who > passes a non-NULL super prefix, what value is passed and for what > purpose, with such an organization. > > A 650+ lines single patch like this buries the details and forces > the readers to disect them out. The change that teaches > run_update_command() to instead use capture_command() and gives the > error message to its callers may be another example of what may be > better done as an independent step before tying the whole thing > together. > > It is larger than what I comfortably can spend my time on while > tending patches from other topics, so I'll skip reviewing this step > for now. > > Thanks. Understood. Apologies for the lack of updates on this topic, I will work on organising this patch (and this series) better. I've taken a note of the conflicts with other topics as well. I don't mind the other topics being prioritized over this one. At the moment I am not too confident about being able to quickly iterate over this series. I'll try my best anyway. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 5/8] submodule: move core cmd_update() logic to C 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar 2021-09-20 17:13 ` Junio C Hamano @ 2021-09-20 19:58 ` Junio C Hamano 2021-09-20 21:28 ` Junio C Hamano 2 siblings, 0 replies; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 19:58 UTC (permalink / raw) To: Atharva Raykar, Emily Shaffer Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > This patch completes the conversion past the flag parsing of > `submodule update` by introducing a helper subcommand called > `submodule--helper update`. The behaviour of `submodule update` should > remain the same after this patch. > ... > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- This seems to overlap with Emily's 242655f2 (submodule: record superproject gitdir during 'update', 2021-08-19) that came in <20210819200953.2105230-5-emilyshaffer@google.com>. Should I expect there probably needs a few more iterations for this topic? Depending, the "a submodule knows which superproject it is part of" topic may have to be done in C on top of this topic. I'll eject the 'es/superproject-aware-submodules' topic for now, just to get today's integration going. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v2 5/8] submodule: move core cmd_update() logic to C 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar 2021-09-20 17:13 ` Junio C Hamano 2021-09-20 19:58 ` Junio C Hamano @ 2021-09-20 21:28 ` Junio C Hamano 2 siblings, 0 replies; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 21:28 UTC (permalink / raw) To: Atharva Raykar, Ævar Arnfjörð Bjarmason Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > +static int update_submodules(struct update_data *update_data) > +{ > + int i, res = 0; > + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; > + > + update_clone_from_update_data(&suc, update_data); > + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, > + update_clone_start_failure, > + update_clone_task_finished, &suc, "submodule", > + "parallel/update"); > + ... As ab/config-based-hooks-base topic from Ævar changes the way this helper function gets called at 73367f2f (run-command: add stdin callback for parallelization, 2021-09-02) and then again in 2aba2f5f (run-command: allow capturing of collated output, 2021-09-02), this part needs to be adjusted when the topics collide in 'seen'. I _think_ I've resolved conflict correctly, but please double-check the result when today's integration result is pushed out later, both of you. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v2 6/8] submodule--helper: remove update-clone subcommand 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (4 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 7/8] submodule--helper: remove unused helpers Atharva Raykar ` (2 subsequent siblings) 8 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip We no longer need this subcommand as the shell version calls the 'update' subcommand instead, which does all the cloning within C itself. We also no longer need the 'update_clone_submodules()' and 'update_clone_submodule()' functions, so we remove those as well. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 98 ------------------------------------- 1 file changed, 98 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 1eea626864..c1ce3981ad 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2552,103 +2552,6 @@ static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } -static void update_clone_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -static int update_clone_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_clone_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - suc.prefix = prefix; - - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) - return 1; - - if (pathspec.nr) - suc.warn_if_uninitialized = 1; - - return update_clone_submodules(&suc); -} - static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; @@ -3564,7 +3467,6 @@ static struct cmd_struct commands[] = { {"add-clone", add_clone, 0}, {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v2 7/8] submodule--helper: remove unused helpers 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (5 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 6/8] submodule--helper: remove update-clone subcommand Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-20 17:19 ` Junio C Hamano 2021-09-16 10:32 ` [PATCH v2 8/8] submodule--helper: rename helper functions Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar 8 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip These helpers were useful back when 'submodule update' had most of its logic in shell. Now that they will never be invoked, let us remove them. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 135 ------------------------------------ 1 file changed, 135 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c1ce3981ad..0910af9c71 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -73,21 +73,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository, refname); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -1993,29 +1978,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -2552,85 +2514,6 @@ static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; - struct string_list err = STRING_LIST_INIT_DUP; - - struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; - - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); - else - prefixed_path = xstrdup(update_data.sm_path); - - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); - - free(prefixed_path); - - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data, &err); - - return 3; -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -2794,19 +2677,6 @@ static void do_ensure_core_worktree(const char *path) } } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) -{ - const char *path; - - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - do_ensure_core_worktree(path); - - return 0; -} - static int absorb_git_dirs(int argc, const char **argv, const char *prefix) { int i; @@ -3466,16 +3336,11 @@ static struct cmd_struct commands[] = { {"clone", module_clone, 0}, {"add-clone", add_clone, 0}, {"update", module_update, 0}, - {"update-module-mode", module_update_module_mode, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v2 7/8] submodule--helper: remove unused helpers 2021-09-16 10:32 ` [PATCH v2 7/8] submodule--helper: remove unused helpers Atharva Raykar @ 2021-09-20 17:19 ` Junio C Hamano 0 siblings, 0 replies; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 17:19 UTC (permalink / raw) To: Atharva Raykar Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > These helpers were useful back when 'submodule update' had most of its > logic in shell. Now that they will never be invoked, let us remove them. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- > builtin/submodule--helper.c | 135 ------------------------------------ > 1 file changed, 135 deletions(-) Makes sense. I briefly hoped that print-default-remote could go after 2/8 but there is another user that is in the cmd_update() that is not removed until 5/8 and removing them in a separate step after we are all done like this patch does makes sense. I am not sure where and how the line to separate the two "remove" patches is drawn, though. Is there a reason why they need to be two patches? ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v2 8/8] submodule--helper: rename helper functions 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (6 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 7/8] submodule--helper: remove unused helpers Atharva Raykar @ 2021-09-16 10:32 ` Atharva Raykar 2021-09-20 17:19 ` Junio C Hamano 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar 8 siblings, 1 reply; 142+ messages in thread From: Atharva Raykar @ 2021-09-16 10:32 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip These two functions were prefixed with 'do' before the shell-to-C conversion because they were utility functions meant to be called by their non-prefixed counterpart. Since those callers don't exist anymore, and these functions can now be used directly, let's rename them to signal this fact. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0910af9c71..e5e33be6ea 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2484,7 +2484,7 @@ static int run_update_command(struct update_data *ud, int subforce, struct strin return 0; } -static int do_run_update_procedure(struct update_data *ud, struct string_list *err) +static int run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2646,7 +2646,7 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static void do_ensure_core_worktree(const char *path) +static void ensure_core_worktree(const char *path) { const struct submodule *sub; const char *cw; @@ -2910,7 +2910,7 @@ static int update_submodule(struct update_data *update_data) char *prefixed_path; struct string_list err = STRING_LIST_INIT_DUP; - do_ensure_core_worktree(update_data->sm_path); + ensure_core_worktree(update_data->sm_path); if (update_data->recursive_prefix) prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, @@ -2950,7 +2950,7 @@ static int update_submodule(struct update_data *update_data) } if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) - if (do_run_update_procedure(update_data, &err)) + if (run_update_procedure(update_data, &err)) return 1; if (update_data->recursive) { -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v2 8/8] submodule--helper: rename helper functions 2021-09-16 10:32 ` [PATCH v2 8/8] submodule--helper: rename helper functions Atharva Raykar @ 2021-09-20 17:19 ` Junio C Hamano 0 siblings, 0 replies; 142+ messages in thread From: Junio C Hamano @ 2021-09-20 17:19 UTC (permalink / raw) To: Atharva Raykar Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > These two functions were prefixed with 'do' before the shell-to-C > conversion because they were utility functions meant to be called by > their non-prefixed counterpart. > > Since those callers don't exist anymore, and these functions can now be > used directly, let's rename them to signal this fact. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > --- > builtin/submodule--helper.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) Nice. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar ` (7 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 8/8] submodule--helper: rename helper functions Atharva Raykar @ 2021-10-13 5:17 ` Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() Atharva Raykar ` (10 more replies) 8 siblings, 11 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:17 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Since v2: - Rebased this series on top of a more up-to-date master branch. - Reorganized this series to (hopefully) make it easier to review, as per Junio's suggestions. I split up the patch that converts the rest of the update shell script to C into multiple steps. I also squashed the patches that removed unused helpers, as there was not clear criteria for it being two patches. - Plugged a memory leak while refactoring sync_submodule() to use my new helper. Note on conflicting series: -------------------------- This series currently conflicts with the work being done by Emily in 'es/superproject-aware-submodules' [1], mainly in the part where they cache the superproject gitdir in the shell script that gets removed during conversion in this series. I have attempted to make a version of this series that is based on that topic [2], and added the superproject gitdir caching code in C [3]. It passes the tests, but I am not too confident about its correctness. I hope that branch can be helpful in some way. [1] https://lore.kernel.org/git/20210819200953.2105230-1-emilyshaffer@google.com/ [2] https://github.com/tfidfwastaken/git/commits/submodule-update-on-es-superproject-aware (fetch-it-via: git fetch https://github.com/tfidfwastaken/git submodule-update-on-es-superproject-aware) [3] https://github.com/tfidfwastaken/git/blob/a74aaf2540c536970f2541d3042c825f82a69770/builtin/submodule--helper.c#L2922-L2930 Fetch-it-Via: git fetch https://github.com/tfidfwastaken/git submodule-update-list-3 Atharva Raykar (9): submodule--helper: split up ensure_core_worktree() submodule--helper: get remote names from any repository submodule--helper: rename helpers for update-clone submodule--helper: refactor get_submodule_displaypath() submodule--helper: allow setting superprefix for init_submodule() submodule--helper: run update using child process struct submodule: move core cmd_update() logic to C submodule--helper: remove unused helpers submodule--helper: rename helper functions builtin/submodule--helper.c | 771 +++++++++++++++++++++--------------- git-submodule.sh | 145 +------ 2 files changed, 458 insertions(+), 458 deletions(-) Range diff against the previous version: 1: f83a5b7f34 ! 1: d057ba04bd submodule--helper: split up ensure_core_worktree() @@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void do_ensure_core_worktree(const char *path) { - const struct submodule *sub; - const char *path; const char *cw; struct repository subrepo; @@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, - - path = argv[1]; - - sub = submodule_from_path(the_repository, null_oid(), path); - if (!sub) - BUG("We could get the submodule handle before?"); + if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) + die(_("could not get a repository handle for submodule '%s'"), path); + @@ builtin/submodule--helper.c: static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); 2: 7f4e24ce25 ! 2: 895cc10b97 submodule--helper: get remote names from any repository @@ builtin/submodule--helper.c: static char *get_default_remote(void) +static char *get_default_remote_submodule(const char *module_path) +{ + const char *refname; -+ const struct submodule *sub; + struct repository subrepo; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), + "HEAD", 0, NULL, NULL); -+ sub = submodule_from_path(the_repository, null_oid(), module_path); -+ repo_submodule_init(&subrepo, the_repository, sub); ++ repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo, refname); +} + @@ builtin/submodule--helper.c: static char *get_default_remote(void) { char *remote; @@ builtin/submodule--helper.c: static void sync_submodule(const char *path, const char *prefix, + { + const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; +- char *sub_origin_url, *super_config_url, *displaypath; ++ char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; @@ builtin/submodule--helper.c: static void sync_submodule(const char *path, const - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) -+ strbuf_addstr(&sb, get_default_remote_submodule(path)); -+ if (!sb.buf) ++ default_remote = get_default_remote_submodule(path); ++ if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); +- strbuf_strip_suffix(&sb, "\n"); +- remote_key = xstrfmt("remote.%s.url", sb.buf); ++ remote_key = xstrfmt("remote.%s.url", default_remote); ++ free(default_remote); + +- strbuf_reset(&sb); + submodule_to_gitdir(&sb, path); + strbuf_addstr(&sb, "/config"); + 3: 390596ee7c = 3: 1defe3e0ca submodule--helper: rename helpers for update-clone 4: 2a2ddcac91 = 4: 693b23772a submodule--helper: refactor get_submodule_displaypath() -: ---------- > 5: d1fd902a2a submodule--helper: allow setting superprefix for init_submodule() -: ---------- > 6: 19c6c4e81a submodule--helper: run update using child process struct 5: 832020a290 ! 7: 7cc32ad6f9 submodule: move core cmd_update() logic to C @@ Commit message new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the - `init_submodule_cb()` callback over each submodule directly. - - This introduces another problem, because there is no mechanism to pass - the superproject path prefix (ie, `--super-prefix`) without starting a - new git process. This field is required for obtaining the display path - for that is used by the command's output messages. So let's add a field - into the `init_cb` struct that lets us pass this information to - `init_submodule()`, which will now also take an explicit 'superprefix' - argument. + `init_submodule_cb()` callback over each submodule in the same process. While we are at it, we also remove the fetch_in_submodule() shell function since it is no longer used anywhere. @@ Commit message Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> ## builtin/submodule--helper.c ## -@@ builtin/submodule--helper.c: static char *compute_submodule_clone_url(const char *rel_url) - - struct init_cb { - const char *prefix; -+ const char *superprefix; - unsigned int flags; - }; --#define INIT_CB_INIT { NULL, 0 } -+#define INIT_CB_INIT { 0 } - - static void init_submodule(const char *path, const char *prefix, -- unsigned int flags) -+ const char *superprefix, unsigned int flags) - { - const struct submodule *sub; - struct strbuf sb = STRBUF_INIT; - char *upd = NULL, *url = NULL, *displaypath; - -- displaypath = get_submodule_displaypath(path, prefix); -+ /* try superprefix from the environment, if it is not passed explicitly */ -+ if (!superprefix) -+ superprefix = get_super_prefix(); -+ displaypath = do_get_submodule_displaypath(path, prefix, superprefix); - - sub = submodule_from_path(the_repository, null_oid(), path); - -@@ builtin/submodule--helper.c: static void init_submodule(const char *path, const char *prefix, - static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) - { - struct init_cb *info = cb_data; -- init_submodule(list_item->name, info->prefix, info->flags); -+ init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); - } - - static int module_init(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: struct submodule_update_clone { const char *prefix; int single_branch; @@ builtin/submodule--helper.c: static int fetch_in_submodule(const char *module_pa -static int run_update_command(struct update_data *ud, int subforce) +static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) { -- struct strvec args = STRVEC_INIT; -- struct strvec child_env = STRVEC_INIT; -+ struct child_process cp = CHILD_PROCESS_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); + struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; -- int git_cmd; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; -+ + +- switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; - -- switch (ud->update_strategy.type) { -+ cp.dir = xstrdup(ud->sm_path); ++ + switch (strategy.type) { case SM_UPDATE_CHECKOUT: -- git_cmd = 1; -- strvec_pushl(&args, "checkout", "-q", NULL); -+ cp.git_cmd = 1; -+ strvec_pushl(&cp.args, "checkout", "-q", NULL); - if (subforce) -- strvec_push(&args, "-f"); -+ strvec_push(&cp.args, "-f"); - break; - case SM_UPDATE_REBASE: -- git_cmd = 1; -- strvec_push(&args, "rebase"); -+ cp.git_cmd = 1; -+ strvec_push(&cp.args, "rebase"); - if (ud->quiet) -- strvec_push(&args, "--quiet"); -+ strvec_push(&cp.args, "--quiet"); - must_die_on_failure = 1; - break; - case SM_UPDATE_MERGE: -- git_cmd = 1; -- strvec_push(&args, "merge"); -+ cp.git_cmd = 1; -+ strvec_push(&cp.args, "merge"); - if (ud->quiet) -- strvec_push(&args, "--quiet"); -+ strvec_push(&cp.args, "--quiet"); - must_die_on_failure = 1; + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); +@@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: -- git_cmd = 0; -- strvec_push(&args, ud->update_strategy.command); -+ cp.git_cmd = 0; -+ cp.use_shell = 1; + cp.use_shell = 1; +- strvec_push(&cp.args, ud->update_strategy.command); + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; @@ builtin/submodule--helper.c: static int fetch_in_submodule(const char *module_pa - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } -- strvec_push(&args, oid); -+ strvec_push(&cp.args, oid); + strvec_push(&cp.args, oid); -- prepare_submodule_repo_env(&child_env); -- if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, -- ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); +- if (run_command(&cp)) { - switch (ud->update_strategy.type) { -+ prepare_submodule_repo_env(&cp.env_array); + if (capture_command(&cp, &out, 0)) { + if (must_die_on_failure) { + switch (strategy.type) { @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * struct add_data { const char *prefix; const char *branch; -@@ builtin/submodule--helper.c: static int add_clone(int argc, const char **argv, const char *prefix) +@@ builtin/submodule--helper.c: static int module_add(int argc, const char **argv, const char *prefix) return 0; } @@ builtin/submodule--helper.c: static int add_clone(int argc, const char **argv, c @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, - {"add-clone", add_clone, 0}, + {"add", module_add, SUPPORT_SUPER_PREFIX}, + {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, 6: fb3fa8174a < -: ---------- submodule--helper: remove update-clone subcommand 7: 364f72f870 ! 8: 486f9d0a0e submodule--helper: remove unused helpers @@ Commit message These helpers were useful back when 'submodule update' had most of its logic in shell. Now that they will never be invoked, let us remove them. + We also no longer need the 'update_clone_submodules()' and + 'update_clone_submodule()' functions, so we remove those as well. + Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da return run_update_command(ud, subforce, err); } +-static void update_clone_submodule(struct update_clone_data *ucd) +-{ +- fprintf(stdout, "dummy %s %d\t%s\n", +- oid_to_hex(&ucd->oid), +- ucd->just_cloned, +- ucd->sub->path); +-} +- +-static int update_clone_submodules(struct submodule_update_clone *suc) +-{ +- int i; +- +- run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, +- update_clone_start_failure, +- update_clone_task_finished, suc, "submodule", +- "parallel/update"); +- +- /* +- * We saved the output and put it out all at once now. +- * That means: +- * - the listener does not have to interleave their (checkout) +- * work with our fetching. The writes involved in a +- * checkout involve more straightforward sequential I/O. +- * - the listener can avoid doing any work if fetching failed. +- */ +- if (suc->quickstop) +- return 1; +- +- for (i = 0; i < suc->update_clone_nr; i++) +- update_clone_submodule(&suc->update_clone[i]); +- +- return 0; +-} +- +-static int update_clone(int argc, const char **argv, const char *prefix) +-{ +- const char *update = NULL; +- struct pathspec pathspec; +- struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; +- +- struct option module_update_clone_options[] = { +- OPT_STRING(0, "prefix", &prefix, +- N_("path"), +- N_("path into the working tree")), +- OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, +- N_("path"), +- N_("path into the working tree, across nested " +- "submodule boundaries")), +- OPT_STRING(0, "update", &update, +- N_("string"), +- N_("rebase, merge, checkout or none")), +- OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), +- N_("reference repository")), +- OPT_BOOL(0, "dissociate", &suc.dissociate, +- N_("use --reference only while cloning")), +- OPT_STRING(0, "depth", &suc.depth, "<depth>", +- N_("create a shallow clone truncated to the " +- "specified number of revisions")), +- OPT_INTEGER('j', "jobs", &suc.max_jobs, +- N_("parallel jobs")), +- OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, +- N_("whether the initial clone should follow the shallow recommendation")), +- OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), +- OPT_BOOL(0, "progress", &suc.progress, +- N_("force cloning progress")), +- OPT_BOOL(0, "require-init", &suc.require_init, +- N_("disallow cloning into non-empty directory")), +- OPT_BOOL(0, "single-branch", &suc.single_branch, +- N_("clone only one branch, HEAD or --branch")), +- OPT_END() +- }; +- +- const char *const git_submodule_helper_usage[] = { +- N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), +- NULL +- }; +- suc.prefix = prefix; +- +- update_clone_config_from_gitmodules(&suc.max_jobs); +- git_config(git_update_clone_config, &suc.max_jobs); +- +- argc = parse_options(argc, argv, prefix, module_update_clone_options, +- git_submodule_helper_usage, 0); +- +- if (update) +- if (parse_submodule_update_strategy(update, &suc.update) < 0) +- die(_("bad value for update parameter")); +- +- if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) +- return 1; +- +- if (pathspec.nr) +- suc.warn_if_uninitialized = 1; +- +- return update_clone_submodules(&suc); +-} +- -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; @@ builtin/submodule--helper.c: static void do_ensure_core_worktree(const char *pat int i; @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"clone", module_clone, 0}, - {"add-clone", add_clone, 0}, + {"add", module_add, SUPPORT_SUPER_PREFIX}, {"update", module_update, 0}, - {"update-module-mode", module_update_module_mode, 0}, +- {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, - {"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, 8: ca48dd452c ! 9: 7b5b2be1a0 submodule--helper: rename helper functions @@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, -static void do_ensure_core_worktree(const char *path) +static void ensure_core_worktree(const char *path) { - const struct submodule *sub; const char *cw; + struct repository subrepo; @@ builtin/submodule--helper.c: static int update_submodule(struct update_data *update_data) char *prefixed_path; struct string_list err = STRING_LIST_INIT_DUP; -- 2.32.0 ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar @ 2021-10-13 5:17 ` Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 2/9] submodule--helper: get remote names from any repository Atharva Raykar ` (9 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:17 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip Let's split up `ensure_core_worktree()` so that we can call it from C code without needing to deal with command line arguments. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 88ce6be69c..764fcb7dba 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2764,17 +2764,11 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void do_ensure_core_worktree(const char *path) { - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) die(_("could not get a repository handle for submodule '%s'"), path); @@ -2794,6 +2788,17 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } +} + +static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +{ + const char *path; + + if (argc != 2) + BUG("submodule--helper ensure-core-worktree <path>"); + + path = argv[1]; + do_ensure_core_worktree(path); return 0; } -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 2/9] submodule--helper: get remote names from any repository 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() Atharva Raykar @ 2021-10-13 5:17 ` Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 3/9] submodule--helper: rename helpers for update-clone Atharva Raykar ` (8 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:17 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 764fcb7dba..bbab43230b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,10 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo, const char *refname) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +45,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +54,23 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + const char *refname; + struct repository subrepo; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), + "HEAD", 0, NULL, NULL); + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo, refname); +} + +static char *get_default_remote(void) +{ + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + return repo_get_default_remote(the_repository, refname); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1341,9 +1357,8 @@ static void sync_submodule(const char *path, const char *prefix, { const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; + char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1382,21 +1397,15 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + default_remote = get_default_remote_submodule(path); + if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); - strbuf_strip_suffix(&sb, "\n"); - remote_key = xstrfmt("remote.%s.url", sb.buf); + remote_key = xstrfmt("remote.%s.url", default_remote); + free(default_remote); - strbuf_reset(&sb); submodule_to_gitdir(&sb, path); strbuf_addstr(&sb, "/config"); -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 3/9] submodule--helper: rename helpers for update-clone 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 2/9] submodule--helper: get remote names from any repository Atharva Raykar @ 2021-10-13 5:17 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 4/9] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar ` (7 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:17 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip The `update-clone` subcommand helpers that perform the parallel clone and printing to stdout for shell script consumption, are renamed. This lets us use the names `update_submodules()` and `update_submodule()` for the helpers in the next patch, when we create an `update` subcommand that does a full conversion. We will get rid of these helpers in a cleanup patch at the end of this series, when the `update-clone` command is no longer useful to us. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index bbab43230b..f60db966ea 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2466,7 +2466,7 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) +static void update_clone_submodule(struct update_clone_data *ucd) { fprintf(stdout, "dummy %s %d\t%s\n", oid_to_hex(&ucd->oid), @@ -2474,7 +2474,7 @@ static void update_submodule(struct update_clone_data *ucd) ucd->sub->path); } -static int update_submodules(struct submodule_update_clone *suc) +static int update_clone_submodules(struct submodule_update_clone *suc) { int i; @@ -2495,7 +2495,7 @@ static int update_submodules(struct submodule_update_clone *suc) return 1; for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); + update_clone_submodule(&suc->update_clone[i]); return 0; } @@ -2560,7 +2560,7 @@ static int update_clone(int argc, const char **argv, const char *prefix) if (pathspec.nr) suc.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_clone_submodules(&suc); } static int run_update_procedure(int argc, const char **argv, const char *prefix) -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 4/9] submodule--helper: refactor get_submodule_displaypath() 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (2 preceding siblings ...) 2021-10-13 5:17 ` [PATCH v3 3/9] submodule--helper: rename helpers for update-clone Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 5/9] submodule--helper: allow setting superprefix for init_submodule() Atharva Raykar ` (6 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f60db966ea..5b4f1dbcbd 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -261,11 +261,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -281,6 +278,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 5/9] submodule--helper: allow setting superprefix for init_submodule() 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (3 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 4/9] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 6/9] submodule--helper: run update using child process struct Atharva Raykar ` (5 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip We allow callers of the `init_submodule()` function to optionally override the superprefix from the environment. We need to enable this option because in our conversion of the update command that will follow, the '--init' option will be handled through this API. We will need to change the superprefix at that time to ensure the display paths show correctly in the output messages. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5b4f1dbcbd..74f084a9c9 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -606,18 +606,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; -#define INIT_CB_INIT { NULL, 0 } +#define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -691,7 +695,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 6/9] submodule--helper: run update using child process struct 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (4 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 5/9] submodule--helper: allow setting superprefix for init_submodule() Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 7/9] submodule: move core cmd_update() logic to C Atharva Raykar ` (4 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip We switch to using the run-command API function that takes a 'struct child process', since we are using a lot of the options. This will also make it simple to switch over to using 'capture_command()' when we start handling the output of the command completely in C. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 74f084a9c9..640b3bd220 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2342,47 +2342,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str static int run_update_command(struct update_data *ud, int subforce) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - int git_cmd; switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.use_shell = 1; + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); + if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Unable to checkout '%s' in submodule path '%s'"), -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 7/9] submodule: move core cmd_update() logic to C 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (5 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 6/9] submodule--helper: run update using child process struct Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 8/9] submodule--helper: remove unused helpers Atharva Raykar ` (3 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. We also introduce `update_submodules()` and `update_submodule()` which are quite similar to `update_clone_submodules()` and `update_clone_submodule()`, and will supersede them. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the `init_submodule_cb()` callback over each submodule in the same process. While we are at it, we also remove the fetch_in_submodule() shell function since it is no longer used anywhere. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 462 +++++++++++++++++++++++++++++++----- git-submodule.sh | 145 +---------- 2 files changed, 410 insertions(+), 197 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 640b3bd220..3049628f88 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2010,7 +2010,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -2033,19 +2032,63 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; struct object_id oid; struct object_id suboid; - struct submodule_update_strategy update_strategy; + int max_jobs; int depth; + int recommend_shallow; + int single_branch; + unsigned int init: 1; unsigned int force: 1; unsigned int quiet: 1; unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int remote: 1; + unsigned int recursive: 1; + unsigned int progress: 1; + unsigned int dissociate: 1; + unsigned int require_init: 1; + unsigned warn_if_uninitialized : 1; + unsigned int just_cloned : 1; + struct submodule_update_strategy update_strategy; + struct string_list references; + struct module_list list; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -2340,13 +2383,21 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str return run_command(&cp); } -static int run_update_command(struct update_data *ud, int subforce) +static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) { struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); + struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; + + switch (strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-q", NULL); @@ -2369,80 +2420,75 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: cp.use_shell = 1; - strvec_push(&cp.args, ud->update_strategy.command); + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); - if (run_command(&cp)) { - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); - break; - case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + if (capture_command(&cp, &out, 0)) { + if (must_die_on_failure) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + die(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_REBASE: + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_MERGE: + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_COMMAND: + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + + /* the command failed, but update must continue */ + string_list_append(err, out.buf); return 1; } - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_REBASE: - printf(_("Submodule path '%s': rebased into '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_MERGE: - printf(_("Submodule path '%s': merged in '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_COMMAND: - printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + if (!ud->quiet) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + printf(_("Submodule path '%s': checked out '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_REBASE: + printf(_("Submodule path '%s': rebased into '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_MERGE: + printf(_("Submodule path '%s': merged in '%s'\n"), + ud->displaypath, oid); + break; + case SM_UPDATE_COMMAND: + printf(_("Submodule path '%s': '%s %s'\n"), + ud->displaypath, strategy.command, oid); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } } return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int do_run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2469,7 +2515,7 @@ static int do_run_update_procedure(struct update_data *ud) ud->displaypath, oid_to_hex(&ud->oid)); } - return run_update_command(ud, subforce); + return run_update_command(ud, subforce, err); } static void update_clone_submodule(struct update_clone_data *ucd) @@ -2574,6 +2620,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data update_data = UPDATE_DATA_INIT; + struct string_list err = STRING_LIST_INIT_DUP; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2631,7 +2678,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) free(prefixed_path); if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + return do_run_update_procedure(&update_data, &err); return 3; } @@ -3002,6 +3049,291 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; + struct string_list err = STRING_LIST_INIT_DUP; + + do_ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if(fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + if (do_run_update_procedure(update_data, &err)) + return 1; + + if (update_data->recursive) { + int res; + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + if ((res = run_command(&cp)) == 128) + die("%s", die_msg); + if (res) + string_list_append(&err, die_msg); + + free(die_msg); + } + + if (err.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &err) + fputs(item->string, stderr); + return 1; + } + + return 0; +} + +static int update_submodules(struct update_data *update_data) +{ + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, &suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) { + string_list_clear(&update_data->references, 0); + return 1; + } + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; + + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + + string_list_clear(&update_data->references, 0); + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ + int init = 0, force = 0, quiet = 0, nofetch = 0; + int remote = 0, recursive = 0, dissociate = 0; + int progress = 0, require_init = 0; + const char *update = NULL; + struct pathspec pathspec; + struct update_data update_data = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { + OPT__FORCE(&force, N_("force checkout updates"), 0), + OPT_BOOL(0, "init", &init, + N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "remote", &remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &update_data.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &dissociate, + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &update_data.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &update_data.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &update_data.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &update_data.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + + update_clone_config_from_gitmodules(&update_data.max_jobs); + git_config(git_update_clone_config, &update_data.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + update_data.prefix = prefix; + + update_data.force = !!force; + update_data.quiet = !!quiet; + update_data.nofetch = !!nofetch; + update_data.init = !!init; + update_data.require_init = !!require_init; + update_data.remote = !!remote; + update_data.recursive = !!recursive; + update_data.progress = !!progress; + update_data.dissociate = !!dissociate; + oidcpy(&update_data.oid, null_oid()); + oidcpy(&update_data.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, + &update_data.update_strategy) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &update_data.list) < 0) + return 1; + + if (pathspec.nr) + update_data.warn_if_uninitialized = 1; + + if (update_data.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, update_data.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = update_data.prefix; + info.superprefix = update_data.recursive_prefix; + if (update_data.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&update_data); +} + struct add_data { const char *prefix; const char *branch; @@ -3360,6 +3692,7 @@ static int module_add(int argc, const char **argv, const char *prefix) return 0; } + #define SUPPORT_SUPER_PREFIX (1<<0) struct cmd_struct { @@ -3373,6 +3706,7 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, + {"update", module_update, 0}, {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66..bcd8b92aab 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,20 +246,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -361,133 +347,26 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + ${GIT_QUIET:+--quiet} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 1 - then - subsha1= - else - just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" - fi - - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 8/9] submodule--helper: remove unused helpers 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (6 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 7/9] submodule: move core cmd_update() logic to C Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 9/9] submodule--helper: rename helper functions Atharva Raykar ` (2 subsequent siblings) 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip These helpers were useful back when 'submodule update' had most of its logic in shell. Now that they will never be invoked, let us remove them. We also no longer need the 'update_clone_submodules()' and 'update_clone_submodule()' functions, so we remove those as well. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 233 ------------------------------------ 1 file changed, 233 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 3049628f88..0d6e65bd6c 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -71,21 +71,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository, refname); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -1960,29 +1945,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -2518,182 +2480,6 @@ static int do_run_update_procedure(struct update_data *ud, struct string_list *e return run_update_command(ud, subforce, err); } -static void update_clone_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -static int update_clone_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_clone_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - suc.prefix = prefix; - - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) - return 1; - - if (pathspec.nr) - suc.warn_if_uninitialized = 1; - - return update_clone_submodules(&suc); -} - -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; - struct string_list err = STRING_LIST_INIT_DUP; - - struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; - - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); - else - prefixed_path = xstrdup(update_data.sm_path); - - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); - - free(prefixed_path); - - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data, &err); - - return 3; -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -2852,19 +2638,6 @@ static void do_ensure_core_worktree(const char *path) } } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) -{ - const char *path; - - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - do_ensure_core_worktree(path); - - return 0; -} - static int absorb_git_dirs(int argc, const char **argv, const char *prefix) { int i; @@ -3707,16 +3480,10 @@ static struct cmd_struct commands[] = { {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, {"update", module_update, 0}, - {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v3 9/9] submodule--helper: rename helper functions 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (7 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 8/9] submodule--helper: remove unused helpers Atharva Raykar @ 2021-10-13 5:18 ` Atharva Raykar 2021-10-14 0:05 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Junio C Hamano 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason 10 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-13 5:18 UTC (permalink / raw) To: raykar.ath Cc: avarab, christian.couder, emilyshaffer, git, gitster, jrnieder, kaartic.sivaraam, pc44800, periperidip These two functions were prefixed with 'do' before the shell-to-C conversion because they were utility functions meant to be called by their non-prefixed counterpart. Since those callers don't exist anymore, and these functions can now be used directly, let's rename them to signal this fact. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> --- builtin/submodule--helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0d6e65bd6c..82d68650e8 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2450,7 +2450,7 @@ static int run_update_command(struct update_data *ud, int subforce, struct strin return 0; } -static int do_run_update_procedure(struct update_data *ud, struct string_list *err) +static int run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2612,7 +2612,7 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static void do_ensure_core_worktree(const char *path) +static void ensure_core_worktree(const char *path) { const char *cw; struct repository subrepo; @@ -2871,7 +2871,7 @@ static int update_submodule(struct update_data *update_data) char *prefixed_path; struct string_list err = STRING_LIST_INIT_DUP; - do_ensure_core_worktree(update_data->sm_path); + ensure_core_worktree(update_data->sm_path); if (update_data->recursive_prefix) prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, @@ -2911,7 +2911,7 @@ static int update_submodule(struct update_data *update_data) } if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) - if (do_run_update_procedure(update_data, &err)) + if (run_update_procedure(update_data, &err)) return 1; if (update_data->recursive) { -- 2.32.0 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (8 preceding siblings ...) 2021-10-13 5:18 ` [PATCH v3 9/9] submodule--helper: rename helper functions Atharva Raykar @ 2021-10-14 0:05 ` Junio C Hamano 2021-10-14 20:46 ` Emily Shaffer 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason 10 siblings, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2021-10-14 0:05 UTC (permalink / raw) To: Atharva Raykar Cc: avarab, christian.couder, emilyshaffer, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Atharva Raykar <raykar.ath@gmail.com> writes: > I have attempted to make a version of this series that is based on that topic [2], > and added the superproject gitdir caching code in C [3]. It passes the tests, > but I am not too confident about its correctness. I hope that branch can be > helpful in some way. > > [1] https://lore.kernel.org/git/20210819200953.2105230-1-emilyshaffer@google.com/ > [2] https://github.com/tfidfwastaken/git/commits/submodule-update-on-es-superproject-aware > (fetch-it-via: git fetch https://github.com/tfidfwastaken/git submodule-update-on-es-superproject-aware) > [3] https://github.com/tfidfwastaken/git/blob/a74aaf2540c536970f2541d3042c825f82a69770/builtin/submodule--helper.c#L2922-L2930 The "C rewrite" of the code [3] that unconditionally sets of the submodule.superprojectgitdir varible seems straightforward enough. Emily, how solid do you think your "superproject aware submodule" topic already is? Would it be stable enough to build other things on top, or is it a bit too premature? ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-10-14 0:05 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Junio C Hamano @ 2021-10-14 20:46 ` Emily Shaffer 2021-12-03 19:00 ` Junio C Hamano 0 siblings, 1 reply; 142+ messages in thread From: Emily Shaffer @ 2021-10-14 20:46 UTC (permalink / raw) To: Junio C Hamano Cc: Atharva Raykar, avarab, christian.couder, git, jrnieder, kaartic.sivaraam, pc44800, periperidip On Wed, Oct 13, 2021 at 05:05:58PM -0700, Junio C Hamano wrote: > > Atharva Raykar <raykar.ath@gmail.com> writes: > > > I have attempted to make a version of this series that is based on that topic [2], > > and added the superproject gitdir caching code in C [3]. It passes the tests, > > but I am not too confident about its correctness. I hope that branch can be > > helpful in some way. > > > > [1] https://lore.kernel.org/git/20210819200953.2105230-1-emilyshaffer@google.com/ > > [2] https://github.com/tfidfwastaken/git/commits/submodule-update-on-es-superproject-aware > > (fetch-it-via: git fetch https://github.com/tfidfwastaken/git submodule-update-on-es-superproject-aware) > > [3] https://github.com/tfidfwastaken/git/blob/a74aaf2540c536970f2541d3042c825f82a69770/builtin/submodule--helper.c#L2922-L2930 > > The "C rewrite" of the code [3] that unconditionally sets of the > submodule.superprojectgitdir varible seems straightforward enough. > > Emily, how solid do you think your "superproject aware submodule" > topic already is? Would it be stable enough to build other things > on top, or is it a bit too premature? As of the version I sent today (https://lore.kernel.org/git/20211014203416.2802639-1-emilyshaffer%40google.com) I think it is stable enough to build on top of. There was general consensus on the semantics of submodule.superprojectgitdir as it's sent in v4. - Emily ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-10-14 20:46 ` Emily Shaffer @ 2021-12-03 19:00 ` Junio C Hamano 2021-12-03 20:15 ` Ævar Arnfjörð Bjarmason 2021-12-04 10:38 ` Atharva Raykar 0 siblings, 2 replies; 142+ messages in thread From: Junio C Hamano @ 2021-12-03 19:00 UTC (permalink / raw) To: Atharva Raykar, Emily Shaffer Cc: avarab, christian.couder, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Emily Shaffer <emilyshaffer@google.com> writes: > On Wed, Oct 13, 2021 at 05:05:58PM -0700, Junio C Hamano wrote: >> >> Atharva Raykar <raykar.ath@gmail.com> writes: >> >> > I have attempted to make a version of this series that is based on that topic [2], >> > and added the superproject gitdir caching code in C [3]. It passes the tests, >> > but I am not too confident about its correctness. I hope that branch can be >> > helpful in some way. >> .. >> The "C rewrite" of the code [3] that unconditionally sets of the >> submodule.superprojectgitdir varible seems straightforward enough. >> >> Emily, how solid do you think your "superproject aware submodule" >> topic already is? Would it be stable enough to build other things >> on top, or is it a bit too premature? > > As of the version I sent today > (https://lore.kernel.org/git/20211014203416.2802639-1-emilyshaffer%40google.com) > I think it is stable enough to build on top of. There was general > consensus on the semantics of submodule.superprojectgitdir as it's sent > in v4. Does the above statement still hold true today? And more importantly, Atharva, are you on board with the plan Emily suggested to have this one built on top of her series? Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-12-03 19:00 ` Junio C Hamano @ 2021-12-03 20:15 ` Ævar Arnfjörð Bjarmason 2021-12-04 10:38 ` Atharva Raykar 1 sibling, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2021-12-03 20:15 UTC (permalink / raw) To: Junio C Hamano Cc: Atharva Raykar, Emily Shaffer, christian.couder, git, jrnieder, kaartic.sivaraam, pc44800, periperidip On Fri, Dec 03 2021, Junio C Hamano wrote: > Emily Shaffer <emilyshaffer@google.com> writes: > >> On Wed, Oct 13, 2021 at 05:05:58PM -0700, Junio C Hamano wrote: >>> >>> Atharva Raykar <raykar.ath@gmail.com> writes: >>> >>> > I have attempted to make a version of this series that is based on that topic [2], >>> > and added the superproject gitdir caching code in C [3]. It passes the tests, >>> > but I am not too confident about its correctness. I hope that branch can be >>> > helpful in some way. >>> .. >>> The "C rewrite" of the code [3] that unconditionally sets of the >>> submodule.superprojectgitdir varible seems straightforward enough. >>> >>> Emily, how solid do you think your "superproject aware submodule" >>> topic already is? Would it be stable enough to build other things >>> on top, or is it a bit too premature? >> >> As of the version I sent today >> (https://lore.kernel.org/git/20211014203416.2802639-1-emilyshaffer%40google.com) >> I think it is stable enough to build on top of. There was general >> consensus on the semantics of submodule.superprojectgitdir as it's sent >> in v4. > > Does the above statement still hold true today? > > And more importantly, Atharva, are you on board with the plan Emily > suggested to have this one built on top of her series? I think the current state of it is that Emily & I were having a discussion about the semantics of that series. See [1] and [2]. That's still outstanding. I.e. I haven't been able to reproduce cases where we actually need this caching for performance reasons (which is the reason it exists), but even if we end up keeping it I'd think we'd want something picked from the RFC patches I sent[1] to test the "caching" v.s. "non-caching" behavior, and assert that they're the same. 1. https://lore.kernel.org/git/RFC-cover-0.2-00000000000-20211117T113134Z-avarab@gmail.com/ 2. https://lore.kernel.org/git/211124.86a6hue2wk.gmgdl@evledraar.gmail.com/ ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v3 0/9] submodule: convert the rest of 'update' to C 2021-12-03 19:00 ` Junio C Hamano 2021-12-03 20:15 ` Ævar Arnfjörð Bjarmason @ 2021-12-04 10:38 ` Atharva Raykar 1 sibling, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-12-04 10:38 UTC (permalink / raw) To: Junio C Hamano Cc: Emily Shaffer, avarab, christian.couder, git, jrnieder, kaartic.sivaraam, pc44800, periperidip Junio C Hamano <gitster@pobox.com> writes: > Emily Shaffer <emilyshaffer@google.com> writes: > >> On Wed, Oct 13, 2021 at 05:05:58PM -0700, Junio C Hamano wrote: >>> >>> Atharva Raykar <raykar.ath@gmail.com> writes: >>> >>> > I have attempted to make a version of this series that is based on that topic [2], >>> > and added the superproject gitdir caching code in C [3]. It passes the tests, >>> > but I am not too confident about its correctness. I hope that branch can be >>> > helpful in some way. >>> .. >>> The "C rewrite" of the code [3] that unconditionally sets of the >>> submodule.superprojectgitdir varible seems straightforward enough. >>> >>> Emily, how solid do you think your "superproject aware submodule" >>> topic already is? Would it be stable enough to build other things >>> on top, or is it a bit too premature? >> >> As of the version I sent today >> (https://lore.kernel.org/git/20211014203416.2802639-1-emilyshaffer%40google.com) >> I think it is stable enough to build on top of. There was general >> consensus on the semantics of submodule.superprojectgitdir as it's sent >> in v4. > > Does the above statement still hold true today? > > And more importantly, Atharva, are you on board with the plan Emily > suggested to have this one built on top of her series? Yes, I am on board with that. I have not been closely following their series, but the places where it clashes with this series are minimal, and look quite easy to port later to C. So I'm totally fine with it. > Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v4 0/7] submodule: convert the rest of 'update' to C 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar ` (9 preceding siblings ...) 2021-10-14 0:05 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Junio C Hamano @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason ` (7 more replies) 10 siblings, 8 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason This series rewrites "git submodule update" in C. It's a rebased and re-rolled version of v3[1] submitted back in October. Per [2] the author doesn't have time to push it forward now. There was discussion in the thread at [2] about the interaction between this and es/superproject-aware-submodules. Per [3] I think it would be better to get this in first, as the big outstanding question about the superproject aware submodules[3] was whether it was an optimization or not. It's currently an optimization, but whether it's needed is muddied by "git-submodule.sh" being a shellscript and invoking "git rev-parse" in a loop, which a version rebased on this could do in C. Per the v3 CL of this series[1] there is a C version of the required code for es/superproject-aware-submodules, but when I tried to rebase it it failed because it's based on an older version of es/superproject-aware-submodules which linked to the .git dir rather than the working tree. I.e. the C code[4] produces "../.git" in the tests, but we're expecting "../..". I couldn't find the right API to get that path from path.c et al, but it's presumably easy for someone more familiar with it. As for changes in this v4: * Rebased on master, it didn't compile due to my changes to the refs_resolve_ref_unsafe() API. * There was some back & forth about large patches v.s. split-up commits in previous iterations. This version squashes several patches together, because I thought a rename/add/removal of code that's all related (and really can only be done as one logical step without a major rewrite) was easier to look at than having to jump back and forth in the series. The resulting diff is large, but I think it's better than looking at it piecemeal. You can see what new code replaces what old code. * There's new formatting-only changes in [56]/7 that I added to make the 7/7 diff a tad smaller. The gitster/ar/submodule-update~3..gitster/ar/submodule-update diff (the real meat of the series) is "402 insertions(+), 422 deletions(-)", and 7/7 here is "389 insertions(+), 418 deletions(-)". So it's not much, but thaht churn before 7/7 makes the big change a bit logical change at the end easier to reason about. * I fixed a strbuf and string_list memory leak in the new code, and simplified one codepath that freed correctly, but could use a "goto cleanup" pattern to do away with duplication. There's still a *lot* of memory leaks in builtin/submodule--helper.c, but they're all (well, to the extent that I can extract signal from the noise) in existing code, or in generic APIs that uses which leak. 1. https://lore.kernel.org/git/20211013051805.45662-1-raykar.ath@gmail.com/ 2. https://lore.kernel.org/git/CADi-XoThCqfvPnBd0p6yAhrtotK_3z2pQQMugWPsYpHLbXge7w@mail.gmail.com/ 3. https://lore.kernel.org/git/211203.86o85xqw7o.gmgdl@evledraar.gmail.com/ 4. https://github.com/tfidfwastaken/git/blob/a74aaf2540c536970f2541d3042c825f82a69770/builtin/submodule--helper.c#L2922-L2930 Atharva Raykar (6): submodule--helper: get remote names from any repository submodule--helper: refactor get_submodule_displaypath() submodule--helper: allow setting superprefix for init_submodule() submodule--helper: run update using child process struct builtin/submodule--helper.c: reformat designated initializers submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason (1): builtin/submodule--helper.c: rename "suc" variable to "opt" builtin/submodule--helper.c | 758 +++++++++++++++++++++--------------- git-submodule.sh | 145 +------ 2 files changed, 449 insertions(+), 454 deletions(-) Range-diff against v3: 1: 775f7c01ddb < -: ----------- submodule--helper: split up ensure_core_worktree() 2: fe3d30c1160 ! 1: 1a0b1323cd7 submodule--helper: get remote names from any repository @@ Commit message Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## builtin/submodule--helper.c ## @@ @@ builtin/submodule--helper.c: static char *get_default_remote(void) +{ + const char *refname; + struct repository subrepo; ++ int ignore_errno; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), -+ "HEAD", 0, NULL, NULL); ++ "HEAD", 0, NULL, NULL, ++ &ignore_errno); + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo, refname); +} 3: 8085571a7cb < -: ----------- submodule--helper: rename helpers for update-clone 4: 18c551543ed ! 2: 7e2df3ff220 submodule--helper: refactor get_submodule_displaypath() @@ Commit message Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## builtin/submodule--helper.c ## @@ builtin/submodule--helper.c: static int resolve_relative_url_test(int argc, const char **argv, const char *pr 5: 2be0453750a ! 3: f31fd72fba2 submodule--helper: allow setting superprefix for init_submodule() @@ Commit message Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## builtin/submodule--helper.c ## @@ builtin/submodule--helper.c: static int module_foreach(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: static int module_foreach(int argc, const char **ar + const char *superprefix; unsigned int flags; }; --#define INIT_CB_INIT { NULL, 0 } -+#define INIT_CB_INIT { 0 } + #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) 6: a882b53177d ! 4: 76c5a826a80 submodule--helper: run update using child process struct @@ Commit message Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## builtin/submodule--helper.c ## @@ builtin/submodule--helper.c: static int fetch_in_submodule(const char *module_path, int depth, int quiet, str -: ----------- > 5: 29aa2fc0851 builtin/submodule--helper.c: reformat designated initializers -: ----------- > 6: d3ad6e7a351 builtin/submodule--helper.c: rename "suc" variable to "opt" 7: 3092469f380 ! 7: 02954603763 submodule: move core cmd_update() logic to C @@ Commit message `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. - We also introduce `update_submodules()` and `update_submodule()` which - are quite similar to `update_clone_submodules()` and - `update_clone_submodule()`, and will supersede them. + We also introduce `update_submodules2()` and `update_submodule2()` + which will supersede `update_submodules()` and `update_submodule()`. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, @@ Commit message Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## builtin/submodule--helper.c ## +@@ builtin/submodule--helper.c: static char *get_default_remote(void) + return repo_get_default_remote(the_repository, refname); + } + +-static int print_default_remote(int argc, const char **argv, const char *prefix) +-{ +- char *remote; +- +- if (argc != 1) +- die(_("submodule--helper print-default-remote takes no arguments")); +- +- remote = get_default_remote(); +- if (remote) +- printf("%s\n", remote); +- +- free(remote); +- return 0; +-} +- + static int starts_with_dot_slash(const char *str) + { + return str[0] == '.' && is_dir_sep(str[1]); +@@ builtin/submodule--helper.c: static void determine_submodule_update_strategy(struct repository *r, + free(key); + } + +-static int module_update_module_mode(int argc, const char **argv, const char *prefix) +-{ +- const char *path, *update = NULL; +- int just_cloned; +- struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; +- +- if (argc < 3 || argc > 4) +- die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); +- +- just_cloned = git_config_int("just_cloned", argv[1]); +- path = argv[2]; +- +- if (argc == 4) +- update = argv[3]; +- +- determine_submodule_update_strategy(the_repository, +- just_cloned, path, update, +- &update_strategy); +- fputs(submodule_strategy_to_string(&update_strategy), stdout); +- +- return 0; +-} +- + struct update_clone_data { + const struct submodule *sub; + struct object_id oid; @@ builtin/submodule--helper.c: struct submodule_update_clone { const char *prefix; int single_branch; @@ builtin/submodule--helper.c: struct submodule_update_clone { const char *displaypath; struct object_id oid; struct object_id suboid; -- struct submodule_update_strategy update_strategy; + struct submodule_update_strategy update_strategy; + int max_jobs; int depth; +- unsigned int force: 1; +- unsigned int quiet: 1; +- unsigned int nofetch: 1; +- unsigned int just_cloned: 1; + int recommend_shallow; + int single_branch; -+ unsigned int init: 1; - unsigned int force: 1; - unsigned int quiet: 1; - unsigned int nofetch: 1; -- unsigned int just_cloned: 1; -+ unsigned int remote: 1; -+ unsigned int recursive: 1; -+ unsigned int progress: 1; -+ unsigned int dissociate: 1; -+ unsigned int require_init: 1; -+ unsigned warn_if_uninitialized : 1; -+ unsigned int just_cloned : 1; -+ struct submodule_update_strategy update_strategy; ++ unsigned int init; ++ unsigned int force; ++ unsigned int quiet; ++ unsigned int nofetch; ++ unsigned int remote; ++ unsigned int recursive; ++ unsigned int progress; ++ unsigned int dissociate; ++ unsigned int require_init; ++ unsigned warn_if_uninitialized ; ++ unsigned int just_cloned ; + struct string_list references; + struct module_list list; }; --#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } -+#define UPDATE_DATA_INIT { \ + #define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ -+ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ @@ builtin/submodule--helper.c: struct submodule_update_clone { + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } -+} + } static void next_submodule_warn_missing(struct submodule_update_clone *suc, - struct strbuf *out, const char *displaypath) @@ builtin/submodule--helper.c: static int fetch_in_submodule(const char *module_path, int depth, int quiet, str return run_command(&cp); } @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u + } + + /* the command failed, but update must continue */ -+ string_list_append(err, out.buf); ++ string_list_append_nodup(err, strbuf_detach(&out, NULL)); + return 1; + } + @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u - submodule_strategy_to_string(&ud->update_strategy)); } ++ strbuf_release(&out); return 0; } -static int do_run_update_procedure(struct update_data *ud) -+static int do_run_update_procedure(struct update_data *ud, struct string_list *err) ++static int run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da } - return run_update_command(ud, subforce); +-} +- +-static void update_submodule(struct update_clone_data *ucd) +-{ +- fprintf(stdout, "dummy %s %d\t%s\n", +- oid_to_hex(&ucd->oid), +- ucd->just_cloned, +- ucd->sub->path); +-} +- +-static int update_submodules(struct submodule_update_clone *suc) +-{ +- int i; +- +- run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, +- update_clone_start_failure, +- update_clone_task_finished, suc, "submodule", +- "parallel/update"); +- +- /* +- * We saved the output and put it out all at once now. +- * That means: +- * - the listener does not have to interleave their (checkout) +- * work with our fetching. The writes involved in a +- * checkout involve more straightforward sequential I/O. +- * - the listener can avoid doing any work if fetching failed. +- */ +- if (suc->quickstop) +- return 1; +- +- for (i = 0; i < suc->update_clone_nr; i++) +- update_submodule(&suc->update_clone[i]); +- +- return 0; +-} +- +-static int update_clone(int argc, const char **argv, const char *prefix) +-{ +- const char *update = NULL; +- struct pathspec pathspec; +- struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; +- +- struct option module_update_clone_options[] = { +- OPT_STRING(0, "prefix", &prefix, +- N_("path"), +- N_("path into the working tree")), +- OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, +- N_("path"), +- N_("path into the working tree, across nested " +- "submodule boundaries")), +- OPT_STRING(0, "update", &update, +- N_("string"), +- N_("rebase, merge, checkout or none")), +- OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), +- N_("reference repository")), +- OPT_BOOL(0, "dissociate", &opt.dissociate, +- N_("use --reference only while cloning")), +- OPT_STRING(0, "depth", &opt.depth, "<depth>", +- N_("create a shallow clone truncated to the " +- "specified number of revisions")), +- OPT_INTEGER('j', "jobs", &opt.max_jobs, +- N_("parallel jobs")), +- OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, +- N_("whether the initial clone should follow the shallow recommendation")), +- OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), +- OPT_BOOL(0, "progress", &opt.progress, +- N_("force cloning progress")), +- OPT_BOOL(0, "require-init", &opt.require_init, +- N_("disallow cloning into non-empty directory")), +- OPT_BOOL(0, "single-branch", &opt.single_branch, +- N_("clone only one branch, HEAD or --branch")), +- OPT_END() +- }; +- +- const char *const git_submodule_helper_usage[] = { +- N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), +- NULL +- }; +- opt.prefix = prefix; +- +- update_clone_config_from_gitmodules(&opt.max_jobs); +- git_config(git_update_clone_config, &opt.max_jobs); +- +- argc = parse_options(argc, argv, prefix, module_update_clone_options, +- git_submodule_helper_usage, 0); +- +- if (update) +- if (parse_submodule_update_strategy(update, &opt.update) < 0) +- die(_("bad value for update parameter")); +- +- if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) +- return 1; +- +- if (pathspec.nr) +- opt.warn_if_uninitialized = 1; +- +- return update_submodules(&opt); +-} +- +-static int run_update_procedure(int argc, const char **argv, const char *prefix) +-{ +- int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; +- char *prefixed_path, *update = NULL; +- struct update_data update_data = UPDATE_DATA_INIT; +- +- struct option options[] = { +- OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), +- OPT__FORCE(&force, N_("force checkout updates"), 0), +- OPT_BOOL('N', "no-fetch", &nofetch, +- N_("don't fetch new objects from the remote site")), +- OPT_BOOL(0, "just-cloned", &just_cloned, +- N_("overrides update mode in case the repository is a fresh clone")), +- OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), +- OPT_STRING(0, "prefix", &prefix, +- N_("path"), +- N_("path into the working tree")), +- OPT_STRING(0, "update", &update, +- N_("string"), +- N_("rebase, merge, checkout or none")), +- OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), +- N_("path into the working tree, across nested " +- "submodule boundaries")), +- OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), +- N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, +- parse_opt_object_id), +- OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), +- N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, +- parse_opt_object_id), +- OPT_END() +- }; +- +- const char *const usage[] = { +- N_("git submodule--helper run-update-procedure [<options>] <path>"), +- NULL +- }; +- +- argc = parse_options(argc, argv, prefix, options, usage, 0); +- +- if (argc != 1) +- usage_with_options(usage, options); +- +- update_data.force = !!force; +- update_data.quiet = !!quiet; +- update_data.nofetch = !!nofetch; +- update_data.just_cloned = !!just_cloned; +- update_data.sm_path = argv[0]; +- +- if (update_data.recursive_prefix) +- prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); +- else +- prefixed_path = xstrdup(update_data.sm_path); +- +- update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); +- +- determine_submodule_update_strategy(the_repository, update_data.just_cloned, +- update_data.sm_path, update, +- &update_data.update_strategy); +- +- free(prefixed_path); +- +- if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) +- return do_run_update_procedure(&update_data); +- +- return 3; +-} +- +-static int resolve_relative_path(int argc, const char **argv, const char *prefix) +-{ +- struct strbuf sb = STRBUF_INIT; +- if (argc != 3) +- die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); +- +- printf("%s", relative_path(argv[1], argv[2], &sb)); +- strbuf_release(&sb); +- return 0; + return run_update_command(ud, subforce, err); } - static void update_clone_submodule(struct update_clone_data *ucd) -@@ builtin/submodule--helper.c: static int run_update_procedure(int argc, const char **argv, const char *prefix) - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; -+ struct string_list err = STRING_LIST_INIT_DUP; + static const char *remote_submodule_branch(const char *path) +@@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, const char *prefix) + return 0; + } - struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), -@@ builtin/submodule--helper.c: static int run_update_procedure(int argc, const char **argv, const char *prefix) - free(prefixed_path); +-static int ensure_core_worktree(int argc, const char **argv, const char *prefix) ++static void ensure_core_worktree(const char *path) + { +- const char *path; + const char *cw; + struct repository subrepo; - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) -- return do_run_update_procedure(&update_data); -+ return do_run_update_procedure(&update_data, &err); +- if (argc != 2) +- BUG("submodule--helper ensure-core-worktree <path>"); +- +- path = argv[1]; +- + if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) + die(_("could not get a repository handle for submodule '%s'"), path); - return 3; +@@ builtin/submodule--helper.c: static int ensure_core_worktree(int argc, const char **argv, const char *prefix) + free(abs_path); + strbuf_release(&sb); + } +- +- return 0; } + + static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + char *prefixed_path; + struct string_list err = STRING_LIST_INIT_DUP; + -+ do_ensure_core_worktree(update_data->sm_path); ++ ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { -+ if(fetch_in_submodule(update_data->sm_path, update_data->depth, ++ if (fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) -+ if (do_run_update_procedure(update_data, &err)) ++ if (run_update_procedure(update_data, &err)) + return 1; + + if (update_data->recursive) { @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + struct string_list_item *item; + for_each_string_list_item(item, &err) + fputs(item->string, stderr); ++ string_list_clear(&err, 0); + return 1; + } + @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) { -+ string_list_clear(&update_data->references, 0); -+ return 1; ++ res = 1; ++ goto cleanup; + } + + for (i = 0; i < suc.update_clone_nr; i++) { @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + res = 1; + } + ++cleanup: + string_list_clear(&update_data->references, 0); + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ -+ int init = 0, force = 0, quiet = 0, nofetch = 0; -+ int remote = 0, recursive = 0, dissociate = 0; -+ int progress = 0, require_init = 0; + const char *update = NULL; + struct pathspec pathspec; -+ struct update_data update_data = UPDATE_DATA_INIT; ++ struct update_data opt = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { -+ OPT__FORCE(&force, N_("force checkout updates"), 0), -+ OPT_BOOL(0, "init", &init, ++ OPT__FORCE(&opt.force, N_("force checkout updates"), 0), ++ OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), -+ OPT_BOOL(0, "remote", &remote, ++ OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), -+ OPT_BOOL(0, "recursive", &recursive, ++ OPT_BOOL(0, "recursive", &opt.recursive, + N_("traverse submodules recursively")), -+ OPT_BOOL('N', "no-fetch", &nofetch, ++ OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), -+ OPT_STRING(0, "prefix", &prefix, ++ OPT_STRING(0, "prefix", &opt.prefix, + N_("path"), + N_("path into the working tree")), -+ OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, ++ OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), -+ OPT_STRING_LIST(0, "reference", &update_data.references, N_("repo"), ++ OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("reference repository")), -+ OPT_BOOL(0, "dissociate", &dissociate, ++ OPT_BOOL(0, "dissociate", &opt.dissociate, + N_("use --reference only while cloning")), -+ OPT_INTEGER(0, "depth", &update_data.depth, ++ OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), -+ OPT_INTEGER('j', "jobs", &update_data.max_jobs, ++ OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), -+ OPT_BOOL(0, "recommend-shallow", &update_data.recommend_shallow, ++ OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), -+ OPT__QUIET(&quiet, N_("don't print cloning progress")), -+ OPT_BOOL(0, "progress", &progress, ++ OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), ++ OPT_BOOL(0, "progress", &opt.progress, + N_("force cloning progress")), -+ OPT_BOOL(0, "require-init", &require_init, ++ OPT_BOOL(0, "require-init", &opt.require_init, + N_("disallow cloning into non-empty directory")), -+ OPT_BOOL(0, "single-branch", &update_data.single_branch, ++ OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + NULL + }; + -+ update_clone_config_from_gitmodules(&update_data.max_jobs); -+ git_config(git_update_clone_config, &update_data.max_jobs); ++ update_clone_config_from_gitmodules(&opt.max_jobs); ++ git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); -+ update_data.prefix = prefix; -+ -+ update_data.force = !!force; -+ update_data.quiet = !!quiet; -+ update_data.nofetch = !!nofetch; -+ update_data.init = !!init; -+ update_data.require_init = !!require_init; -+ update_data.remote = !!remote; -+ update_data.recursive = !!recursive; -+ update_data.progress = !!progress; -+ update_data.dissociate = !!dissociate; -+ oidcpy(&update_data.oid, null_oid()); -+ oidcpy(&update_data.suboid, null_oid()); ++ oidcpy(&opt.oid, null_oid()); ++ oidcpy(&opt.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, -+ &update_data.update_strategy) < 0) ++ &opt.update_strategy) < 0) + die(_("bad value for update parameter")); + -+ if (module_list_compute(argc, argv, prefix, &pathspec, &update_data.list) < 0) ++ if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) + return 1; + + if (pathspec.nr) -+ update_data.warn_if_uninitialized = 1; ++ opt.warn_if_uninitialized = 1; + -+ if (update_data.init) { ++ if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + -+ if (module_list_compute(argc, argv, update_data.prefix, ++ if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + -+ info.prefix = update_data.prefix; -+ info.superprefix = update_data.recursive_prefix; -+ if (update_data.quiet) ++ info.prefix = opt.prefix; ++ info.superprefix = opt.recursive_prefix; ++ if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + -+ return update_submodules(&update_data); ++ return update_submodules(&opt); +} + struct add_data { const char *prefix; const char *branch; -@@ builtin/submodule--helper.c: static int module_add(int argc, const char **argv, const char *prefix) - return 0; - } - -+ - #define SUPPORT_SUPER_PREFIX (1<<0) - - struct cmd_struct { @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, +- {"update-module-mode", module_update_module_mode, 0}, +- {"update-clone", update_clone, 0}, +- {"run-update-procedure", run_update_procedure, 0}, +- {"ensure-core-worktree", ensure_core_worktree, 0}, +- {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, - {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, + {"resolve-relative-url-test", resolve_relative_url_test, 0}, + {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, + {"init", module_init, SUPPORT_SUPER_PREFIX}, + {"status", module_status, SUPPORT_SUPER_PREFIX}, +- {"print-default-remote", print_default_remote, 0}, + {"sync", module_sync, SUPPORT_SUPER_PREFIX}, + {"deinit", module_deinit, 0}, + {"summary", module_summary, SUPPORT_SUPER_PREFIX}, ## git-submodule.sh ## @@ git-submodule.sh: cmd_deinit() 8: cee4beb7abe < -: ----------- submodule--helper: remove unused helpers 9: 2194c1729f1 < -: ----------- submodule--helper: rename helper functions -- 2.35.0.894.g563b84683b9 ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v4 1/7] submodule--helper: get remote names from any repository 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 18:45 ` Glen Choo 2022-01-27 16:22 ` [PATCH v4 2/7] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason ` (6 subsequent siblings) 7 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 41 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c5d3fc3817f..965260edb22 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,10 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo, const char *refname) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +45,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +54,25 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + const char *refname; + struct repository subrepo; + int ignore_errno; + + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), + "HEAD", 0, NULL, NULL, + &ignore_errno); + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo, refname); +} + +static char *get_default_remote(void) +{ + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + return repo_get_default_remote(the_repository, refname); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1341,9 +1359,8 @@ static void sync_submodule(const char *path, const char *prefix, { const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; + char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1382,21 +1399,15 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + default_remote = get_default_remote_submodule(path); + if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); - strbuf_strip_suffix(&sb, "\n"); - remote_key = xstrfmt("remote.%s.url", sb.buf); + remote_key = xstrfmt("remote.%s.url", default_remote); + free(default_remote); - strbuf_reset(&sb); submodule_to_gitdir(&sb, path); strbuf_addstr(&sb, "/config"); -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v4 1/7] submodule--helper: get remote names from any repository 2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason @ 2022-01-27 18:45 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-01-27 18:45 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason, git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: This wasn't introduced by you (it was introduced in v1 [1]), but I think it's worth pointing out. > Let's instead introduce a function called `repo_get_default_remote()` > which takes any repository object and retrieves the remote accordingly. > > `get_default_remote()` is then defined as a call to > `repo_get_default_remote()` with 'the_repository' passed to it. We say this, suggesting that repo_get_default_remote()'s signature is just get_default_remote()'s plus a "struct repository *" (like most repo_*). But.. > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index c5d3fc3817f..965260edb22 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -29,11 +29,10 @@ > typedef void (*each_submodule_fn)(const struct cache_entry *list_item, > void *cb_data); > > -static char *get_default_remote(void) > +static char *repo_get_default_remote(struct repository *repo, const char *refname) > { > char *dest = NULL, *ret; > struct strbuf sb = STRBUF_INIT; > - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); > > if (!refname) > die(_("No such ref: %s"), "HEAD"); > @@ -46,7 +45,7 @@ static char *get_default_remote(void) > die(_("Expecting a full ref name, got %s"), refname); > > strbuf_addf(&sb, "branch.%s.remote", refname); > - if (git_config_get_string(sb.buf, &dest)) > + if (repo_config_get_string(repo, sb.buf, &dest)) > ret = xstrdup("origin"); > else > ret = dest; > @@ -55,6 +54,25 @@ static char *get_default_remote(void) > return ret; > } > > +static char *get_default_remote_submodule(const char *module_path) > +{ > + const char *refname; > + struct repository subrepo; > + int ignore_errno; > + > + refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), > + "HEAD", 0, NULL, NULL, > + &ignore_errno); > + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); > + return repo_get_default_remote(&subrepo, refname); > +} > + > +static char *get_default_remote(void) > +{ > + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); > + return repo_get_default_remote(the_repository, refname); > +} > + repo_get_default_remote() actually take yet another argument - refname. It looks to me that repo_get_default_remote() shouldn't take the refname argument at all and that we should be using refs_resolve_ref_unsafe() instead, like: +static char *repo_get_default_remote(struct repository *repo) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + const char *refname = refs_resolve_ref_unsafe( + get_main_ref_store(repo), "HEAD", 0, NULL, NULL /*, errno? */); this makes the rest of the code a lot cleaner.. +static char *get_default_remote_submodule(const char *module_path) +{ + struct repository subrepo; + + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo); +} + +static char *get_default_remote(void) +{ + return repo_get_default_remote(the_repository); +} And because it's quite idiomatic to initialize the subrepo struct in order to can call repo_* functions, we could even drop get_default_remote_submodule() altogether. As for why this wasn't the original approach, the only reason I can think of is that we didn't realize get_main_ref_store(subrepo) was an option. [1] https://lore.kernel.org/git/20210907115932.36068-3-raykar.ath@gmail.com/ ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v4 2/7] submodule--helper: refactor get_submodule_displaypath() 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 3/7] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason ` (5 subsequent siblings) 7 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 965260edb22..d38a64c7b7d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -263,11 +263,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -283,6 +280,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v4 3/7] submodule--helper: allow setting superprefix for init_submodule() 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 2/7] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 4/7] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason ` (4 subsequent siblings) 7 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We allow callers of the `init_submodule()` function to optionally override the superprefix from the environment. We need to enable this option because in our conversion of the update command that will follow, the '--init' option will be handled through this API. We will need to change the superprefix at that time to ensure the display paths show correctly in the output messages. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index d38a64c7b7d..f8e18820ace 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -608,18 +608,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -693,7 +697,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v4 4/7] submodule--helper: run update using child process struct 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason ` (2 preceding siblings ...) 2022-01-27 16:22 ` [PATCH v4 3/7] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 5/7] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason ` (3 subsequent siblings) 7 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We switch to using the run-command API function that takes a 'struct child process', since we are using a lot of the options. This will also make it simple to switch over to using 'capture_command()' when we start handling the output of the command completely in C. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f8e18820ace..328c6cc87cd 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2346,47 +2346,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str static int run_update_command(struct update_data *ud, int subforce) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - int git_cmd; switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.use_shell = 1; + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); + if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Unable to checkout '%s' in submodule path '%s'"), -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v4 5/7] builtin/submodule--helper.c: reformat designated initializers 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason ` (3 preceding siblings ...) 2022-01-27 16:22 ` [PATCH v4 4/7] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 6/7] builtin/submodule--helper.c: rename "suc" variable to "opt" Ævar Arnfjörð Bjarmason ` (2 subsequent siblings) 7 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> The second hunk here will make a subsequent commit's diff smaller, and let's do the first and third hunks while we're at it so that we consistently format all of these. Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 328c6cc87cd..1553b318cc7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1656,7 +1656,10 @@ struct module_clone_data { unsigned int require_init: 1; int single_branch; }; -#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 } +#define MODULE_CLONE_DATA_INIT { \ + .reference = STRING_LIST_INIT_NODUP, \ + .single_branch = -1, \ +} struct submodule_alternate_setup { const char *submodule_name; @@ -2049,7 +2052,9 @@ struct update_data { unsigned int nofetch: 1; unsigned int just_cloned: 1; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -3015,7 +3020,9 @@ struct add_data { unsigned int progress: 1; unsigned int dissociate: 1; }; -#define ADD_DATA_INIT { .depth = -1 } +#define ADD_DATA_INIT { \ + .depth = -1, \ +} static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) { -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v4 6/7] builtin/submodule--helper.c: rename "suc" variable to "opt" 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason ` (4 preceding siblings ...) 2022-01-27 16:22 ` [PATCH v4 5/7] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 7/7] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 7 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason Rename the "suc" variable in "builtin/submodule--helper.c" to "opt". The only reason for this change is to make the subsequent commit's diff smaller, by doing this rename we can "anchor" the diff better, as it "borrow" most of the options declared here as-is as far as the diff rename detection is concerned. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 1553b318cc7..a96976b1772 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2519,36 +2519,36 @@ static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, + OPT_BOOL(0, "dissociate", &opt.dissociate, N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", + OPT_STRING(0, "depth", &opt.depth, "<depth>", N_("create a shallow clone truncated to the " "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, + OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, + OPT_BOOL(0, "require-init", &opt.require_init, N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, + OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() }; @@ -2557,25 +2557,25 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - suc.prefix = prefix; + opt.prefix = prefix; - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) + if (parse_submodule_update_strategy(update, &opt.update) < 0) die(_("bad value for update parameter")); - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) return 1; if (pathspec.nr) - suc.warn_if_uninitialized = 1; + opt.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_submodules(&opt); } static int run_update_procedure(int argc, const char **argv, const char *prefix) -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v4 7/7] submodule: move core cmd_update() logic to C 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason ` (5 preceding siblings ...) 2022-01-27 16:22 ` [PATCH v4 6/7] builtin/submodule--helper.c: rename "suc" variable to "opt" Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 ` Ævar Arnfjörð Bjarmason 2022-01-27 21:55 ` Glen Choo 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 7 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-27 16:22 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. We also introduce `update_submodules2()` and `update_submodule2()` which will supersede `update_submodules()` and `update_submodule()`. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the `init_submodule_cb()` callback over each submodule in the same process. While we are at it, we also remove the fetch_in_submodule() shell function since it is no longer used anywhere. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 662 ++++++++++++++++++++---------------- git-submodule.sh | 145 +------- 2 files changed, 389 insertions(+), 418 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a96976b1772..916df6d9947 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -73,21 +73,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository, refname); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -1967,29 +1952,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -2017,7 +1979,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -2040,20 +2001,62 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; struct object_id oid; struct object_id suboid; struct submodule_update_strategy update_strategy; + int max_jobs; int depth; - unsigned int force: 1; - unsigned int quiet: 1; - unsigned int nofetch: 1; - unsigned int just_cloned: 1; + int recommend_shallow; + int single_branch; + unsigned int init; + unsigned int force; + unsigned int quiet; + unsigned int nofetch; + unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; + unsigned int require_init; + unsigned warn_if_uninitialized ; + unsigned int just_cloned ; + struct string_list references; + struct module_list list; }; #define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } } static void next_submodule_warn_missing(struct submodule_update_clone *suc, @@ -2349,13 +2352,21 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str return run_command(&cp); } -static int run_update_command(struct update_data *ud, int subforce) +static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) { struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); + struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; + + switch (strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-q", NULL); @@ -2378,80 +2389,76 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: cp.use_shell = 1; - strvec_push(&cp.args, ud->update_strategy.command); + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); - if (run_command(&cp)) { - switch (ud->update_strategy.type) { + if (capture_command(&cp, &out, 0)) { + if (must_die_on_failure) { + switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + die(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_REBASE: + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_MERGE: + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); + break; + case SM_UPDATE_COMMAND: + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); + break; + default: + BUG("unexpected update strategy type: %s", + submodule_strategy_to_string(&strategy)); + } + } + + /* the command failed, but update must continue */ + string_list_append_nodup(err, strbuf_detach(&out, NULL)); + return 1; + } + + if (!ud->quiet) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); + printf(_("Submodule path '%s': checked out '%s'\n"), + ud->displaypath, oid); break; case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); + printf(_("Submodule path '%s': rebased into '%s'\n"), + ud->displaypath, oid); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); + printf(_("Submodule path '%s': merged in '%s'\n"), + ud->displaypath, oid); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); + printf(_("Submodule path '%s': '%s %s'\n"), + ud->displaypath, strategy.command, oid); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ - return 1; - } - - switch (ud->update_strategy.type) { - case SM_UPDATE_CHECKOUT: - printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_REBASE: - printf(_("Submodule path '%s': rebased into '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_MERGE: - printf(_("Submodule path '%s': merged in '%s'\n"), - ud->displaypath, oid); - break; - case SM_UPDATE_COMMAND: - printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); - break; - default: - BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); } + strbuf_release(&out); return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int run_update_procedure(struct update_data *ud, struct string_list *err) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2478,182 +2485,7 @@ static int do_run_update_procedure(struct update_data *ud) ud->displaypath, oid_to_hex(&ud->oid)); } - return run_update_command(ud, subforce); -} - -static void update_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -static int update_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &opt.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &opt.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - opt.prefix = prefix; - - update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) - return 1; - - if (pathspec.nr) - opt.warn_if_uninitialized = 1; - - return update_submodules(&opt); -} - -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; - - struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; - - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); - else - prefixed_path = xstrdup(update_data.sm_path); - - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); - - free(prefixed_path); - - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); - - return 3; -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; + return run_update_command(ud, subforce, err); } static const char *remote_submodule_branch(const char *path) @@ -2788,17 +2620,11 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void ensure_core_worktree(const char *path) { - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) die(_("could not get a repository handle for submodule '%s'"), path); @@ -2818,8 +2644,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } - - return 0; } static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ -3006,6 +2830,279 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; + struct string_list err = STRING_LIST_INIT_DUP; + + ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if (fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + if (run_update_procedure(update_data, &err)) + return 1; + + if (update_data->recursive) { + int res; + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + if ((res = run_command(&cp)) == 128) + die("%s", die_msg); + if (res) + string_list_append(&err, die_msg); + + free(die_msg); + } + + if (err.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &err) + fputs(item->string, stderr); + string_list_clear(&err, 0); + return 1; + } + + return 0; +} + +static int update_submodules(struct update_data *update_data) +{ + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, &suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) { + res = 1; + goto cleanup; + } + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; + + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + +cleanup: + string_list_clear(&update_data->references, 0); + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ + const char *update = NULL; + struct pathspec pathspec; + struct update_data opt = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { + OPT__FORCE(&opt.force, N_("force checkout updates"), 0), + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &opt.recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &opt.prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &opt.dissociate, + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &opt.require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, + &opt.update_strategy) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) + return 1; + + if (pathspec.nr) + opt.warn_if_uninitialized = 1; + + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&opt); +} + struct add_data { const char *prefix; const char *branch; @@ -3393,16 +3490,11 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66a..bcd8b92aabd 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,20 +246,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -361,133 +347,26 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + ${GIT_QUIET:+--quiet} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 1 - then - subsha1= - else - just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" - fi - - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.35.0.894.g563b84683b9 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v4 7/7] submodule: move core cmd_update() logic to C 2022-01-27 16:22 ` [PATCH v4 7/7] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason @ 2022-01-27 21:55 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-01-27 21:55 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason, git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > From: Atharva Raykar <raykar.ath@gmail.com> > > This patch completes the conversion past the flag parsing of > `submodule update` by introducing a helper subcommand called > `submodule--helper update`. The behaviour of `submodule update` should > remain the same after this patch. > > We add more fields to the `struct update_data` that are required by > `struct submodule_update_clone` to be able to perform a clone, when that > is needed to be done. > > Recursing on a submodule is done by calling a subprocess that launches > `submodule--helper update`, with a modified `--recursive-prefix` and > `--prefix` parameter. > > We also introduce `update_submodules2()` and `update_submodule2()` > which will supersede `update_submodules()` and `update_submodule()`. > > When the `--init` flag is passed to the subcommand, we do not spawn a > new subprocess and call `submodule--helper init` on the submodule paths, > because the Git machinery is not able to pick up the configuration > changes introduced by that init call[1]. So we instead run the > `init_submodule_cb()` callback over each submodule in the same process. > > While we are at it, we also remove the fetch_in_submodule() shell > function since it is no longer used anywhere. > > [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > Signed-off-by: Junio C Hamano <gitster@pobox.com> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> > --- I've read through all of the patches besides this one - I hope to get through this one soon. The diff is quite large, but I can't think of any way to shrink it down at the moment. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v5 0/9] submodule: convert the rest of 'update' to C 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason ` (6 preceding siblings ...) 2022-01-27 16:22 ` [PATCH v4 7/7] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 1/9] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason ` (9 more replies) 7 siblings, 10 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason A rewrite of "git submodule" in C, except the trivial pass-through wrapping code (basically getopt etc.) in git-submodule.sh. For a greater summary & context see v4's CL: https://lore.kernel.org/git/cover-v4-0.7-00000000000-20220127T143552Z-avarab@gmail.com/ Changes in v5: * Took Glen Choo's suggestion for a code change in 1/8, thanks! * A bit more mid-series churn to make the large commit at the end have a smaller diff. The result is that in v4/v5 we have in that last commit (but see below). - 2 files changed, 389 insertions(+), 418 deletions(-) + 2 files changed, 357 insertions(+), 388 deletions(-) * There were some logic errors in v4 around how we handled error reporting. A new 8/9 adds tests for the existing behavior, and we're now bug-for-bug compatible. It turned out that we were passing around string lists of errors etc. in a way that wasn't needed, i.e. the initial code can just report the error. Much of this was also simplified with my recently added die_message() function. I.e. sometimes we want to have a "fatal: " message, but exit non-128. Atharva Raykar (6): submodule--helper: get remote names from any repository submodule--helper: refactor get_submodule_displaypath() submodule--helper: allow setting superprefix for init_submodule() submodule--helper: run update using child process struct builtin/submodule--helper.c: reformat designated initializers submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason (3): builtin/submodule--helper.c: rename option variables to "opt" submodule--helper: don't use bitfield indirection for parse_options() submodule tests: test for init and update failure output builtin/submodule--helper.c | 706 +++++++++++++++++++-------------- git-submodule.sh | 145 +------ t/t7406-submodule-update.sh | 14 +- t/t7408-submodule-reference.sh | 14 +- 4 files changed, 444 insertions(+), 435 deletions(-) Range-diff against v4: 1: 1a0b1323cd7 ! 1: 088c7236a16 submodule--helper: get remote names from any repository @@ Commit message Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> + Helped-by: Glen Choo <chooglen@google.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> @@ builtin/submodule--helper.c void *cb_data); -static char *get_default_remote(void) -+static char *repo_get_default_remote(struct repository *repo, const char *refname) ++static char *repo_get_default_remote(struct repository *repo) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); ++ struct ref_store *store = get_main_ref_store(repo); ++ int ignore_errno; ++ const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL, ++ NULL, &ignore_errno); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ builtin/submodule--helper.c: static char *get_default_remote(void) +static char *get_default_remote_submodule(const char *module_path) +{ -+ const char *refname; + struct repository subrepo; -+ int ignore_errno; + -+ refname = refs_resolve_ref_unsafe(get_submodule_ref_store(module_path), -+ "HEAD", 0, NULL, NULL, -+ &ignore_errno); + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); -+ return repo_get_default_remote(&subrepo, refname); ++ return repo_get_default_remote(&subrepo); +} + +static char *get_default_remote(void) +{ -+ const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); -+ return repo_get_default_remote(the_repository, refname); ++ return repo_get_default_remote(the_repository); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) 2: 7e2df3ff220 = 2: bc694987893 submodule--helper: refactor get_submodule_displaypath() 3: f31fd72fba2 = 3: e2cc7f0e23b submodule--helper: allow setting superprefix for init_submodule() 4: 76c5a826a80 = 4: e1df2dd4457 submodule--helper: run update using child process struct 5: 29aa2fc0851 = 5: fa815e37f9f builtin/submodule--helper.c: reformat designated initializers 6: d3ad6e7a351 ! 6: ef097f7ea51 builtin/submodule--helper.c: rename "suc" variable to "opt" @@ Metadata Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ## Commit message ## - builtin/submodule--helper.c: rename "suc" variable to "opt" + builtin/submodule--helper.c: rename option variables to "opt" - Rename the "suc" variable in "builtin/submodule--helper.c" to - "opt". The only reason for this change is to make the subsequent - commit's diff smaller, by doing this rename we can "anchor" the diff - better, as it "borrow" most of the options declared here as-is as far - as the diff rename detection is concerned. + Rename the "suc" variable in update_clone() to "opt", and do the same + for the "update_data" variable in run_update_procedure(). + + The only reason for this change is to make the subsequent commit's + diff smaller, by doing this rename we can "anchor" the diff better, as + it "borrow" most of the options declared here as-is as far as the diff + rename detection is concerned. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> @@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv } static int run_update_procedure(int argc, const char **argv, const char *prefix) + { + int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; + char *prefixed_path, *update = NULL; +- struct update_data update_data = UPDATE_DATA_INIT; ++ struct update_data opt = UPDATE_DATA_INIT; + + struct option options[] = { + OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), +@@ builtin/submodule--helper.c: static int run_update_procedure(int argc, const char **argv, const char *prefix) + N_("don't fetch new objects from the remote site")), + OPT_BOOL(0, "just-cloned", &just_cloned, + N_("overrides update mode in case the repository is a fresh clone")), +- OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), ++ OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), +- OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), ++ OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), +- OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), ++ OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), + N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, + parse_opt_object_id), +- OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), ++ OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), + N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, + parse_opt_object_id), + OPT_END() +@@ builtin/submodule--helper.c: static int run_update_procedure(int argc, const char **argv, const char *prefix) + if (argc != 1) + usage_with_options(usage, options); + +- update_data.force = !!force; +- update_data.quiet = !!quiet; +- update_data.nofetch = !!nofetch; +- update_data.just_cloned = !!just_cloned; +- update_data.sm_path = argv[0]; ++ opt.force = !!force; ++ opt.quiet = !!quiet; ++ opt.nofetch = !!nofetch; ++ opt.just_cloned = !!just_cloned; ++ opt.sm_path = argv[0]; + +- if (update_data.recursive_prefix) +- prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); ++ if (opt.recursive_prefix) ++ prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); + else +- prefixed_path = xstrdup(update_data.sm_path); ++ prefixed_path = xstrdup(opt.sm_path); + +- update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); ++ opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); + +- determine_submodule_update_strategy(the_repository, update_data.just_cloned, +- update_data.sm_path, update, +- &update_data.update_strategy); ++ determine_submodule_update_strategy(the_repository, opt.just_cloned, ++ opt.sm_path, update, ++ &opt.update_strategy); + + free(prefixed_path); + +- if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) +- return do_run_update_procedure(&update_data); ++ if (!oideq(&opt.oid, &opt.suboid) || opt.force) ++ return do_run_update_procedure(&opt); + + return 3; + } -: ----------- > 7: 6b038f558c1 submodule--helper: don't use bitfield indirection for parse_options() -: ----------- > 8: b4f84132201 submodule tests: test for init and update failure output 7: 02954603763 ! 9: e8e57606ee9 submodule: move core cmd_update() logic to C @@ Commit message ## builtin/submodule--helper.c ## @@ builtin/submodule--helper.c: static char *get_default_remote(void) - return repo_get_default_remote(the_repository, refname); + return repo_get_default_remote(the_repository); } -static int print_default_remote(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: struct submodule_update_clone { const char *recursive_prefix; const char *sm_path; const char *displaypath; - struct object_id oid; +@@ builtin/submodule--helper.c: struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; -+ int max_jobs; int depth; -- unsigned int force: 1; -- unsigned int quiet: 1; -- unsigned int nofetch: 1; -- unsigned int just_cloned: 1; + int recommend_shallow; + int single_branch; ++ int max_jobs; + unsigned int init; -+ unsigned int force; -+ unsigned int quiet; -+ unsigned int nofetch; + unsigned int force; + unsigned int quiet; + unsigned int nofetch; + unsigned int just_cloned; + unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; + unsigned int require_init; + unsigned warn_if_uninitialized ; -+ unsigned int just_cloned ; + struct string_list references; + struct module_list list; }; @@ builtin/submodule--helper.c: struct submodule_update_clone { } static void next_submodule_warn_missing(struct submodule_update_clone *suc, -@@ builtin/submodule--helper.c: static int fetch_in_submodule(const char *module_path, int depth, int quiet, str - return run_command(&cp); - } - --static int run_update_command(struct update_data *ud, int subforce) -+static int run_update_command(struct update_data *ud, int subforce, struct string_list *err) - { +@@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); -+ struct strbuf out = STRBUF_INIT; int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); -- if (run_command(&cp)) { + if (run_command(&cp)) { - switch (ud->update_strategy.type) { -+ if (capture_command(&cp, &out, 0)) { -+ if (must_die_on_failure) { -+ switch (strategy.type) { -+ case SM_UPDATE_CHECKOUT: -+ die(_("Unable to checkout '%s' in submodule path '%s'"), -+ oid, ud->displaypath); -+ break; -+ case SM_UPDATE_REBASE: -+ die(_("Unable to rebase '%s' in submodule path '%s'"), -+ oid, ud->displaypath); -+ break; -+ case SM_UPDATE_MERGE: -+ die(_("Unable to merge '%s' in submodule path '%s'"), -+ oid, ud->displaypath); -+ break; -+ case SM_UPDATE_COMMAND: -+ die(_("Execution of '%s %s' failed in submodule path '%s'"), -+ strategy.command, oid, ud->displaypath); -+ break; -+ default: -+ BUG("unexpected update strategy type: %s", -+ submodule_strategy_to_string(&strategy)); -+ } -+ } -+ -+ /* the command failed, but update must continue */ -+ string_list_append_nodup(err, strbuf_detach(&out, NULL)); -+ return 1; -+ } -+ -+ if (!ud->quiet) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); -+ printf(_("Submodule path '%s': checked out '%s'\n"), -+ ud->displaypath, oid); ++ die_message(_("Unable to checkout '%s' in submodule path '%s'"), ++ oid, ud->displaypath); break; case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); -+ printf(_("Submodule path '%s': rebased into '%s'\n"), -+ ud->displaypath, oid); ++ if (!must_die_on_failure) ++ break; ++ die(_("Unable to rebase '%s' in submodule path '%s'"), ++ oid, ud->displaypath); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); -+ printf(_("Submodule path '%s': merged in '%s'\n"), -+ ud->displaypath, oid); ++ if (!must_die_on_failure) ++ break; ++ die(_("Unable to merge '%s' in submodule path '%s'"), ++ oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); -+ printf(_("Submodule path '%s': '%s %s'\n"), -+ ud->displaypath, strategy.command, oid); ++ if (!must_die_on_failure) ++ break; ++ die(_("Execution of '%s %s' failed in submodule path '%s'"), ++ strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u - * This signifies to the caller in shell that the command - * failed without dying - */ -- return 1; -- } -- ++ ++ /* the command failed, but update must continue */ + return 1; + } + - switch (ud->update_strategy.type) { -- case SM_UPDATE_CHECKOUT: -- printf(_("Submodule path '%s': checked out '%s'\n"), -- ud->displaypath, oid); -- break; -- case SM_UPDATE_REBASE: -- printf(_("Submodule path '%s': rebased into '%s'\n"), -- ud->displaypath, oid); -- break; -- case SM_UPDATE_MERGE: -- printf(_("Submodule path '%s': merged in '%s'\n"), -- ud->displaypath, oid); -- break; -- case SM_UPDATE_COMMAND: -- printf(_("Submodule path '%s': '%s %s'\n"), ++ if (ud->quiet) ++ return 0; ++ ++ switch (strategy.type) { + case SM_UPDATE_CHECKOUT: + printf(_("Submodule path '%s': checked out '%s'\n"), + ud->displaypath, oid); +@@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) + break; + case SM_UPDATE_COMMAND: + printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); -- break; -- default: -- BUG("unexpected update strategy type: %s", ++ ud->displaypath, strategy.command, oid); + break; + default: + BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); ++ submodule_strategy_to_string(&strategy)); } -+ strbuf_release(&out); return 0; } -static int do_run_update_procedure(struct update_data *ud) -+static int run_update_procedure(struct update_data *ud, struct string_list *err) ++static int run_update_procedure(struct update_data *ud) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_data *ud) - ud->displaypath, oid_to_hex(&ud->oid)); - } + return run_update_command(ud, subforce); + } -- return run_update_command(ud, subforce); --} -- -static void update_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ -- int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; - char *prefixed_path, *update = NULL; -- struct update_data update_data = UPDATE_DATA_INIT; +- struct update_data opt = UPDATE_DATA_INIT; - - struct option options[] = { -- OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), -- OPT__FORCE(&force, N_("force checkout updates"), 0), -- OPT_BOOL('N', "no-fetch", &nofetch, +- OPT__QUIET(&opt.quiet, +- N_("suppress output for update by rebase or merge")), +- OPT__FORCE(&opt.force, N_("force checkout updates"), +- 0), +- OPT_BOOL('N', "no-fetch", &opt.nofetch, - N_("don't fetch new objects from the remote site")), -- OPT_BOOL(0, "just-cloned", &just_cloned, +- OPT_BOOL(0, "just-cloned", &opt.just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), -- OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), +- OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), -- OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), +- OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), -- OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), +- OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), -- OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), +- OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - if (argc != 1) - usage_with_options(usage, options); - -- update_data.force = !!force; -- update_data.quiet = !!quiet; -- update_data.nofetch = !!nofetch; -- update_data.just_cloned = !!just_cloned; -- update_data.sm_path = argv[0]; +- opt.sm_path = argv[0]; - -- if (update_data.recursive_prefix) -- prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); +- if (opt.recursive_prefix) +- prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); - else -- prefixed_path = xstrdup(update_data.sm_path); +- prefixed_path = xstrdup(opt.sm_path); - -- update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); +- opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - -- determine_submodule_update_strategy(the_repository, update_data.just_cloned, -- update_data.sm_path, update, -- &update_data.update_strategy); +- determine_submodule_update_strategy(the_repository, opt.just_cloned, +- opt.sm_path, update, +- &opt.update_strategy); - - free(prefixed_path); - -- if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) -- return do_run_update_procedure(&update_data); +- if (!oideq(&opt.oid, &opt.suboid) || opt.force) +- return do_run_update_procedure(&opt); - - return 3; -} @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -+ return run_update_command(ud, subforce, err); - } - +-} +- static const char *remote_submodule_branch(const char *path) + { + const struct submodule *sub; @@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, const char *prefix) return 0; } @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; -+ struct string_list err = STRING_LIST_INIT_DUP; + + ensure_core_worktree(update_data->sm_path); + @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) -+ if (run_update_procedure(update_data, &err)) ++ if (run_update_procedure(update_data)) + return 1; + + if (update_data->recursive) { -+ int res; + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; -+ char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"), -+ update_data->displaypath); ++ int res; + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ -+ if ((res = run_command(&cp)) == 128) -+ die("%s", die_msg); -+ if (res) -+ string_list_append(&err, die_msg); -+ -+ free(die_msg); -+ } -+ -+ if (err.nr) { -+ struct string_list_item *item; -+ for_each_string_list_item(item, &err) -+ fputs(item->string, stderr); -+ string_list_clear(&err, 0); -+ return 1; ++ res = run_command(&cp); ++ if (!res) ++ return 0; ++ die_message(_("Failed to recurse into submodule path '%s'"), ++ update_data->displaypath); ++ if (res == 128) ++ exit(res); ++ else if (res) ++ return 1; + } + + return 0; -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v5 1/9] submodule--helper: get remote names from any repository 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 2/9] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason ` (8 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Helped-by: Glen Choo <chooglen@google.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c5d3fc3817f..4c7c1e1432d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,14 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + struct ref_store *store = get_main_ref_store(repo); + int ignore_errno; + const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL, + NULL, &ignore_errno); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +49,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +58,19 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + struct repository subrepo; + + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo); +} + +static char *get_default_remote(void) +{ + return repo_get_default_remote(the_repository); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1341,9 +1357,8 @@ static void sync_submodule(const char *path, const char *prefix, { const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; + char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1382,21 +1397,15 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + default_remote = get_default_remote_submodule(path); + if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); - strbuf_strip_suffix(&sb, "\n"); - remote_key = xstrfmt("remote.%s.url", sb.buf); + remote_key = xstrfmt("remote.%s.url", default_remote); + free(default_remote); - strbuf_reset(&sb); submodule_to_gitdir(&sb, path); strbuf_addstr(&sb, "/config"); -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 2/9] submodule--helper: refactor get_submodule_displaypath() 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 1/9] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 3/9] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason ` (7 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4c7c1e1432d..5efceb9d46c 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -261,11 +261,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -281,6 +278,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 3/9] submodule--helper: allow setting superprefix for init_submodule() 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 1/9] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 2/9] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 4/9] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason ` (6 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We allow callers of the `init_submodule()` function to optionally override the superprefix from the environment. We need to enable this option because in our conversion of the update command that will follow, the '--init' option will be handled through this API. We will need to change the superprefix at that time to ensure the display paths show correctly in the output messages. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5efceb9d46c..09cda67c1ea 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -606,18 +606,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -691,7 +695,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 4/9] submodule--helper: run update using child process struct 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (2 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 3/9] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 5/9] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason ` (5 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We switch to using the run-command API function that takes a 'struct child process', since we are using a lot of the options. This will also make it simple to switch over to using 'capture_command()' when we start handling the output of the command completely in C. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 09cda67c1ea..db71e6f4ec8 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2344,47 +2344,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str static int run_update_command(struct update_data *ud, int subforce) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - int git_cmd; switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.use_shell = 1; + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); + if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Unable to checkout '%s' in submodule path '%s'"), -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 5/9] builtin/submodule--helper.c: reformat designated initializers 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (3 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 4/9] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 6/9] builtin/submodule--helper.c: rename option variables to "opt" Ævar Arnfjörð Bjarmason ` (4 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> The second hunk here will make a subsequent commit's diff smaller, and let's do the first and third hunks while we're at it so that we consistently format all of these. Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index db71e6f4ec8..9f79bdf4d51 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1654,7 +1654,10 @@ struct module_clone_data { unsigned int require_init: 1; int single_branch; }; -#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 } +#define MODULE_CLONE_DATA_INIT { \ + .reference = STRING_LIST_INIT_NODUP, \ + .single_branch = -1, \ +} struct submodule_alternate_setup { const char *submodule_name; @@ -2047,7 +2050,9 @@ struct update_data { unsigned int nofetch: 1; unsigned int just_cloned: 1; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -3013,7 +3018,9 @@ struct add_data { unsigned int progress: 1; unsigned int dissociate: 1; }; -#define ADD_DATA_INIT { .depth = -1 } +#define ADD_DATA_INIT { \ + .depth = -1, \ +} static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) { -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 6/9] builtin/submodule--helper.c: rename option variables to "opt" 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (4 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 5/9] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 7/9] submodule--helper: don't use bitfield indirection for parse_options() Ævar Arnfjörð Bjarmason ` (3 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason Rename the "suc" variable in update_clone() to "opt", and do the same for the "update_data" variable in run_update_procedure(). The only reason for this change is to make the subsequent commit's diff smaller, by doing this rename we can "anchor" the diff better, as it "borrow" most of the options declared here as-is as far as the diff rename detection is concerned. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 74 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9f79bdf4d51..c2d4fd0347a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2517,36 +2517,36 @@ static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, + OPT_BOOL(0, "dissociate", &opt.dissociate, N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", + OPT_STRING(0, "depth", &opt.depth, "<depth>", N_("create a shallow clone truncated to the " "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, + OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, + OPT_BOOL(0, "require-init", &opt.require_init, N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, + OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() }; @@ -2555,32 +2555,32 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - suc.prefix = prefix; + opt.prefix = prefix; - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) + if (parse_submodule_update_strategy(update, &opt.update) < 0) die(_("bad value for update parameter")); - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) return 1; if (pathspec.nr) - suc.warn_if_uninitialized = 1; + opt.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_submodules(&opt); } static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; + struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2589,20 +2589,20 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) N_("don't fetch new objects from the remote site")), OPT_BOOL(0, "just-cloned", &just_cloned, N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), + OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), + OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), + OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, parse_opt_object_id), OPT_END() @@ -2618,27 +2618,27 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; + opt.force = !!force; + opt.quiet = !!quiet; + opt.nofetch = !!nofetch; + opt.just_cloned = !!just_cloned; + opt.sm_path = argv[0]; - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); + if (opt.recursive_prefix) + prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); else - prefixed_path = xstrdup(update_data.sm_path); + prefixed_path = xstrdup(opt.sm_path); - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); + opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); + determine_submodule_update_strategy(the_repository, opt.just_cloned, + opt.sm_path, update, + &opt.update_strategy); free(prefixed_path); - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + if (!oideq(&opt.oid, &opt.suboid) || opt.force) + return do_run_update_procedure(&opt); return 3; } -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 7/9] submodule--helper: don't use bitfield indirection for parse_options() 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (5 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 6/9] builtin/submodule--helper.c: rename option variables to "opt" Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 8/9] submodule tests: test for init and update failure output Ævar Arnfjörð Bjarmason ` (2 subsequent siblings) 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason Do away with the indirection of local variables added in c51f8f94e5b (submodule--helper: run update procedures from C, 2021-08-24). These were only needed because in C you can't get a pointer to a single bit, so we were using intermediate variables instead. This will also make a subsequent large commit's diff smaller. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c2d4fd0347a..4a0890954e9 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2045,10 +2045,10 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; - unsigned int force: 1; - unsigned int quiet: 1; - unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int force; + unsigned int quiet; + unsigned int nofetch; + unsigned int just_cloned; }; #define UPDATE_DATA_INIT { \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ @@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix) static int run_update_procedure(int argc, const char **argv, const char *prefix) { - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, + OPT__QUIET(&opt.quiet, + N_("suppress output for update by rebase or merge")), + OPT__FORCE(&opt.force, N_("force checkout updates"), + 0), + OPT_BOOL('N', "no-fetch", &opt.nofetch, N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, + OPT_BOOL(0, "just-cloned", &opt.just_cloned, N_("overrides update mode in case the repository is a fresh clone")), OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, @@ -2618,10 +2619,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - opt.force = !!force; - opt.quiet = !!quiet; - opt.nofetch = !!nofetch; - opt.just_cloned = !!just_cloned; opt.sm_path = argv[0]; if (opt.recursive_prefix) -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 8/9] submodule tests: test for init and update failure output 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (6 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 7/9] submodule--helper: don't use bitfield indirection for parse_options() Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 9/9] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo 9 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason Amend some submodule tests to test for the failure output of "git submodule [update|init]". The lack of such tests hid a regression in an earlier version of a subsequent commit. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- t/t7406-submodule-update.sh | 14 ++++++++++++-- t/t7408-submodule-reference.sh | 14 +++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 11cccbb333b..7764c1c3cb6 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' ' (cd submodule && compare_head ) && - test_must_fail git submodule update submodule - ) + test_must_fail git submodule update submodule 2>../actual.raw + ) && + sed "s/^> //" >expect <<-\EOF && + > error: Your local changes to the following files would be overwritten by checkout: + > file + > Please commit your changes or stash them before you switch branches. + > Aborting + > fatal: Unable to checkout OID in submodule path '\''submodule'\'' + EOF + sed -e "s/checkout $SQ[^$SQ]*$SQ/checkout OID/" <actual.raw >actual && + test_cmp expect actual + ' test_expect_success 'submodule update should throw away changes with --force ' ' (cd super && diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index a3892f494b6..c3a45455106 100755 --- a/t/t7408-submodule-reference.sh +++ b/t/t7408-submodule-reference.sh @@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul cd supersuper-clone && check_that_two_of_three_alternates_are_used && # update of the submodule fails - test_must_fail git submodule update --init --recursive + cat >expect <<-\EOF && + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\''. Retry scheduled + fatal: submodule '\''sub-dissociate'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub-dissociate'\''. Retry scheduled + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\'' a second time, aborting + fatal: Failed to recurse into submodule path ... + EOF + test_must_fail git submodule update --init --recursive 2>err && + grep -e fatal: -e ^Failed err >actual.raw && + sed -e "s/path $SQ[^$SQ]*$SQ/path .../" <actual.raw >actual && + test_cmp expect actual ) ' -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v5 9/9] submodule: move core cmd_update() logic to C 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (7 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 8/9] submodule tests: test for init and update failure output Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 ` Ævar Arnfjörð Bjarmason 2022-02-03 0:18 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo 9 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-01-28 12:56 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Glen Choo, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. We also introduce `update_submodules2()` and `update_submodule2()` which will supersede `update_submodules()` and `update_submodule()`. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call[1]. So we instead run the `init_submodule_cb()` callback over each submodule in the same process. While we are at it, we also remove the fetch_in_submodule() shell function since it is no longer used anywhere. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/submodule--helper.c | 599 +++++++++++++++++++++--------------- git-submodule.sh | 145 +-------- 2 files changed, 356 insertions(+), 388 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4a0890954e9..1c28b6f479c 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -71,21 +71,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -1965,29 +1950,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -2015,7 +1977,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -2038,6 +1999,7 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; @@ -2045,13 +2007,54 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; + int recommend_shallow; + int single_branch; + int max_jobs; + unsigned int init; unsigned int force; unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; + unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; + unsigned int require_init; + unsigned warn_if_uninitialized ; + struct string_list references; + struct module_list list; }; #define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } } static void next_submodule_warn_missing(struct submodule_update_clone *suc, @@ -2352,8 +2355,15 @@ static int run_update_command(struct update_data *ud, int subforce) struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - switch (ud->update_strategy.type) { + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; + + switch (strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-q", NULL); @@ -2376,55 +2386,54 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: cp.use_shell = 1; - strvec_push(&cp.args, ud->update_strategy.command); + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); if (run_command(&cp)) { - switch (ud->update_strategy.type) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); + die_message(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + + /* the command failed, but update must continue */ return 1; } - switch (ud->update_strategy.type) { + if (ud->quiet) + return 0; + + switch (strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), ud->displaypath, oid); @@ -2439,17 +2448,17 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); + ud->displaypath, strategy.command, oid); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int run_update_procedure(struct update_data *ud) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2479,178 +2488,6 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -static int update_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &opt.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &opt.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - opt.prefix = prefix; - - update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) - return 1; - - if (pathspec.nr) - opt.warn_if_uninitialized = 1; - - return update_submodules(&opt); -} - -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - char *prefixed_path, *update = NULL; - struct update_data opt = UPDATE_DATA_INIT; - - struct option options[] = { - OPT__QUIET(&opt.quiet, - N_("suppress output for update by rebase or merge")), - OPT__FORCE(&opt.force, N_("force checkout updates"), - 0), - OPT_BOOL('N', "no-fetch", &opt.nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &opt.just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - opt.sm_path = argv[0]; - - if (opt.recursive_prefix) - prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); - else - prefixed_path = xstrdup(opt.sm_path); - - opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, opt.just_cloned, - opt.sm_path, update, - &opt.update_strategy); - - free(prefixed_path); - - if (!oideq(&opt.oid, &opt.suboid) || opt.force) - return do_run_update_procedure(&opt); - - return 3; -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -2783,17 +2620,11 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void ensure_core_worktree(const char *path) { - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) die(_("could not get a repository handle for submodule '%s'"), path); @@ -2813,8 +2644,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } - - return 0; } static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ -3001,6 +2830,271 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) +{ + char *prefixed_path; + + ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if (fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + if (run_update_procedure(update_data)) + return 1; + + if (update_data->recursive) { + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + int res; + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + res = run_command(&cp); + if (!res) + return 0; + die_message(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + if (res == 128) + exit(res); + else if (res) + return 1; + } + + return 0; +} + +static int update_submodules(struct update_data *update_data) +{ + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, &suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc.quickstop) { + res = 1; + goto cleanup; + } + + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; + + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + +cleanup: + string_list_clear(&update_data->references, 0); + return res; +} + +static int module_update(int argc, const char **argv, const char *prefix) +{ + const char *update = NULL; + struct pathspec pathspec; + struct update_data opt = UPDATE_DATA_INIT; + + struct option module_update_clone_options[] = { + OPT__FORCE(&opt.force, N_("force checkout updates"), 0), + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &opt.recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &opt.prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &opt.dissociate, + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &opt.require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); + + if (update) + if (parse_submodule_update_strategy(update, + &opt.update_strategy) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) + return 1; + + if (pathspec.nr) + opt.warn_if_uninitialized = 1; + + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&opt); +} + struct add_data { const char *prefix; const char *branch; @@ -3388,16 +3482,11 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66a..bcd8b92aabd 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,20 +246,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -361,133 +347,26 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + ${GIT_QUIET:+--quiet} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 1 - then - subsha1= - else - just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" - fi - - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.35.0.914.ge5c8aab0d5b ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v5 9/9] submodule: move core cmd_update() logic to C 2022-01-28 12:56 ` [PATCH v5 9/9] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason @ 2022-02-03 0:18 ` Glen Choo 2022-02-03 2:26 ` Ævar Arnfjörð Bjarmason 0 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-03 0:18 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason, git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason I mentioned (out-of-mailing-list) that I was still looking at this, but that the big sh -> c conversion is quite challenging for me to parse personally. I'm still looking at it, but it will take some time.. I'm of the opinion that this patch would be a lot easier to review if it were broken up into more patches, but it has always looked like this [1]. The only real difference from [1] to this version is that this also removes all of the dead code, which doesn't really hinder reviewability. I don't think you have to go through the effort of splitting it up - after all you were able to review [1], so given enough time I should be able to read through this patch too :) That said, I wish that we already had a split up patch for at least 2 other reasons: - Junio pointed out that this conflicts with es/superproject-aware-submodules [2]. I'm not sure which should be based on which. If this does end up being based on es/superproject-aware-submodules, it would probably be easier to rebase as a series of smaller patches. Atharva noted that the conflicts are mild though, so maybe it's not so bad. - Besides making sure that the sh -> c is faithful, a thorough review should hopefully catch unintentional mistakes. The size of this patch makes such mistakes difficult to spot. For instance, here's something I spotted only after trying to split the patch myself.. > +static int module_update(int argc, const char **argv, const char *prefix) > +{ > + const char *update = NULL; > + struct pathspec pathspec; > + struct update_data opt = UPDATE_DATA_INIT; > + > + struct option module_update_clone_options[] = { [...] > + }; > + > + const char *const git_submodule_helper_usage[] = { > + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), > + NULL > + }; > + > + update_clone_config_from_gitmodules(&opt.max_jobs); > + git_config(git_update_clone_config, &opt.max_jobs); Notice that we copy-pasted the option parsing from update-clone into module_update() but forgot to update the names. My ideal patch organization would be something like: - wrap some existing command in "git submodule--helper update" (probably run-update-procedure) - absorb the surrounding sh code into "git submodule--helper update" one command at-a-time i.e. deprecating and removing the commands one at a time - instead of deprecating and removing them all at once (like this patch), or deprecating all at once and removing them one at a time (like v1). I don't know if it's feasible or not; Atharva noted upthread that there are some technical reasons why some things can be done in-process and some cannot, but it might be a useful exercise. Here's what I propose: - If you think this alternative organization would be helpful for you too, I will attempt it. This will take a while, but by the end you and I will have effectively reviewed all of the code, so it should be easy to finish up the review. - Otherwise e.g. maybe this is a huge waste of time, or you're already really confident in the correctness of the sh -> c when you reviewed the original patch, etc, I'll just review this patch as-is. I'd appreciate any tips and tricks that might help :) - Orthogonal to patch organization, I'm still not sure if this will be rebased on es/superproject-aware-submodules or vice-versa, and I don't want either of us to sink too much effort before knowing the answer. [1] https://lore.kernel.org/git/20210907115932.36068-7-raykar.ath@gmail.com/ [2] https://lore.kernel.org/git/YWiXL+plA7GHfuVv@google.com/ ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v5 9/9] submodule: move core cmd_update() logic to C 2022-02-03 0:18 ` Glen Choo @ 2022-02-03 2:26 ` Ævar Arnfjörð Bjarmason 2022-02-03 8:15 ` Ævar Arnfjörð Bjarmason 0 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-03 2:26 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Wed, Feb 02 2022, Glen Choo wrote: > - Junio pointed out that this conflicts with > es/superproject-aware-submodules [2]. I'm not sure which should be > based on which. If this does end up being based on > es/superproject-aware-submodules, it would probably be easier to > rebase as a series of smaller patches. Atharva noted that the > conflicts are mild though, so maybe it's not so bad. I think it makes sense to get this series through first, i.e. the (supposedly) no-behavior-changing one, and then one that introduces new submodule behavior. Particularly because for es/superproject-aware-submodules the main selling point is a performance improvement, which as I noted in the review for it I've been unable to observe once the C<->sh layer goes away. I'm not saying it's not there, just that I don't think it's been shown so far, IIRC there was some reference to some Google-internal network FS that might or might not be helped by it... > - Besides making sure that the sh -> c is faithful, a thorough review > should hopefully catch unintentional mistakes. The size of this patch > makes such mistakes difficult to spot. For instance, here's something > I spotted only after trying to split the patch myself.. > > > +static int module_update(int argc, const char **argv, const char *prefix) > > +{ > > + const char *update = NULL; > > + struct pathspec pathspec; > > + struct update_data opt = UPDATE_DATA_INIT; > > + > > + struct option module_update_clone_options[] = { > [...] > > + }; > > + > > + const char *const git_submodule_helper_usage[] = { > > + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), > > + NULL > > + }; > > + > > + update_clone_config_from_gitmodules(&opt.max_jobs); > > + git_config(git_update_clone_config, &opt.max_jobs); > > Notice that we copy-pasted the option parsing from update-clone into > module_update() but forgot to update the names. > > My ideal patch organization would be something like: > > - wrap some existing command in "git submodule--helper update" (probably > run-update-procedure) > - absorb the surrounding sh code into "git submodule--helper > update" one command at-a-time i.e. deprecating and removing the > commands one at a time - instead of deprecating and removing them all > at once (like this patch), or deprecating all at once and removing > them one at a time (like v1). I do think atomic changes that don't leave dead code for removal later are easier to read & reason about, whatever else is reorganized. I.e. not to have something where we replace all the running code, and then remove already-unused code later. On that topic, I noticed this series could/should have [1] fixed up into it. > - If you think this alternative organization would be helpful for you > too, I will attempt it. This will take a while, but by the end you and > I will have effectively reviewed all of the code, so it should be easy > to finish up the review. I think it might, but I really don't know. We'll just have to see, so if you want to take a stab at it that would be great. Maybe it's a good way forward. E.g. as af first small step we could turn: while read -r quickabort sha1 just_cloned sm_path [...] die_if_unmatched "$quickabort" "$sha1" into version where we fold that die_if_unmatched() logic into the C code, and then ensure-core-worktree etc. > - Otherwise e.g. maybe this is a huge waste of time, or you're already > really confident in the correctness of the sh -> c when you reviewed > the original patch, etc, I'll just review this patch as-is. I'd > appreciate any tips and tricks that might help :) I'm not really confident in it. I've read it, tested it as well as I could manage etc. but it's still a very large change. 1. diff --git a/git-sh-setup.sh b/git-sh-setup.sh index b93f39288ce..756c2a67c72 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -286,13 +286,6 @@ get_author_ident_from_commit () { parse_ident_from_commit author AUTHOR } -# Clear repo-local GIT_* environment variables. Useful when switching to -# another repository (e.g. when entering a submodule). See also the env -# list in git_connect() -clear_local_git_env() { - unset $(git rev-parse --local-env-vars) -} - # Generate a virtual base file for a two-file merge. Uses git apply to # remove lines from $1 that are not in $2, leaving only common lines. create_virtual_base() { diff --git a/git-submodule.sh b/git-submodule.sh index bcd8b92aabd..6c91b9e2403 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -50,30 +50,11 @@ single_branch= jobs= recommend_shallow= -die_if_unmatched () -{ - if test "$1" = "#unmatched" - then - exit ${2:-1} - fi -} - isnumber() { n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1" } -# Sanitize the local git environment for use within a submodule. We -# can't simply use clear_local_git_env since we want to preserve some -# of the settings from GIT_CONFIG_PARAMETERS. -sanitize_submodule_env() -{ - save_config=$GIT_CONFIG_PARAMETERS - clear_local_git_env - GIT_CONFIG_PARAMETERS=$save_config - export GIT_CONFIG_PARAMETERS -} - # # Add a new submodule to the working tree, .gitmodules and the index # ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v5 9/9] submodule: move core cmd_update() logic to C 2022-02-03 2:26 ` Ævar Arnfjörð Bjarmason @ 2022-02-03 8:15 ` Ævar Arnfjörð Bjarmason 2022-02-03 17:35 ` Glen Choo 0 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-03 8:15 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 03 2022, Ævar Arnfjörð Bjarmason wrote: > On Wed, Feb 02 2022, Glen Choo wrote: > >> - Junio pointed out that this conflicts with >> es/superproject-aware-submodules [2]. I'm not sure which should be >> based on which. If this does end up being based on >> es/superproject-aware-submodules, it would probably be easier to >> rebase as a series of smaller patches. Atharva noted that the >> conflicts are mild though, so maybe it's not so bad. > > I think it makes sense to get this series through first, i.e. the > (supposedly) no-behavior-changing one, and then one that introduces new > submodule behavior. > > Particularly because for es/superproject-aware-submodules the main > selling point is a performance improvement, which as I noted in the > review for it I've been unable to observe once the C<->sh layer goes > away. > > I'm not saying it's not there, just that I don't think it's been shown > so far, IIRC there was some reference to some Google-internal network FS > that might or might not be helped by it... > >> - Besides making sure that the sh -> c is faithful, a thorough review >> should hopefully catch unintentional mistakes. The size of this patch >> makes such mistakes difficult to spot. For instance, here's something >> I spotted only after trying to split the patch myself.. >> >> > +static int module_update(int argc, const char **argv, const char *prefix) >> > +{ >> > + const char *update = NULL; >> > + struct pathspec pathspec; >> > + struct update_data opt = UPDATE_DATA_INIT; >> > + >> > + struct option module_update_clone_options[] = { >> [...] >> > + }; >> > + >> > + const char *const git_submodule_helper_usage[] = { >> > + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), >> > + NULL >> > + }; >> > + >> > + update_clone_config_from_gitmodules(&opt.max_jobs); >> > + git_config(git_update_clone_config, &opt.max_jobs); >> >> Notice that we copy-pasted the option parsing from update-clone into >> module_update() but forgot to update the names. >> >> My ideal patch organization would be something like: >> >> - wrap some existing command in "git submodule--helper update" (probably >> run-update-procedure) >> - absorb the surrounding sh code into "git submodule--helper >> update" one command at-a-time i.e. deprecating and removing the >> commands one at a time - instead of deprecating and removing them all >> at once (like this patch), or deprecating all at once and removing >> them one at a time (like v1). > > I do think atomic changes that don't leave dead code for removal later > are easier to read & reason about, whatever else is reorganized. > > I.e. not to have something where we replace all the running code, and > then remove already-unused code later. > > On that topic, I noticed this series could/should have [1] fixed up into > it. > >> - If you think this alternative organization would be helpful for you >> too, I will attempt it. This will take a while, but by the end you and >> I will have effectively reviewed all of the code, so it should be easy >> to finish up the review. > > I think it might, but I really don't know. We'll just have to see, so if > you want to take a stab at it that would be great. > > Maybe it's a good way forward. E.g. as af first small step we could turn: > > while read -r quickabort sha1 just_cloned sm_path > [...] > die_if_unmatched "$quickabort" "$sha1" > > into version where we fold that die_if_unmatched() logic into the C > code, and then ensure-core-worktree etc. Sorry, that one makes no sense since it's an artifact of the shellscript implementation. But I tested the below on top of master, and it passes all tests, which isn't very promising... diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4a0890954e9..e749008f13a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2783,40 +2783,6 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) -{ - const char *path; - const char *cw; - struct repository subrepo; - - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) - die(_("could not get a repository handle for submodule '%s'"), path); - - if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) { - char *cfg_file, *abs_path; - const char *rel_path; - struct strbuf sb = STRBUF_INIT; - - cfg_file = repo_git_path(&subrepo, "config"); - - abs_path = absolute_pathdup(path); - rel_path = relative_path(abs_path, subrepo.gitdir, &sb); - - git_config_set_in_file(cfg_file, "core.worktree", rel_path); - - free(cfg_file); - free(abs_path); - strbuf_release(&sb); - } - - return 0; -} - static int absorb_git_dirs(int argc, const char **argv, const char *prefix) { int i; @@ -3391,7 +3357,6 @@ static struct cmd_struct commands[] = { {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66a..460cbd4e265 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -387,8 +387,6 @@ cmd_update() do die_if_unmatched "$quickabort" "$sha1" - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") if test $just_cloned -eq 1 ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v5 9/9] submodule: move core cmd_update() logic to C 2022-02-03 8:15 ` Ævar Arnfjörð Bjarmason @ 2022-02-03 17:35 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-03 17:35 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Thu, Feb 03 2022, Ævar Arnfjörð Bjarmason wrote: > >> On Wed, Feb 02 2022, Glen Choo wrote: >> >>> - Junio pointed out that this conflicts with >>> es/superproject-aware-submodules [2]. I'm not sure which should be >>> based on which. If this does end up being based on >>> es/superproject-aware-submodules, it would probably be easier to >>> rebase as a series of smaller patches. Atharva noted that the >>> conflicts are mild though, so maybe it's not so bad. >> >> I think it makes sense to get this series through first, i.e. the >> (supposedly) no-behavior-changing one, and then one that introduces new >> submodule behavior. >> >> Particularly because for es/superproject-aware-submodules the main >> selling point is a performance improvement, which as I noted in the >> review for it I've been unable to observe once the C<->sh layer goes >> away. >> >> I'm not saying it's not there, just that I don't think it's been shown >> so far, IIRC there was some reference to some Google-internal network FS >> that might or might not be helped by it... I'll let the experts chime in, I don't think I can add anything useful to the discussion. >>> My ideal patch organization would be something like: >>> >>> - wrap some existing command in "git submodule--helper update" (probably >>> run-update-procedure) >>> - absorb the surrounding sh code into "git submodule--helper >>> update" one command at-a-time i.e. deprecating and removing the >>> commands one at a time - instead of deprecating and removing them all >>> at once (like this patch), or deprecating all at once and removing >>> them one at a time (like v1). >> >> I do think atomic changes that don't leave dead code for removal later >> are easier to read & reason about, whatever else is reorganized. >> >> I.e. not to have something where we replace all the running code, and >> then remove already-unused code later. I agree - otherwise patches aren't self-contianed and harder to merge. >>> - If you think this alternative organization would be helpful for you >>> too, I will attempt it. This will take a while, but by the end you and >>> I will have effectively reviewed all of the code, so it should be easy >>> to finish up the review. >> >> I think it might, but I really don't know. We'll just have to see, so if >> you want to take a stab at it that would be great. >> >> Maybe it's a good way forward. E.g. as af first small step we could turn: >> >> while read -r quickabort sha1 just_cloned sm_path >> [...] >> die_if_unmatched "$quickabort" "$sha1" >> >> into version where we fold that die_if_unmatched() logic into the C >> code, and then ensure-core-worktree etc. > > Sorry, that one makes no sense since it's an artifact of the shellscript > implementation. Whether or not it makes sense, I think it gets the point across i.e. that we think folding into C can be done incrementally. >>> - Otherwise e.g. maybe this is a huge waste of time, or you're already >>> really confident in the correctness of the sh -> c when you reviewed >>> the original patch, etc, I'll just review this patch as-is. I'd >>> appreciate any tips and tricks that might help :) >> >> I'm not really confident in it. >> >> I've read it, tested it as well as I could manage etc. but it's still a >> very large change. [...] > But I tested the below on top of master, and it passes all tests, which > isn't very promising... A good enough (i.e. extremely comprehensive) test suite will all but guarantee that no behavior has changed. Our test suite is nowhere near that level and probably never will be, so we can't trust that things are correct even if it passes tests. So, for the sake of reviewability, I'll take a stab at reorganizing. I'll be taking a long flight anyway, so I'll have big chunk of non-company time to spend on this ;) ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v6 00/16] submodule: convert the rest of 'update' to C 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason ` (8 preceding siblings ...) 2022-01-28 12:56 ` [PATCH v5 9/9] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 01/16] submodule--helper: get remote names from any repository Glen Choo ` (16 more replies) 9 siblings, 17 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Here is a split-up of the last patch as I promised :) The intent was to minimize the diff vs v5 instead of getting to a perfect end state; this will almost certainly need a reroll. This split-up isn't as complete as I had hoped - the last patch is still rather large, but breaking that up already took more time than everything else combined, and I think this organization is already easier to review than v5. I'd appreciate any suggestions on how this could be done [1] :) If inspiration strikes, I'll break it up further in a reroll, but as of right now, I'm out of ideas. I did some minimal review of the implementation, but I plan to do more after sending this to the list e.g. I have not revisited the earlier preparatory patches to see if my patches make sense with them. Where I found issues, I left NEEDSWORK comments instead of fixing them because the result would be easier to diff with v5 (the only differences between this tree and v5's is the NEEDSWORK comments). I plan to fix implementation issues (once we've spotted them in reivew) and the NEEDSWORKs in the next reroll. Let me know if the trailers make sense - this is my first time reworking someone else's changes, so I don't think I did a perfect job at attributing work. I also had to fiddle with the Signed-off-by to make them resemble the v5 patches' Signed-off-by (ar/submodule-update seemed to order them differently from v5, I'm not sure why). [1] The difficulty in the last patch comes from the fact that we have the --recursive flag handling in shell, and we are piping update-clone into {run-update-procedure + --recursive flag handling}. Because of how "git submodule" parses args, it is tricky to implement --recursive without bypassing "git submodule" with "git submodule--helper update" (the final patch does this bypass). On the other hand, it's difficult to leave --recursive for last, because we would need to mimic the piping and exiting behavior around update-clone and run-update-procedure. Changes in v6: - Split up last patch of v5 into patches 9-16. - Patches 9-10 are preparatory work on submodule--helper.c. - Patches 11-14 contain sh -> c conversions of the git-submodule.sh code surrounding update-clone and run-update-procedure. - Patch 15 moves functions around in order to shrink patch 16's diff - If reviewers prefer, we could choose _not_ to move the functions around. If so, we can drop patch 15. - Patch 16 introduces "submodule--helper update". Change the commit message to drop references to work done in previous patches. - Add NEEDSWORK comments for potential issues. These will be cleaned up in the next version. Atharva Raykar (6): submodule--helper: get remote names from any repository submodule--helper: refactor get_submodule_displaypath() submodule--helper: allow setting superprefix for init_submodule() submodule--helper: run update using child process struct builtin/submodule--helper.c: reformat designated initializers submodule: move core cmd_update() logic to C Glen Choo (7): submodule--helper: remove update-module-mode submodule--helper: reorganize code for sh to C conversion submodule--helper run-update-procedure: remove --suboid submodule--helper run-update-procedure: learn --remote submodule--helper: remove ensure-core-worktree submodule--helper update-clone: learn --init submodule--helper: move functions around Ævar Arnfjörð Bjarmason (3): builtin/submodule--helper.c: rename option variables to "opt" submodule--helper: don't use bitfield indirection for parse_options() submodule tests: test for init and update failure output builtin/submodule--helper.c | 709 +++++++++++++++++++-------------- git-submodule.sh | 145 +------ t/t7406-submodule-update.sh | 14 +- t/t7408-submodule-reference.sh | 14 +- 4 files changed, 447 insertions(+), 435 deletions(-) Range-diff against v5: 1: b45e49810a = 1: 86ffb53742 submodule--helper: get remote names from any repository 2: 8974329fc5 = 2: 2a40266b7a submodule--helper: refactor get_submodule_displaypath() 3: bd92e00c05 = 3: cd851c8eb5 submodule--helper: allow setting superprefix for init_submodule() 4: 909cb60cd4 = 4: bfe5cad136 submodule--helper: run update using child process struct 5: 36575b2f25 = 5: 72c257fdbf builtin/submodule--helper.c: reformat designated initializers 6: a743003e09 = 6: 4b5f703fde builtin/submodule--helper.c: rename option variables to "opt" 7: 3a449d00b9 = 7: f1d21f5b1c submodule--helper: don't use bitfield indirection for parse_options() 8: 7da45dde67 = 8: 9d32a73fc3 submodule tests: test for init and update failure output -: ---------- > 9: 087bf43aba submodule--helper: remove update-module-mode -: ---------- > 10: 4eb2893a19 submodule--helper: reorganize code for sh to C conversion -: ---------- > 11: c08e7781e3 submodule--helper run-update-procedure: remove --suboid -: ---------- > 12: 2419c37184 submodule--helper run-update-procedure: learn --remote -: ---------- > 13: 6691fd3648 submodule--helper: remove ensure-core-worktree -: ---------- > 14: d2c9c356e9 submodule--helper update-clone: learn --init -: ---------- > 15: a5cde5e084 submodule--helper: move functions around 9: 251a0b4241 ! 16: f0551a37e5 submodule: move core cmd_update() logic to C @@ Commit message `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. - We also introduce `update_submodules2()` and `update_submodule2()` - which will supersede `update_submodules()` and `update_submodule()`. - - When the `--init` flag is passed to the subcommand, we do not spawn a - new subprocess and call `submodule--helper init` on the submodule paths, - because the Git machinery is not able to pick up the configuration - changes introduced by that init call[1]. So we instead run the - `init_submodule_cb()` callback over each submodule in the same process. - - While we are at it, we also remove the fetch_in_submodule() shell - function since it is no longer used anywhere. - - [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ - Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> + Signed-off-by: Glen Choo <chooglen@google.com> ## builtin/submodule--helper.c ## -@@ builtin/submodule--helper.c: static char *get_default_remote(void) - return repo_get_default_remote(the_repository); - } - --static int print_default_remote(int argc, const char **argv, const char *prefix) --{ -- char *remote; -- -- if (argc != 1) -- die(_("submodule--helper print-default-remote takes no arguments")); -- -- remote = get_default_remote(); -- if (remote) -- printf("%s\n", remote); -- -- free(remote); -- return 0; --} -- - static int starts_with_dot_slash(const char *str) - { - return str[0] == '.' && is_dir_sep(str[1]); -@@ builtin/submodule--helper.c: static void determine_submodule_update_strategy(struct repository *r, - free(key); - } - --static int module_update_module_mode(int argc, const char **argv, const char *prefix) --{ -- const char *path, *update = NULL; -- int just_cloned; -- struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; -- -- if (argc < 3 || argc > 4) -- die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); -- -- just_cloned = git_config_int("just_cloned", argv[1]); -- path = argv[2]; -- -- if (argc == 4) -- update = argv[3]; -- -- determine_submodule_update_strategy(the_repository, -- just_cloned, path, update, -- &update_strategy); -- fputs(submodule_strategy_to_string(&update_strategy), stdout); -- -- return 0; --} -- - struct update_clone_data { - const struct submodule *sub; - struct object_id oid; @@ builtin/submodule--helper.c: struct submodule_update_clone { const char *prefix; int single_branch; @@ builtin/submodule--helper.c: struct submodule_update_clone { struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; +@@ builtin/submodule--helper.c: struct submodule_update_clone { + int failed_clones_nr, failed_clones_alloc; + + int max_jobs; +- unsigned int init; + }; + #define SUBMODULE_UPDATE_CLONE_INIT { \ + .list = MODULE_LIST_INIT, \ @@ builtin/submodule--helper.c: struct submodule_update_clone { } @@ builtin/submodule--helper.c: struct update_data { unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; -+ unsigned int remote; + unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - -- switch (ud->update_strategy.type) { ++ + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; -+ + +- switch (ud->update_strategy.type) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - ucd->sub->path); -} - --static int update_submodules(struct submodule_update_clone *suc) --{ -- int i; -- -- run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, -- update_clone_start_failure, -- update_clone_task_finished, suc, "submodule", -- "parallel/update"); -- -- /* -- * We saved the output and put it out all at once now. -- * That means: -- * - the listener does not have to interleave their (checkout) -- * work with our fetching. The writes involved in a -- * checkout involve more straightforward sequential I/O. -- * - the listener can avoid doing any work if fetching failed. -- */ -- if (suc->quickstop) -- return 1; -- -- for (i = 0; i < suc->update_clone_nr; i++) -- update_submodule(&suc->update_clone[i]); -- -- return 0; --} -- --static int update_clone(int argc, const char **argv, const char *prefix) --{ -- const char *update = NULL; -- struct pathspec pathspec; -- struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; -- -- struct option module_update_clone_options[] = { -- OPT_STRING(0, "prefix", &prefix, -- N_("path"), -- N_("path into the working tree")), -- OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, -- N_("path"), -- N_("path into the working tree, across nested " -- "submodule boundaries")), -- OPT_STRING(0, "update", &update, -- N_("string"), -- N_("rebase, merge, checkout or none")), -- OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), -- N_("reference repository")), -- OPT_BOOL(0, "dissociate", &opt.dissociate, -- N_("use --reference only while cloning")), -- OPT_STRING(0, "depth", &opt.depth, "<depth>", -- N_("create a shallow clone truncated to the " -- "specified number of revisions")), -- OPT_INTEGER('j', "jobs", &opt.max_jobs, -- N_("parallel jobs")), -- OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, -- N_("whether the initial clone should follow the shallow recommendation")), -- OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), -- OPT_BOOL(0, "progress", &opt.progress, -- N_("force cloning progress")), -- OPT_BOOL(0, "require-init", &opt.require_init, -- N_("disallow cloning into non-empty directory")), -- OPT_BOOL(0, "single-branch", &opt.single_branch, -- N_("clone only one branch, HEAD or --branch")), -- OPT_END() -- }; -- -- const char *const git_submodule_helper_usage[] = { -- N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), -- NULL -- }; -- opt.prefix = prefix; -- -- update_clone_config_from_gitmodules(&opt.max_jobs); -- git_config(git_update_clone_config, &opt.max_jobs); -- -- argc = parse_options(argc, argv, prefix, module_update_clone_options, -- git_submodule_helper_usage, 0); -- -- if (update) -- if (parse_submodule_update_strategy(update, &opt.update) < 0) -- die(_("bad value for update parameter")); -- -- if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) -- return 1; -- -- if (pathspec.nr) -- opt.warn_if_uninitialized = 1; -- -- return update_submodules(&opt); --} -- +-/* +- * NEEDSWORK: Use a forward declaration to avoid moving +- * run_update_procedure() (which will be removed soon). +- */ +-static int update_submodule2(struct update_data *update_data); -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - char *prefixed_path, *update = NULL; @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), -- OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), -- N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, -- parse_opt_object_id), +- OPT_BOOL(0, "remote", &opt.remote, +- N_("use SHA-1 of submodule's remote tracking branch")), - OPT_END() - }; - @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - &opt.update_strategy); - - free(prefixed_path); -- -- if (!oideq(&opt.oid, &opt.suboid) || opt.force) -- return do_run_update_procedure(&opt); -- -- return 3; +- return update_submodule2(&opt); -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; -@@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv, const char *prefix) - return 0; - } - --static int ensure_core_worktree(int argc, const char **argv, const char *prefix) -+static void ensure_core_worktree(const char *path) - { -- const char *path; - const char *cw; - struct repository subrepo; - -- if (argc != 2) -- BUG("submodule--helper ensure-core-worktree <path>"); -- -- path = argv[1]; -- - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) - die(_("could not get a repository handle for submodule '%s'"), path); - -@@ builtin/submodule--helper.c: static int ensure_core_worktree(int argc, const char **argv, const char *prefix) - free(abs_path); - strbuf_release(&sb); - } -- -- return 0; - } - - static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +-/* NEEDSWORK: this is a temporary name until we delete update_submodule() */ +-static int update_submodule2(struct update_data *update_data) +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * +} + +static int update_submodule(struct update_data *update_data) -+{ + { + char *prefixed_path; + -+ ensure_core_worktree(update_data->sm_path); -+ + ensure_core_worktree(update_data->sm_path); + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + update_data->prefix); + free(prefixed_path); + -+ if (update_data->just_cloned) { -+ oidcpy(&update_data->suboid, null_oid()); -+ } else { -+ if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) -+ die(_("Unable to find current revision in submodule path '%s'"), -+ update_data->displaypath); -+ } -+ -+ if (update_data->remote) { -+ char *remote_name = get_default_remote_submodule(update_data->sm_path); -+ const char *branch = remote_submodule_branch(update_data->sm_path); -+ char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); -+ -+ if (!update_data->nofetch) { -+ if (fetch_in_submodule(update_data->sm_path, update_data->depth, -+ 0, NULL)) -+ die(_("Unable to fetch in submodule path '%s'"), -+ update_data->sm_path); -+ } -+ -+ if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) -+ die(_("Unable to find %s revision in submodule path '%s'"), -+ remote_ref, update_data->sm_path); -+ -+ free(remote_ref); -+ } -+ -+ if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + /* NEEDSWORK: fix the style issues e.g. braces */ + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); +@@ builtin/submodule--helper.c: static int update_submodule2(struct update_data *update_data) + } + + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) +- return do_run_update_procedure(update_data); + if (run_update_procedure(update_data)) + return 1; -+ + +- return 3; + if (update_data->recursive) { + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + } + + return 0; -+} -+ + } + +-static int update_submodules(struct submodule_update_clone *suc) +static int update_submodules(struct update_data *update_data) -+{ + { +- int i; + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; -+ + +- run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, -+ update_clone_start_failure, + update_clone_start_failure, +- update_clone_task_finished, suc, "submodule", + update_clone_task_finished, &suc, "submodule", -+ "parallel/update"); -+ -+ /* -+ * We saved the output and put it out all at once now. -+ * That means: -+ * - the listener does not have to interleave their (checkout) -+ * work with our fetching. The writes involved in a -+ * checkout involve more straightforward sequential I/O. -+ * - the listener can avoid doing any work if fetching failed. -+ */ + "parallel/update"); + + /* +@@ builtin/submodule--helper.c: static int update_submodules(struct submodule_update_clone *suc) + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ +- if (suc->quickstop) +- return 1; + if (suc.quickstop) { + res = 1; + goto cleanup; + } -+ + +- for (i = 0; i < suc->update_clone_nr; i++) +- update_submodule(&suc->update_clone[i]); + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; -+ + +- return 0; + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * +cleanup: + string_list_clear(&update_data->references, 0); + return res; -+} -+ + } + +-static int update_clone(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix) -+{ -+ const char *update = NULL; -+ struct pathspec pathspec; + { + const char *update = NULL; + struct pathspec pathspec; +- struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + struct update_data opt = UPDATE_DATA_INIT; -+ -+ struct option module_update_clone_options[] = { + ++ /* NEEDSWORK: update names and strings */ + struct option module_update_clone_options[] = { + OPT__FORCE(&opt.force, N_("force checkout updates"), 0), -+ OPT_BOOL(0, "init", &opt.init, -+ N_("initialize uninitialized submodules before update")), + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), +- OPT_STRING(0, "prefix", &prefix, + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &opt.recursive, @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &opt.prefix, -+ N_("path"), -+ N_("path into the working tree")), -+ OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, -+ N_("path"), -+ N_("path into the working tree, across nested " -+ "submodule boundaries")), -+ OPT_STRING(0, "update", &update, -+ N_("string"), -+ N_("rebase, merge, checkout or none")), -+ OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, +@@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv, const char *prefix) + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), +- N_("reference repository")), + N_("reference repository")), -+ OPT_BOOL(0, "dissociate", &opt.dissociate, + OPT_BOOL(0, "dissociate", &opt.dissociate, +- N_("use --reference only while cloning")), +- OPT_STRING(0, "depth", &opt.depth, "<depth>", +- N_("create a shallow clone truncated to the " +- "specified number of revisions")), + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), -+ OPT_INTEGER('j', "jobs", &opt.max_jobs, -+ N_("parallel jobs")), -+ OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, +- N_("whether the initial clone should follow the shallow recommendation")), + N_("whether the initial clone should follow the shallow recommendation")), -+ OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), -+ OPT_BOOL(0, "progress", &opt.progress, + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, +- N_("force cloning progress")), + N_("force cloning progress")), -+ OPT_BOOL(0, "require-init", &opt.require_init, + OPT_BOOL(0, "require-init", &opt.require_init, +- N_("disallow cloning into non-empty directory")), + N_("disallow cloning into non-empty directory")), -+ OPT_BOOL(0, "single-branch", &opt.single_branch, -+ N_("clone only one branch, HEAD or --branch")), -+ OPT_END() -+ }; -+ -+ const char *const git_submodule_helper_usage[] = { -+ N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), -+ NULL -+ }; -+ -+ update_clone_config_from_gitmodules(&opt.max_jobs); -+ git_config(git_update_clone_config, &opt.max_jobs); -+ -+ argc = parse_options(argc, argv, prefix, module_update_clone_options, -+ git_submodule_helper_usage, 0); + OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() +@@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv, const char *prefix) + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; +- opt.prefix = prefix; + + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); -+ -+ if (update) + + if (update) +- if (parse_submodule_update_strategy(update, &opt.update) < 0) + if (parse_submodule_update_strategy(update, + &opt.update_strategy) < 0) -+ die(_("bad value for update parameter")); -+ -+ if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) -+ return 1; -+ -+ if (pathspec.nr) -+ opt.warn_if_uninitialized = 1; -+ -+ if (opt.init) { -+ struct module_list list = MODULE_LIST_INIT; -+ struct init_cb info = INIT_CB_INIT; -+ -+ if (module_list_compute(argc, argv, opt.prefix, -+ &pathspec, &list) < 0) -+ return 1; -+ -+ /* -+ * If there are no path args and submodule.active is set then, -+ * by default, only initialize 'active' modules. -+ */ -+ if (!argc && git_config_get_value_multi("submodule.active")) -+ module_list_active(&list); -+ -+ info.prefix = opt.prefix; -+ info.superprefix = opt.recursive_prefix; -+ if (opt.quiet) -+ info.flags |= OPT_QUIET; -+ -+ for_each_listed_submodule(&list, init_submodule_cb, &info); -+ } -+ -+ return update_submodules(&opt); -+} -+ - struct add_data { - const char *prefix; - const char *branch; + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, -- {"update-module-mode", module_update_module_mode, 0}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, -- {"ensure-core-worktree", ensure_core_worktree, 0}, - {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, - {"status", module_status, SUPPORT_SUPER_PREFIX}, -- {"print-default-remote", print_default_remote, 0}, - {"sync", module_sync, SUPPORT_SUPER_PREFIX}, - {"deinit", module_deinit, 0}, - {"summary", module_summary, SUPPORT_SUPER_PREFIX}, ## git-submodule.sh ## -@@ git-submodule.sh: cmd_deinit() - git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" - } - --# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] --# Because arguments are positional, use an empty string to omit <depth> --# but include <sha1>. --fetch_in_submodule () ( -- sanitize_submodule_env && -- cd "$1" && -- if test $# -eq 3 -- then -- echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} -- else -- git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} -- fi --) -- - # - # Update each submodule path to correct revision, using clone and checkout as needed - # @@ git-submodule.sh: cmd_update() shift done -- if test -n "$init" -- then -- cmd_init "--" "$@" || return -- fi -- - { -- git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ -- ${progress:+"--progress"} \ +- git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ -+ ${GIT_QUIET:+--quiet} \ + ${GIT_QUIET:+--quiet} \ +- ${progress:+"--progress"} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ -+ ${init:+--init} \ + ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ @@ git-submodule.sh: cmd_update() - do - die_if_unmatched "$quickabort" "$sha1" - -- git submodule--helper ensure-core-worktree "$sm_path" || exit 1 -- - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - -- if test $just_cloned -eq 1 +- if test $just_cloned -eq 0 - then -- subsha1= -- else - just_cloned= -- subsha1=$(sanitize_submodule_env; cd "$sm_path" && -- git rev-parse --verify HEAD) || -- die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" -- fi -- -- if test -n "$remote" -- then -- branch=$(git submodule--helper remote-branch "$sm_path") -- if test -z "$nofetch" -- then -- # Fetch remote before determining tracking $sha1 -- fetch_in_submodule "$sm_path" $depth || -- die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" -- fi -- remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) -- sha1=$(sanitize_submodule_env; cd "$sm_path" && -- git rev-parse --verify "${remote_name}/${branch}") || -- die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - - out=$(git submodule--helper run-update-procedure \ @@ git-submodule.sh: cmd_update() - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ -- ${subsha1:+--suboid "$subsha1"} \ +- ${remote:+--remote} \ - "--" \ - "$sm_path") - base-commit: b23dac905bde28da47543484320db16312c87551 -- 2.33.GIT ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v6 01/16] submodule--helper: get remote names from any repository 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 02/16] submodule--helper: refactor get_submodule_displaypath() Glen Choo ` (15 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Helped-by: Glen Choo <chooglen@google.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c5d3fc3817..4c7c1e1432 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,14 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + struct ref_store *store = get_main_ref_store(repo); + int ignore_errno; + const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL, + NULL, &ignore_errno); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +49,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +58,19 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + struct repository subrepo; + + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo); +} + +static char *get_default_remote(void) +{ + return repo_get_default_remote(the_repository); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1341,9 +1357,8 @@ static void sync_submodule(const char *path, const char *prefix, { const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; + char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1382,21 +1397,15 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + default_remote = get_default_remote_submodule(path); + if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); - strbuf_strip_suffix(&sb, "\n"); - remote_key = xstrfmt("remote.%s.url", sb.buf); + remote_key = xstrfmt("remote.%s.url", default_remote); + free(default_remote); - strbuf_reset(&sb); submodule_to_gitdir(&sb, path); strbuf_addstr(&sb, "/config"); -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 02/16] submodule--helper: refactor get_submodule_displaypath() 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo 2022-02-08 8:39 ` [PATCH v6 01/16] submodule--helper: get remote names from any repository Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 03/16] submodule--helper: allow setting superprefix for init_submodule() Glen Choo ` (14 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4c7c1e1432..5efceb9d46 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -261,11 +261,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -281,6 +278,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 03/16] submodule--helper: allow setting superprefix for init_submodule() 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo 2022-02-08 8:39 ` [PATCH v6 01/16] submodule--helper: get remote names from any repository Glen Choo 2022-02-08 8:39 ` [PATCH v6 02/16] submodule--helper: refactor get_submodule_displaypath() Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 04/16] submodule--helper: run update using child process struct Glen Choo ` (13 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We allow callers of the `init_submodule()` function to optionally override the superprefix from the environment. We need to enable this option because in our conversion of the update command that will follow, the '--init' option will be handled through this API. We will need to change the superprefix at that time to ensure the display paths show correctly in the output messages. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5efceb9d46..09cda67c1e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -606,18 +606,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -691,7 +695,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 04/16] submodule--helper: run update using child process struct 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (2 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 03/16] submodule--helper: allow setting superprefix for init_submodule() Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 05/16] builtin/submodule--helper.c: reformat designated initializers Glen Choo ` (12 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We switch to using the run-command API function that takes a 'struct child process', since we are using a lot of the options. This will also make it simple to switch over to using 'capture_command()' when we start handling the output of the command completely in C. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 09cda67c1e..db71e6f4ec 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2344,47 +2344,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str static int run_update_command(struct update_data *ud, int subforce) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - int git_cmd; switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.use_shell = 1; + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); + if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Unable to checkout '%s' in submodule path '%s'"), -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 05/16] builtin/submodule--helper.c: reformat designated initializers 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (3 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 04/16] submodule--helper: run update using child process struct Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 06/16] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo ` (11 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> The second hunk here will make a subsequent commit's diff smaller, and let's do the first and third hunks while we're at it so that we consistently format all of these. Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index db71e6f4ec..9f79bdf4d5 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1654,7 +1654,10 @@ struct module_clone_data { unsigned int require_init: 1; int single_branch; }; -#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 } +#define MODULE_CLONE_DATA_INIT { \ + .reference = STRING_LIST_INIT_NODUP, \ + .single_branch = -1, \ +} struct submodule_alternate_setup { const char *submodule_name; @@ -2047,7 +2050,9 @@ struct update_data { unsigned int nofetch: 1; unsigned int just_cloned: 1; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -3013,7 +3018,9 @@ struct add_data { unsigned int progress: 1; unsigned int dissociate: 1; }; -#define ADD_DATA_INIT { .depth = -1 } +#define ADD_DATA_INIT { \ + .depth = -1, \ +} static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) { -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 06/16] builtin/submodule--helper.c: rename option variables to "opt" 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (4 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 05/16] builtin/submodule--helper.c: reformat designated initializers Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 07/16] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo ` (10 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Rename the "suc" variable in update_clone() to "opt", and do the same for the "update_data" variable in run_update_procedure(). The only reason for this change is to make the subsequent commit's diff smaller, by doing this rename we can "anchor" the diff better, as it "borrow" most of the options declared here as-is as far as the diff rename detection is concerned. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 74 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9f79bdf4d5..c2d4fd0347 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2517,36 +2517,36 @@ static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, + OPT_BOOL(0, "dissociate", &opt.dissociate, N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", + OPT_STRING(0, "depth", &opt.depth, "<depth>", N_("create a shallow clone truncated to the " "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, + OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, + OPT_BOOL(0, "require-init", &opt.require_init, N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, + OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() }; @@ -2555,32 +2555,32 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - suc.prefix = prefix; + opt.prefix = prefix; - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) + if (parse_submodule_update_strategy(update, &opt.update) < 0) die(_("bad value for update parameter")); - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) return 1; if (pathspec.nr) - suc.warn_if_uninitialized = 1; + opt.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_submodules(&opt); } static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; + struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2589,20 +2589,20 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) N_("don't fetch new objects from the remote site")), OPT_BOOL(0, "just-cloned", &just_cloned, N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), + OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), + OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), + OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, parse_opt_object_id), OPT_END() @@ -2618,27 +2618,27 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; + opt.force = !!force; + opt.quiet = !!quiet; + opt.nofetch = !!nofetch; + opt.just_cloned = !!just_cloned; + opt.sm_path = argv[0]; - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); + if (opt.recursive_prefix) + prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); else - prefixed_path = xstrdup(update_data.sm_path); + prefixed_path = xstrdup(opt.sm_path); - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); + opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); + determine_submodule_update_strategy(the_repository, opt.just_cloned, + opt.sm_path, update, + &opt.update_strategy); free(prefixed_path); - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + if (!oideq(&opt.oid, &opt.suboid) || opt.force) + return do_run_update_procedure(&opt); return 3; } -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 07/16] submodule--helper: don't use bitfield indirection for parse_options() 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (5 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 06/16] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 08/16] submodule tests: test for init and update failure output Glen Choo ` (9 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Do away with the indirection of local variables added in c51f8f94e5b (submodule--helper: run update procedures from C, 2021-08-24). These were only needed because in C you can't get a pointer to a single bit, so we were using intermediate variables instead. This will also make a subsequent large commit's diff smaller. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c2d4fd0347..4a0890954e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2045,10 +2045,10 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; - unsigned int force: 1; - unsigned int quiet: 1; - unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int force; + unsigned int quiet; + unsigned int nofetch; + unsigned int just_cloned; }; #define UPDATE_DATA_INIT { \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ @@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix) static int run_update_procedure(int argc, const char **argv, const char *prefix) { - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, + OPT__QUIET(&opt.quiet, + N_("suppress output for update by rebase or merge")), + OPT__FORCE(&opt.force, N_("force checkout updates"), + 0), + OPT_BOOL('N', "no-fetch", &opt.nofetch, N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, + OPT_BOOL(0, "just-cloned", &opt.just_cloned, N_("overrides update mode in case the repository is a fresh clone")), OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, @@ -2618,10 +2619,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - opt.force = !!force; - opt.quiet = !!quiet; - opt.nofetch = !!nofetch; - opt.just_cloned = !!just_cloned; opt.sm_path = argv[0]; if (opt.recursive_prefix) -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 08/16] submodule tests: test for init and update failure output 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (6 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 07/16] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 09/16] submodule--helper: remove update-module-mode Glen Choo ` (8 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Amend some submodule tests to test for the failure output of "git submodule [update|init]". The lack of such tests hid a regression in an earlier version of a subsequent commit. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- t/t7406-submodule-update.sh | 14 ++++++++++++-- t/t7408-submodule-reference.sh | 14 +++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 11cccbb333..7764c1c3cb 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' ' (cd submodule && compare_head ) && - test_must_fail git submodule update submodule - ) + test_must_fail git submodule update submodule 2>../actual.raw + ) && + sed "s/^> //" >expect <<-\EOF && + > error: Your local changes to the following files would be overwritten by checkout: + > file + > Please commit your changes or stash them before you switch branches. + > Aborting + > fatal: Unable to checkout OID in submodule path '\''submodule'\'' + EOF + sed -e "s/checkout $SQ[^$SQ]*$SQ/checkout OID/" <actual.raw >actual && + test_cmp expect actual + ' test_expect_success 'submodule update should throw away changes with --force ' ' (cd super && diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index a3892f494b..c3a4545510 100755 --- a/t/t7408-submodule-reference.sh +++ b/t/t7408-submodule-reference.sh @@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul cd supersuper-clone && check_that_two_of_three_alternates_are_used && # update of the submodule fails - test_must_fail git submodule update --init --recursive + cat >expect <<-\EOF && + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\''. Retry scheduled + fatal: submodule '\''sub-dissociate'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub-dissociate'\''. Retry scheduled + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\'' a second time, aborting + fatal: Failed to recurse into submodule path ... + EOF + test_must_fail git submodule update --init --recursive 2>err && + grep -e fatal: -e ^Failed err >actual.raw && + sed -e "s/path $SQ[^$SQ]*$SQ/path .../" <actual.raw >actual && + test_cmp expect actual ) ' -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 09/16] submodule--helper: remove update-module-mode 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (7 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 08/16] submodule tests: test for init and update failure output Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 10/16] submodule--helper: reorganize code for sh to C conversion Glen Choo ` (7 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason This is dead code - it has not been used since c51f8f94e5 (submodule--helper: run update procedures from C, 2021-08-24). Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4a0890954e..e0cc1c1b79 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1965,29 +1965,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -3388,7 +3365,6 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, {"ensure-core-worktree", ensure_core_worktree, 0}, -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 10/16] submodule--helper: reorganize code for sh to C conversion 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (8 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 09/16] submodule--helper: remove update-module-mode Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 11/16] submodule--helper run-update-procedure: remove --suboid Glen Choo ` (6 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Introduce a function, update_submodule2(), that performs an update for one submodule. This function will implement the functionality of run-update-procedure and its surrounding shell code in submodule.sh. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index e0cc1c1b79..0b5120734a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2553,6 +2553,11 @@ static int update_clone(int argc, const char **argv, const char *prefix) return update_submodules(&opt); } +/* + * NEEDSWORK: Use a forward declaration to avoid moving + * run_update_procedure() (which will be removed soon). + */ +static int update_submodule2(struct update_data *update_data); static int run_update_procedure(int argc, const char **argv, const char *prefix) { char *prefixed_path, *update = NULL; @@ -2610,11 +2615,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) &opt.update_strategy); free(prefixed_path); - - if (!oideq(&opt.oid, &opt.suboid) || opt.force) - return do_run_update_procedure(&opt); - - return 3; + return update_submodule2(&opt); } static int resolve_relative_path(int argc, const char **argv, const char *prefix) @@ -2978,6 +2979,15 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +/* NEEDSWORK: this is a temporary name until we delete update_submodule() */ +static int update_submodule2(struct update_data *update_data) +{ + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + return do_run_update_procedure(update_data); + + return 3; +} + struct add_data { const char *prefix; const char *branch; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 11/16] submodule--helper run-update-procedure: remove --suboid 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (9 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 10/16] submodule--helper: reorganize code for sh to C conversion Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 12/16] submodule--helper run-update-procedure: learn --remote Glen Choo ` (5 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach run-update-procedure to determine the oid of the submodule's HEAD instead of doing it in git-subomdule.sh. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 12 +++++++++--- git-submodule.sh | 8 +------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0b5120734a..a26477ce04 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2585,9 +2585,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), OPT_END() }; @@ -2982,6 +2979,15 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) /* NEEDSWORK: this is a temporary name until we delete update_submodule() */ static int update_submodule2(struct update_data *update_data) { + /* NEEDSWORK: fix the style issues e.g. braces */ + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) return do_run_update_procedure(update_data); diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66..d48c314f01 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -391,14 +391,9 @@ cmd_update() displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - if test $just_cloned -eq 1 + if test $just_cloned -eq 0 then - subsha1= - else just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" fi if test -n "$remote" @@ -426,7 +421,6 @@ cmd_update() ${update:+--update "$update"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ "--" \ "$sm_path") -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 12/16] submodule--helper run-update-procedure: learn --remote 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (10 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 11/16] submodule--helper run-update-procedure: remove --suboid Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 13/16] submodule--helper: remove ensure-core-worktree Glen Choo ` (4 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach run-update-procedure to handle --remote instead of parsing --remote in git-submodule.sh. As a result, "git submodule--helper print-default-remote" has no more callers, so remove it. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 39 ++++++++++++++++++++++--------------- git-submodule.sh | 30 +--------------------------- 2 files changed, 24 insertions(+), 45 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a26477ce04..15ae986692 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -71,21 +71,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -2026,6 +2011,7 @@ struct update_data { unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; + unsigned int remote; }; #define UPDATE_DATA_INIT { \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ @@ -2585,6 +2571,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), OPT_END() }; @@ -2988,6 +2976,25 @@ static int update_submodule2(struct update_data *update_data) update_data->displaypath); } + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if (fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) return do_run_update_procedure(update_data); @@ -3389,10 +3396,10 @@ static struct cmd_struct commands[] = { {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, + /* NEEDSWORK: remote-branch is also obsolete */ {"remote-branch", resolve_remote_submodule_branch, 0}, {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index d48c314f01..29fd69250d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,20 +246,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -396,21 +382,6 @@ cmd_update() just_cloned= fi - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - out=$(git submodule--helper run-update-procedure \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${GIT_QUIET:+--quiet} \ @@ -421,6 +392,7 @@ cmd_update() ${update:+--update "$update"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${sha1:+--oid "$sha1"} \ + ${remote:+--remote} \ "--" \ "$sm_path") -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 13/16] submodule--helper: remove ensure-core-worktree 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (11 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 12/16] submodule--helper run-update-procedure: learn --remote Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 14/16] submodule--helper update-clone: learn --init Glen Choo ` (3 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Move the logic of "git submodule--helper ensure-core-worktree" into run-update-procedure. Since the ensure-core-worktree command is obsolete, remove it. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 13 +++---------- git-submodule.sh | 2 -- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 15ae986692..a05aea5cd6 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2746,17 +2746,11 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void ensure_core_worktree(const char *path) { - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) die(_("could not get a repository handle for submodule '%s'"), path); @@ -2776,8 +2770,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } - - return 0; } static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ -2967,6 +2959,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) /* NEEDSWORK: this is a temporary name until we delete update_submodule() */ static int update_submodule2(struct update_data *update_data) { + ensure_core_worktree(update_data->sm_path); + /* NEEDSWORK: fix the style issues e.g. braces */ if (update_data->just_cloned) { oidcpy(&update_data->suboid, null_oid()); @@ -3390,7 +3384,6 @@ static struct cmd_struct commands[] = { {"add", module_add, SUPPORT_SUPER_PREFIX}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 29fd69250d..aa9c898e1c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -373,8 +373,6 @@ cmd_update() do die_if_unmatched "$quickabort" "$sha1" - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") if test $just_cloned -eq 0 -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 14/16] submodule--helper update-clone: learn --init 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (12 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 13/16] submodule--helper: remove ensure-core-worktree Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 15/16] submodule--helper: move functions around Glen Choo ` (2 subsequent siblings) 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach "git submodule--helper update-clone" the --init flag and remove the corresponding shell code. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call. So we instead run the `init_submodule_cb()` callback over each submodule in the same process. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++ git-submodule.sh | 9 +++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a05aea5cd6..5635f0c48b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1989,6 +1989,7 @@ struct submodule_update_clone { int failed_clones_nr, failed_clones_alloc; int max_jobs; + unsigned int init; }; #define SUBMODULE_UPDATE_CLONE_INIT { \ .list = MODULE_LIST_INIT, \ @@ -2483,6 +2484,8 @@ static int update_clone(int argc, const char **argv, const char *prefix) struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), @@ -2536,6 +2539,29 @@ static int update_clone(int argc, const char **argv, const char *prefix) if (pathspec.nr) opt.warn_if_uninitialized = 1; + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + return update_submodules(&opt); } diff --git a/git-submodule.sh b/git-submodule.sh index aa9c898e1c..3ccf2388bf 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -347,14 +347,11 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ + ${GIT_QUIET:+--quiet} \ ${progress:+"--progress"} \ + ${init:+--init} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 15/16] submodule--helper: move functions around 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (13 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 14/16] submodule--helper update-clone: learn --init Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 16/16] submodule: move core cmd_update() logic to C Glen Choo 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason The next commit will change the internals of several functions and arrange them in a more logical manner. Move these functions to their final positions so that the diff is smaller. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 228 ++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5635f0c48b..0ab8f9d49f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2451,120 +2451,6 @@ static void update_submodule(struct update_clone_data *ucd) ucd->sub->path); } -static int update_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_BOOL(0, "init", &opt.init, - N_("initialize uninitialized submodules before update")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &opt.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &opt.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - opt.prefix = prefix; - - update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) - return 1; - - if (pathspec.nr) - opt.warn_if_uninitialized = 1; - - if (opt.init) { - struct module_list list = MODULE_LIST_INIT; - struct init_cb info = INIT_CB_INIT; - - if (module_list_compute(argc, argv, opt.prefix, - &pathspec, &list) < 0) - return 1; - - /* - * If there are no path args and submodule.active is set then, - * by default, only initialize 'active' modules. - */ - if (!argc && git_config_get_value_multi("submodule.active")) - module_list_active(&list); - - info.prefix = opt.prefix; - info.superprefix = opt.recursive_prefix; - if (opt.quiet) - info.flags |= OPT_QUIET; - - for_each_listed_submodule(&list, init_submodule_cb, &info); - } - - return update_submodules(&opt); -} - /* * NEEDSWORK: Use a forward declaration to avoid moving * run_update_procedure() (which will be removed soon). @@ -3021,6 +2907,120 @@ static int update_submodule2(struct update_data *update_data) return 3; } +static int update_submodules(struct submodule_update_clone *suc) +{ + int i; + + run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc->quickstop) + return 1; + + for (i = 0; i < suc->update_clone_nr; i++) + update_submodule(&suc->update_clone[i]); + + return 0; +} + +static int update_clone(int argc, const char **argv, const char *prefix) +{ + const char *update = NULL; + struct pathspec pathspec; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + + struct option module_update_clone_options[] = { + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &opt.dissociate, + N_("use --reference only while cloning")), + OPT_STRING(0, "depth", &opt.depth, "<depth>", + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &opt.require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + opt.prefix = prefix; + + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + + if (update) + if (parse_submodule_update_strategy(update, &opt.update) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) + return 1; + + if (pathspec.nr) + opt.warn_if_uninitialized = 1; + + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&opt); +} + struct add_data { const char *prefix; const char *branch; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v6 16/16] submodule: move core cmd_update() logic to C 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (14 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 15/16] submodule--helper: move functions around Glen Choo @ 2022-02-08 8:39 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo 16 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-08 8:39 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 360 ++++++++++++++++++++++-------------- git-submodule.sh | 102 +--------- 2 files changed, 227 insertions(+), 235 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0ab8f9d49f..5085b28a2d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1977,7 +1977,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -1989,7 +1988,6 @@ struct submodule_update_clone { int failed_clones_nr, failed_clones_alloc; int max_jobs; - unsigned int init; }; #define SUBMODULE_UPDATE_CLONE_INIT { \ .list = MODULE_LIST_INIT, \ @@ -2001,6 +1999,7 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; @@ -2008,14 +2007,54 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; + int recommend_shallow; + int single_branch; + int max_jobs; + unsigned int init; unsigned int force; unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; + unsigned int require_init; + unsigned warn_if_uninitialized ; + struct string_list references; + struct module_list list; }; #define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } } static void next_submodule_warn_missing(struct submodule_update_clone *suc, @@ -2316,8 +2355,15 @@ static int run_update_command(struct update_data *ud, int subforce) struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; + struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; + + if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) + determine_submodule_update_strategy(the_repository, ud->just_cloned, + ud->sm_path, NULL, &strategy); + else + strategy = ud->update_strategy; - switch (ud->update_strategy.type) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-q", NULL); @@ -2340,55 +2386,54 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: cp.use_shell = 1; - strvec_push(&cp.args, ud->update_strategy.command); + strvec_push(&cp.args, strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); if (run_command(&cp)) { - switch (ud->update_strategy.type) { + switch (strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); + die_message(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); + if (!must_die_on_failure) + break; + die(_("Execution of '%s %s' failed in submodule path '%s'"), + strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ - if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + + /* the command failed, but update must continue */ return 1; } - switch (ud->update_strategy.type) { + if (ud->quiet) + return 0; + + switch (strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), ud->displaypath, oid); @@ -2403,17 +2448,17 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); + ud->displaypath, strategy.command, oid); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&ud->update_strategy)); + submodule_strategy_to_string(&strategy)); } return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int run_update_procedure(struct update_data *ud) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2443,89 +2488,6 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -/* - * NEEDSWORK: Use a forward declaration to avoid moving - * run_update_procedure() (which will be removed soon). - */ -static int update_submodule2(struct update_data *update_data); -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - char *prefixed_path, *update = NULL; - struct update_data opt = UPDATE_DATA_INIT; - - struct option options[] = { - OPT__QUIET(&opt.quiet, - N_("suppress output for update by rebase or merge")), - OPT__FORCE(&opt.force, N_("force checkout updates"), - 0), - OPT_BOOL('N', "no-fetch", &opt.nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &opt.just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_BOOL(0, "remote", &opt.remote, - N_("use SHA-1 of submodule's remote tracking branch")), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - opt.sm_path = argv[0]; - - if (opt.recursive_prefix) - prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); - else - prefixed_path = xstrdup(opt.sm_path); - - opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, opt.just_cloned, - opt.sm_path, update, - &opt.update_strategy); - - free(prefixed_path); - return update_submodule2(&opt); -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -2868,11 +2830,66 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } -/* NEEDSWORK: this is a temporary name until we delete update_submodule() */ -static int update_submodule2(struct update_data *update_data) +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + const char *update = submodule_strategy_to_string(&update_data->update_strategy); + + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update) + strvec_pushl(args, "--update", update, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) { + char *prefixed_path; + ensure_core_worktree(update_data->sm_path); + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + /* NEEDSWORK: fix the style issues e.g. braces */ if (update_data->just_cloned) { oidcpy(&update_data->suboid, null_oid()); @@ -2902,18 +2919,55 @@ static int update_submodule2(struct update_data *update_data) } if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) - return do_run_update_procedure(update_data); + if (run_update_procedure(update_data)) + return 1; - return 3; + if (update_data->recursive) { + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + int res; + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); + + /* die() if child process die()'d */ + res = run_command(&cp); + if (!res) + return 0; + die_message(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + if (res == 128) + exit(res); + else if (res) + return 1; + } + + return 0; } -static int update_submodules(struct submodule_update_clone *suc) +static int update_submodules(struct update_data *update_data) { - int i; + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, update_clone_start_failure, - update_clone_task_finished, suc, "submodule", + update_clone_task_finished, &suc, "submodule", "parallel/update"); /* @@ -2924,25 +2978,45 @@ static int update_submodules(struct submodule_update_clone *suc) * checkout involve more straightforward sequential I/O. * - the listener can avoid doing any work if fetching failed. */ - if (suc->quickstop) - return 1; + if (suc.quickstop) { + res = 1; + goto cleanup; + } - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; - return 0; + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + +cleanup: + string_list_clear(&update_data->references, 0); + return res; } -static int update_clone(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix) { const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + struct update_data opt = UPDATE_DATA_INIT; + /* NEEDSWORK: update names and strings */ struct option module_update_clone_options[] = { + OPT__FORCE(&opt.force, N_("force checkout updates"), 0), OPT_BOOL(0, "init", &opt.init, N_("initialize uninitialized submodules before update")), - OPT_STRING(0, "prefix", &prefix, + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &opt.recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &opt.prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, @@ -2953,21 +3027,21 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), + N_("reference repository")), OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), + N_("whether the initial clone should follow the shallow recommendation")), OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), + N_("force cloning progress")), OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), + N_("disallow cloning into non-empty directory")), OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() @@ -2977,16 +3051,18 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - opt.prefix = prefix; update_clone_config_from_gitmodules(&opt.max_jobs); git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) + if (parse_submodule_update_strategy(update, + &opt.update_strategy) < 0) die(_("bad value for update parameter")); if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) @@ -3408,9 +3484,7 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 3ccf2388bf..bcd8b92aab 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -347,108 +347,26 @@ cmd_update() shift done - { - git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 0 - then - just_cloned= - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${remote:+--remote} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo ` (15 preceding siblings ...) 2022-02-08 8:39 ` [PATCH v6 16/16] submodule: move core cmd_update() logic to C Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 01/20] submodule--helper: get remote names from any repository Glen Choo ` (21 more replies) 16 siblings, 22 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason This reroll contains another 'easy' preparatory patch and the fixups I alluded to in v6 [1]. This isn't the split-up I described in the footnote of v6, but it gets the big patch (patch 17) to what I think is a reviewable state. The diff between v7 and v5 is no longer just NEEDSWORK comments, but I think it is easier to reason about. Patch 17 resembles v5 the most (I will include a diff in a reply to that patch); everything after patch 17 is fixups (I did not squash them in because they would grow the diff even more). I will also leave a review on patch 17 since the changes were not originally authored by me. [1] https://lore.kernel.org/git/20220208083952.35036-1-chooglen@google.com Changes in v7: - Split the last patch of v6 (the big one) into patches 16-17. - Patch 16 moves logic out of run_update_procedure() (because the command is going away), removing some noise from patch 17. This makes the update_strategy parsing easier to reason about, but at the cost of growing the diff vis-a-vis v5 - Patches 18-20 are fixups that address NEEDSWORK comments from earlier patches. Once maintaining a small diff vis-a-vis v5 stops making sense, I will squash them in. Atharva Raykar (6): submodule--helper: get remote names from any repository submodule--helper: refactor get_submodule_displaypath() submodule--helper: allow setting superprefix for init_submodule() submodule--helper: run update using child process struct builtin/submodule--helper.c: reformat designated initializers submodule: move core cmd_update() logic to C Glen Choo (11): submodule--helper: remove update-module-mode submodule--helper: reorganize code for sh to C conversion submodule--helper run-update-procedure: remove --suboid submodule--helper run-update-procedure: learn --remote submodule--helper: remove ensure-core-worktree submodule--helper update-clone: learn --init submodule--helper: move functions around submodule--helper: reduce logic in run_update_procedure() fixup! submodule--helper run-update-procedure: remove --suboid fixup! submodule--helper run-update-procedure: learn --remote fixup! submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason (3): builtin/submodule--helper.c: rename option variables to "opt" submodule--helper: don't use bitfield indirection for parse_options() submodule tests: test for init and update failure output builtin/submodule--helper.c | 695 ++++++++++++++++++--------------- git-submodule.sh | 153 +------- t/t7406-submodule-update.sh | 14 +- t/t7408-submodule-reference.sh | 14 +- 4 files changed, 423 insertions(+), 453 deletions(-) Range-diff against v6: 1: 79c522cf56 = 1: 86ffb53742 submodule--helper: get remote names from any repository 2: 0b97034d89 = 2: 2a40266b7a submodule--helper: refactor get_submodule_displaypath() 3: fedbed87a3 = 3: cd851c8eb5 submodule--helper: allow setting superprefix for init_submodule() 4: 8e7868c5d1 = 4: bfe5cad136 submodule--helper: run update using child process struct 5: 3dee4b9b15 = 5: 72c257fdbf builtin/submodule--helper.c: reformat designated initializers 6: e2cc866e6b = 6: 4b5f703fde builtin/submodule--helper.c: rename option variables to "opt" 7: 4831695dc6 = 7: f1d21f5b1c submodule--helper: don't use bitfield indirection for parse_options() 8: c2dadfffb2 = 8: 9d32a73fc3 submodule tests: test for init and update failure output 9: 79ceb88dee = 9: 087bf43aba submodule--helper: remove update-module-mode 10: 6fe25e24da = 10: 4eb2893a19 submodule--helper: reorganize code for sh to C conversion 11: 52c997f97b = 11: c08e7781e3 submodule--helper run-update-procedure: remove --suboid 12: 61a5b02472 = 12: 2419c37184 submodule--helper run-update-procedure: learn --remote 13: f76627a078 = 13: 6691fd3648 submodule--helper: remove ensure-core-worktree 14: 2d93c4232b = 14: d2c9c356e9 submodule--helper update-clone: learn --init 15: d4899c5635 ! 15: c8945fcc6f submodule--helper: move functions around @@ Metadata ## Commit message ## submodule--helper: move functions around - The next commit will change the internals of several functions and + A subsequent commit will change the internals of several functions and arrange them in a more logical manner. Move these functions to their final positions so that the diff is smaller. -: ---------- > 16: 10af533ae0 submodule--helper: reduce logic in run_update_procedure() 16: edf752da8d ! 17: 19143f6009 submodule: move core cmd_update() logic to C @@ builtin/submodule--helper.c: struct submodule_update_clone { }; #define SUBMODULE_UPDATE_CLONE_INIT { \ .list = MODULE_LIST_INIT, \ -@@ builtin/submodule--helper.c: struct submodule_update_clone { - } - - struct update_data { -+ const char *prefix; - const char *recursive_prefix; - const char *sm_path; - const char *displaypath; @@ builtin/submodule--helper.c: struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; @@ builtin/submodule--helper.c: struct update_data { static void next_submodule_warn_missing(struct submodule_update_clone *suc, @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) - struct child_process cp = CHILD_PROCESS_INIT; - char *oid = oid_to_hex(&ud->oid); - int must_die_on_failure = 0; -+ struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; -+ -+ if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) -+ determine_submodule_update_strategy(the_repository, ud->just_cloned, -+ ud->sm_path, NULL, &strategy); -+ else -+ strategy = ud->update_strategy; - -- switch (ud->update_strategy.type) { -+ switch (strategy.type) { - case SM_UPDATE_CHECKOUT: - cp.git_cmd = 1; - strvec_pushl(&cp.args, "checkout", "-q", NULL); -@@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) - break; - case SM_UPDATE_COMMAND: - cp.use_shell = 1; -- strvec_push(&cp.args, ud->update_strategy.command); -+ strvec_push(&cp.args, strategy.command); - must_die_on_failure = 1; - break; - default: - BUG("unexpected update strategy type: %s", -- submodule_strategy_to_string(&ud->update_strategy)); -+ submodule_strategy_to_string(&strategy)); - } - strvec_push(&cp.args, oid); - - cp.dir = xstrdup(ud->sm_path); - prepare_submodule_repo_env(&cp.env_array); if (run_command(&cp)) { -- switch (ud->update_strategy.type) { -+ switch (strategy.type) { + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); -+ if (!must_die_on_failure) -+ break; -+ die(_("Unable to rebase '%s' in submodule path '%s'"), ++ die_message(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); -+ if (!must_die_on_failure) -+ break; -+ die(_("Unable to merge '%s' in submodule path '%s'"), ++ die_message(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); -+ if (!must_die_on_failure) -+ break; -+ die(_("Execution of '%s %s' failed in submodule path '%s'"), -+ strategy.command, oid, ud->displaypath); ++ die_message(_("Execution of '%s %s' failed in submodule path '%s'"), ++ ud->update_strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", -- submodule_strategy_to_string(&ud->update_strategy)); -+ submodule_strategy_to_string(&strategy)); + submodule_strategy_to_string(&ud->update_strategy)); } - /* - * NEEDSWORK: We are currently printing to stdout with error @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *u - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ -- if (must_die_on_failure) + if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ ++ exit(128); + + /* the command failed, but update must continue */ return 1; } -- switch (ud->update_strategy.type) { + if (ud->quiet) + return 0; + -+ switch (strategy.type) { + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); @@ builtin/submodule--helper.c: static int run_update_command(struct update_data *ud, int subforce) - break; - case SM_UPDATE_COMMAND: - printf(_("Submodule path '%s': '%s %s'\n"), -- ud->displaypath, ud->update_strategy.command, oid); -+ ud->displaypath, strategy.command, oid); - break; - default: - BUG("unexpected update strategy type: %s", -- submodule_strategy_to_string(&ud->update_strategy)); -+ submodule_strategy_to_string(&strategy)); - } - return 0; } @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da -static int update_submodule2(struct update_data *update_data); -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ -- char *prefixed_path, *update = NULL; - struct update_data opt = UPDATE_DATA_INIT; - - struct option options[] = { @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - OPT_BOOL(0, "just-cloned", &opt.just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), -- OPT_STRING(0, "prefix", &prefix, +- OPT_STRING(0, "prefix", &opt.prefix, - N_("path"), - N_("path into the working tree")), -- OPT_STRING(0, "update", &update, +- OPT_STRING(0, "update", &opt.update_default, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), @@ builtin/submodule--helper.c: static int do_run_update_procedure(struct update_da - - opt.sm_path = argv[0]; - -- if (opt.recursive_prefix) -- prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); -- else -- prefixed_path = xstrdup(opt.sm_path); -- -- opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); -- -- determine_submodule_update_strategy(the_repository, opt.just_cloned, -- opt.sm_path, update, -- &opt.update_strategy); -- -- free(prefixed_path); - return update_submodule2(&opt); -} - @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * -static int update_submodule2(struct update_data *update_data) +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ -+ const char *update = submodule_strategy_to_string(&update_data->update_strategy); -+ + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); ++ /* ++ * NEEDSWORK: the equivalent code in git-submodule.sh does not ++ * pass --prefix, so this shouldn't either ++ */ + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); -+ if (update) -+ strvec_pushl(args, "--update", update, NULL); ++ if (update_data->update_default) ++ strvec_pushl(args, "--update", update_data->update_default, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char * + +static int update_submodule(struct update_data *update_data) { -+ char *prefixed_path; -+ - ensure_core_worktree(update_data->sm_path); + char *prefixed_path; -+ if (update_data->recursive_prefix) -+ prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, -+ update_data->sm_path); -+ else -+ prefixed_path = xstrdup(update_data->sm_path); -+ -+ update_data->displaypath = get_submodule_displaypath(prefixed_path, -+ update_data->prefix); -+ free(prefixed_path); -+ - /* NEEDSWORK: fix the style issues e.g. braces */ - if (update_data->just_cloned) { - oidcpy(&update_data->suboid, null_oid()); @@ builtin/submodule--helper.c: static int update_submodule2(struct update_data *update_data) } @@ builtin/submodule--helper.c: static int update_submodule2(struct update_data *up - return do_run_update_procedure(update_data); + if (run_update_procedure(update_data)) + return 1; - -- return 3; ++ + if (update_data->recursive) { + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; @@ builtin/submodule--helper.c: static int update_submodule2(struct update_data *up + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); -+ + +- return 3; + /* die() if child process die()'d */ + res = run_command(&cp); + if (!res) @@ builtin/submodule--helper.c: static int update_submodules(struct submodule_updat -static int update_clone(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix) { - const char *update = NULL; +- const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + struct update_data opt = UPDATE_DATA_INIT; @@ builtin/submodule--helper.c: static int update_submodules(struct submodule_updat N_("path"), N_("path into the working tree")), OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, -@@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv, const char *prefix) + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), +- OPT_STRING(0, "update", &update, ++ OPT_STRING(0, "update", &opt.update_default, N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), @@ builtin/submodule--helper.c: static int update_clone(int argc, const char **argv + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); - if (update) +- if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) -+ if (parse_submodule_update_strategy(update, ++ if (opt.update_default) ++ if (parse_submodule_update_strategy(opt.update_default, + &opt.update_strategy) < 0) die(_("bad value for update parameter")); @@ builtin/submodule--helper.c: static struct cmd_struct commands[] = { {"init", module_init, SUPPORT_SUPER_PREFIX}, ## git-submodule.sh ## +@@ git-submodule.sh: single_branch= + jobs= + recommend_shallow= + ++# NEEDSWORK this is now unused + die_if_unmatched () + { + if test "$1" = "#unmatched" @@ git-submodule.sh: cmd_update() shift done - { - git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ ++ # NEEDSWORK --super-prefix isn't actually supported by this ++ # command - we just pass the $prefix to --recursive-prefix. + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ -: ---------- > 18: 9d0afc60ec fixup! submodule--helper run-update-procedure: remove --suboid -: ---------- > 19: e700861239 fixup! submodule--helper run-update-procedure: learn --remote -: ---------- > 20: aef1a03b44 fixup! submodule: move core cmd_update() logic to C base-commit: b23dac905bde28da47543484320db16312c87551 -- 2.33.GIT ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 01/20] submodule--helper: get remote names from any repository 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() Glen Choo ` (20 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> `get_default_remote()` retrieves the name of a remote by resolving the refs from of the current repository's ref store. Thus in order to use it for retrieving the remote name of a submodule, we have to start a new subprocess which runs from the submodule directory. Let's instead introduce a function called `repo_get_default_remote()` which takes any repository object and retrieves the remote accordingly. `get_default_remote()` is then defined as a call to `repo_get_default_remote()` with 'the_repository' passed to it. Now that we have `repo_get_default_remote()`, we no longer have to start a subprocess that called `submodule--helper get-default-remote` from within the submodule directory. So let's make a function called `get_default_remote_submodule()` which takes a submodule path, and returns the default remote for that submodule, all within the same process. We can now use this function to save an unnecessary subprocess spawn in `sync_submodule()`, and also in the next patch, which will require this functionality. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Helped-by: Glen Choo <chooglen@google.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c5d3fc3817..4c7c1e1432 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -29,11 +29,14 @@ typedef void (*each_submodule_fn)(const struct cache_entry *list_item, void *cb_data); -static char *get_default_remote(void) +static char *repo_get_default_remote(struct repository *repo) { char *dest = NULL, *ret; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + struct ref_store *store = get_main_ref_store(repo); + int ignore_errno; + const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL, + NULL, &ignore_errno); if (!refname) die(_("No such ref: %s"), "HEAD"); @@ -46,7 +49,7 @@ static char *get_default_remote(void) die(_("Expecting a full ref name, got %s"), refname); strbuf_addf(&sb, "branch.%s.remote", refname); - if (git_config_get_string(sb.buf, &dest)) + if (repo_config_get_string(repo, sb.buf, &dest)) ret = xstrdup("origin"); else ret = dest; @@ -55,6 +58,19 @@ static char *get_default_remote(void) return ret; } +static char *get_default_remote_submodule(const char *module_path) +{ + struct repository subrepo; + + repo_submodule_init(&subrepo, the_repository, module_path, null_oid()); + return repo_get_default_remote(&subrepo); +} + +static char *get_default_remote(void) +{ + return repo_get_default_remote(the_repository); +} + static int print_default_remote(int argc, const char **argv, const char *prefix) { char *remote; @@ -1341,9 +1357,8 @@ static void sync_submodule(const char *path, const char *prefix, { const struct submodule *sub; char *remote_key = NULL; - char *sub_origin_url, *super_config_url, *displaypath; + char *sub_origin_url, *super_config_url, *displaypath, *default_remote; struct strbuf sb = STRBUF_INIT; - struct child_process cp = CHILD_PROCESS_INIT; char *sub_config_path = NULL; if (!is_submodule_active(the_repository, path)) @@ -1382,21 +1397,15 @@ static void sync_submodule(const char *path, const char *prefix, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); - cp.git_cmd = 1; - cp.dir = path; - strvec_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); - strbuf_reset(&sb); - if (capture_command(&cp, &sb, 0)) + default_remote = get_default_remote_submodule(path); + if (!default_remote) die(_("failed to get the default remote for submodule '%s'"), path); - strbuf_strip_suffix(&sb, "\n"); - remote_key = xstrfmt("remote.%s.url", sb.buf); + remote_key = xstrfmt("remote.%s.url", default_remote); + free(default_remote); - strbuf_reset(&sb); submodule_to_gitdir(&sb, path); strbuf_addstr(&sb, "/config"); -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo 2022-02-10 9:28 ` [PATCH v7 01/20] submodule--helper: get remote names from any repository Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:24 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() Glen Choo ` (19 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We create a function called `do_get_submodule_displaypath()` that generates the display path required by several submodule functions, and takes a custom superprefix parameter, instead of reading it from the environment. We then redefine the existing `get_submodule_displaypath()` function as a call to this new function, where the superprefix is obtained from the environment. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4c7c1e1432..5efceb9d46 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -261,11 +261,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr return 0; } -/* the result should be freed by the caller. */ -static char *get_submodule_displaypath(const char *path, const char *prefix) +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) { - const char *super_prefix = get_super_prefix(); - if (prefix && super_prefix) { BUG("cannot have prefix '%s' and superprefix '%s'", prefix, super_prefix); @@ -281,6 +278,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix) } } +/* the result should be freed by the caller. */ +static char *get_submodule_displaypath(const char *path, const char *prefix) +{ + const char *super_prefix = get_super_prefix(); + return do_get_submodule_displaypath(path, prefix, super_prefix); +} + static char *compute_rev_name(const char *sub_path, const char* object_id) { struct strbuf sb = STRBUF_INIT; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() 2022-02-10 9:28 ` [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() Glen Choo @ 2022-02-12 14:24 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:24 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > From: Atharva Raykar <raykar.ath@gmail.com> > > We create a function called `do_get_submodule_displaypath()` that > generates the display path required by several submodule functions, and > takes a custom superprefix parameter, instead of reading it from the > environment. > > We then redefine the existing `get_submodule_displaypath()` function > as a call to this new function, where the superprefix is obtained from > the environment. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> > Signed-off-by: Junio C Hamano <gitster@pobox.com> > --- > builtin/submodule--helper.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 4c7c1e1432..5efceb9d46 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -261,11 +261,8 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr > return 0; > } > > -/* the result should be freed by the caller. */ > -static char *get_submodule_displaypath(const char *path, const char *prefix) > +static char *do_get_submodule_displaypath(const char *path, const char *prefix, const char *super_prefix) Nit: overly long line (also in my v5, but since we're applying some final polishing touches...) ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo 2022-02-10 9:28 ` [PATCH v7 01/20] submodule--helper: get remote names from any repository Glen Choo 2022-02-10 9:28 ` [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:30 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 04/20] submodule--helper: run update using child process struct Glen Choo ` (18 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We allow callers of the `init_submodule()` function to optionally override the superprefix from the environment. We need to enable this option because in our conversion of the update command that will follow, the '--init' option will be handled through this API. We will need to change the superprefix at that time to ensure the display paths show correctly in the output messages. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5efceb9d46..09cda67c1e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -606,18 +606,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) struct init_cb { const char *prefix; + const char *superprefix; unsigned int flags; }; #define INIT_CB_INIT { 0 } static void init_submodule(const char *path, const char *prefix, - unsigned int flags) + const char *superprefix, unsigned int flags) { const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - displaypath = get_submodule_displaypath(path, prefix); + /* try superprefix from the environment, if it is not passed explicitly */ + if (!superprefix) + superprefix = get_super_prefix(); + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); sub = submodule_from_path(the_repository, null_oid(), path); @@ -691,7 +695,7 @@ static void init_submodule(const char *path, const char *prefix, static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->flags); + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); } static int module_init(int argc, const char **argv, const char *prefix) -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() 2022-02-10 9:28 ` [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() Glen Choo @ 2022-02-12 14:30 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:30 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > From: Atharva Raykar <raykar.ath@gmail.com> > > We allow callers of the `init_submodule()` function to optionally > override the superprefix from the environment. > > We need to enable this option because in our conversion of the update > command that will follow, the '--init' option will be handled through > this API. We will need to change the superprefix at that time to ensure > the display paths show correctly in the output messages. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> > Signed-off-by: Junio C Hamano <gitster@pobox.com> > --- > builtin/submodule--helper.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 5efceb9d46..09cda67c1e 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -606,18 +606,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix) > > struct init_cb { > const char *prefix; > + const char *superprefix; > unsigned int flags; > }; > #define INIT_CB_INIT { 0 } > > static void init_submodule(const char *path, const char *prefix, > - unsigned int flags) > + const char *superprefix, unsigned int flags) > { > const struct submodule *sub; > struct strbuf sb = STRBUF_INIT; > char *upd = NULL, *url = NULL, *displaypath; > > - displaypath = get_submodule_displaypath(path, prefix); > + /* try superprefix from the environment, if it is not passed explicitly */ > + if (!superprefix) > + superprefix = get_super_prefix(); > + displaypath = do_get_submodule_displaypath(path, prefix, superprefix); > > sub = submodule_from_path(the_repository, null_oid(), path); > > @@ -691,7 +695,7 @@ static void init_submodule(const char *path, const char *prefix, > static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) > { > struct init_cb *info = cb_data; > - init_submodule(list_item->name, info->prefix, info->flags); > + init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); > } > > static int module_init(int argc, const char **argv, const char *prefix) Note/nit on existing (pre this series) code, I wonder why we ended up with this init_submodule() v.s. init_submodule_cb() indirection, v.s. just doing: diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 09cda67c1ea..aa82abeb37a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -611,9 +611,14 @@ struct init_cb { }; #define INIT_CB_INIT { 0 } -static void init_submodule(const char *path, const char *prefix, - const char *superprefix, unsigned int flags) +static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) { + const char *path = list_item->name; + struct init_cb *info = cb_data; + const char *prefix = info->prefix; + const char *superprefix = info->superprefix ? info->superprefix : + get_super_prefix(); + unsigned int flags = info->flags; const struct submodule *sub; struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; @@ -692,12 +697,6 @@ static void init_submodule(const char *path, const char *prefix, free(upd); } -static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data) -{ - struct init_cb *info = cb_data; - init_submodule(list_item->name, info->prefix, info->superprefix, info->flags); -} - static int module_init(int argc, const char **argv, const char *prefix) { struct init_cb info = INIT_CB_INIT; Maybe it's worth it to declare the variables in the argument list v.s. the function. ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 04/20] submodule--helper: run update using child process struct 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (2 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:33 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 05/20] builtin/submodule--helper.c: reformat designated initializers Glen Choo ` (17 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> We switch to using the run-command API function that takes a 'struct child process', since we are using a lot of the options. This will also make it simple to switch over to using 'capture_command()' when we start handling the output of the command completely in C. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 09cda67c1e..db71e6f4ec 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2344,47 +2344,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str static int run_update_command(struct update_data *ud, int subforce) { - struct strvec args = STRVEC_INIT; - struct strvec child_env = STRVEC_INIT; + struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - int git_cmd; switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - git_cmd = 1; - strvec_pushl(&args, "checkout", "-q", NULL); + cp.git_cmd = 1; + strvec_pushl(&cp.args, "checkout", "-q", NULL); if (subforce) - strvec_push(&args, "-f"); + strvec_push(&cp.args, "-f"); break; case SM_UPDATE_REBASE: - git_cmd = 1; - strvec_push(&args, "rebase"); + cp.git_cmd = 1; + strvec_push(&cp.args, "rebase"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_MERGE: - git_cmd = 1; - strvec_push(&args, "merge"); + cp.git_cmd = 1; + strvec_push(&cp.args, "merge"); if (ud->quiet) - strvec_push(&args, "--quiet"); + strvec_push(&cp.args, "--quiet"); must_die_on_failure = 1; break; case SM_UPDATE_COMMAND: - git_cmd = 0; - strvec_push(&args, ud->update_strategy.command); + cp.use_shell = 1; + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - strvec_push(&args, oid); + strvec_push(&cp.args, oid); - prepare_submodule_repo_env(&child_env); - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, - ud->sm_path, child_env.v)) { + cp.dir = xstrdup(ud->sm_path); + prepare_submodule_repo_env(&cp.env_array); + if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Unable to checkout '%s' in submodule path '%s'"), -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 04/20] submodule--helper: run update using child process struct 2022-02-10 9:28 ` [PATCH v7 04/20] submodule--helper: run update using child process struct Glen Choo @ 2022-02-12 14:33 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:33 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > From: Atharva Raykar <raykar.ath@gmail.com> > > We switch to using the run-command API function that takes a > 'struct child process', since we are using a lot of the options. This > will also make it simple to switch over to using 'capture_command()' > when we start handling the output of the command completely in C. > > Mentored-by: Christian Couder <christian.couder@gmail.com> > Mentored-by: Shourya Shukla <periperidip@gmail.com> > Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> > Signed-off-by: Junio C Hamano <gitster@pobox.com> > --- > builtin/submodule--helper.c | 34 ++++++++++++++++------------------ > 1 file changed, 16 insertions(+), 18 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 09cda67c1e..db71e6f4ec 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -2344,47 +2344,45 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str > > static int run_update_command(struct update_data *ud, int subforce) > { > - struct strvec args = STRVEC_INIT; > - struct strvec child_env = STRVEC_INIT; > + struct child_process cp = CHILD_PROCESS_INIT; > char *oid = oid_to_hex(&ud->oid); > int must_die_on_failure = 0; > - int git_cmd; > > switch (ud->update_strategy.type) { > case SM_UPDATE_CHECKOUT: > - git_cmd = 1; > - strvec_pushl(&args, "checkout", "-q", NULL); > + cp.git_cmd = 1; > + strvec_pushl(&cp.args, "checkout", "-q", NULL); > if (subforce) > - strvec_push(&args, "-f"); > + strvec_push(&cp.args, "-f"); > break; > case SM_UPDATE_REBASE: > - git_cmd = 1; > - strvec_push(&args, "rebase"); > + cp.git_cmd = 1; > + strvec_push(&cp.args, "rebase"); > if (ud->quiet) > - strvec_push(&args, "--quiet"); > + strvec_push(&cp.args, "--quiet"); > must_die_on_failure = 1; > break; > case SM_UPDATE_MERGE: > - git_cmd = 1; > - strvec_push(&args, "merge"); > + cp.git_cmd = 1; > + strvec_push(&cp.args, "merge"); > if (ud->quiet) > - strvec_push(&args, "--quiet"); > + strvec_push(&cp.args, "--quiet"); > must_die_on_failure = 1; > break; > case SM_UPDATE_COMMAND: > - git_cmd = 0; > - strvec_push(&args, ud->update_strategy.command); > + cp.use_shell = 1; > + strvec_push(&cp.args, ud->update_strategy.command); > must_die_on_failure = 1; > break; > default: > BUG("unexpected update strategy type: %s", > submodule_strategy_to_string(&ud->update_strategy)); > } > - strvec_push(&args, oid); > + strvec_push(&cp.args, oid); > > - prepare_submodule_repo_env(&child_env); > - if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL, > - ud->sm_path, child_env.v)) { > + cp.dir = xstrdup(ud->sm_path); > + prepare_submodule_repo_env(&cp.env_array); > + if (run_command(&cp)) { > switch (ud->update_strategy.type) { > case SM_UPDATE_CHECKOUT: > printf(_("Unable to checkout '%s' in submodule path '%s'"), If this series is re-arranged so that this comes first, this compiles just fine & passes all tests. So I wonder if we can peel this and perhaps other such easy to review prep changes off into its own series, since this one has grown to 20 patches. We could then hopefully fast-track those easy-to-review prep changes, which would make the "real" series to follow smaller and easier to review/grok. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 05/20] builtin/submodule--helper.c: reformat designated initializers 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (3 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 04/20] submodule--helper: run update using child process struct Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 06/20] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo ` (16 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> The second hunk here will make a subsequent commit's diff smaller, and let's do the first and third hunks while we're at it so that we consistently format all of these. Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index db71e6f4ec..9f79bdf4d5 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1654,7 +1654,10 @@ struct module_clone_data { unsigned int require_init: 1; int single_branch; }; -#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 } +#define MODULE_CLONE_DATA_INIT { \ + .reference = STRING_LIST_INIT_NODUP, \ + .single_branch = -1, \ +} struct submodule_alternate_setup { const char *submodule_name; @@ -2047,7 +2050,9 @@ struct update_data { unsigned int nofetch: 1; unsigned int just_cloned: 1; }; -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } +#define UPDATE_DATA_INIT { \ + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ +} static void next_submodule_warn_missing(struct submodule_update_clone *suc, struct strbuf *out, const char *displaypath) @@ -3013,7 +3018,9 @@ struct add_data { unsigned int progress: 1; unsigned int dissociate: 1; }; -#define ADD_DATA_INIT { .depth = -1 } +#define ADD_DATA_INIT { \ + .depth = -1, \ +} static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) { -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 06/20] builtin/submodule--helper.c: rename option variables to "opt" 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (4 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 05/20] builtin/submodule--helper.c: reformat designated initializers Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 07/20] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo ` (15 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Rename the "suc" variable in update_clone() to "opt", and do the same for the "update_data" variable in run_update_procedure(). The only reason for this change is to make the subsequent commit's diff smaller, by doing this rename we can "anchor" the diff better, as it "borrow" most of the options declared here as-is as far as the diff rename detection is concerned. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 74 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9f79bdf4d5..c2d4fd0347 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2517,36 +2517,36 @@ static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &suc.dissociate, + OPT_BOOL(0, "dissociate", &opt.dissociate, N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &suc.depth, "<depth>", + OPT_STRING(0, "depth", &opt.depth, "<depth>", N_("create a shallow clone truncated to the " "specified number of revisions")), - OPT_INTEGER('j', "jobs", &suc.max_jobs, + OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &suc.progress, + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, N_("force cloning progress")), - OPT_BOOL(0, "require-init", &suc.require_init, + OPT_BOOL(0, "require-init", &opt.require_init, N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &suc.single_branch, + OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() }; @@ -2555,32 +2555,32 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - suc.prefix = prefix; + opt.prefix = prefix; - update_clone_config_from_gitmodules(&suc.max_jobs); - git_config(git_update_clone_config, &suc.max_jobs); + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); if (update) - if (parse_submodule_update_strategy(update, &suc.update) < 0) + if (parse_submodule_update_strategy(update, &opt.update) < 0) die(_("bad value for update parameter")); - if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) return 1; if (pathspec.nr) - suc.warn_if_uninitialized = 1; + opt.warn_if_uninitialized = 1; - return update_submodules(&suc); + return update_submodules(&opt); } static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; - struct update_data update_data = UPDATE_DATA_INIT; + struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), @@ -2589,20 +2589,20 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) N_("don't fetch new objects from the remote site")), OPT_BOOL(0, "just-cloned", &just_cloned, N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")), + OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"), + OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"), + OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, parse_opt_object_id), OPT_END() @@ -2618,27 +2618,27 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - update_data.force = !!force; - update_data.quiet = !!quiet; - update_data.nofetch = !!nofetch; - update_data.just_cloned = !!just_cloned; - update_data.sm_path = argv[0]; + opt.force = !!force; + opt.quiet = !!quiet; + opt.nofetch = !!nofetch; + opt.just_cloned = !!just_cloned; + opt.sm_path = argv[0]; - if (update_data.recursive_prefix) - prefixed_path = xstrfmt("%s%s", update_data.recursive_prefix, update_data.sm_path); + if (opt.recursive_prefix) + prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); else - prefixed_path = xstrdup(update_data.sm_path); + prefixed_path = xstrdup(opt.sm_path); - update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix); + opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - determine_submodule_update_strategy(the_repository, update_data.just_cloned, - update_data.sm_path, update, - &update_data.update_strategy); + determine_submodule_update_strategy(the_repository, opt.just_cloned, + opt.sm_path, update, + &opt.update_strategy); free(prefixed_path); - if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) - return do_run_update_procedure(&update_data); + if (!oideq(&opt.oid, &opt.suboid) || opt.force) + return do_run_update_procedure(&opt); return 3; } -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 07/20] submodule--helper: don't use bitfield indirection for parse_options() 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (5 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 06/20] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 08/20] submodule tests: test for init and update failure output Glen Choo ` (14 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Do away with the indirection of local variables added in c51f8f94e5b (submodule--helper: run update procedures from C, 2021-08-24). These were only needed because in C you can't get a pointer to a single bit, so we were using intermediate variables instead. This will also make a subsequent large commit's diff smaller. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- builtin/submodule--helper.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c2d4fd0347..4a0890954e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2045,10 +2045,10 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; - unsigned int force: 1; - unsigned int quiet: 1; - unsigned int nofetch: 1; - unsigned int just_cloned: 1; + unsigned int force; + unsigned int quiet; + unsigned int nofetch; + unsigned int just_cloned; }; #define UPDATE_DATA_INIT { \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ @@ -2578,16 +2578,17 @@ static int update_clone(int argc, const char **argv, const char *prefix) static int run_update_procedure(int argc, const char **argv, const char *prefix) { - int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; char *prefixed_path, *update = NULL; struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { - OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")), - OPT__FORCE(&force, N_("force checkout updates"), 0), - OPT_BOOL('N', "no-fetch", &nofetch, + OPT__QUIET(&opt.quiet, + N_("suppress output for update by rebase or merge")), + OPT__FORCE(&opt.force, N_("force checkout updates"), + 0), + OPT_BOOL('N', "no-fetch", &opt.nofetch, N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &just_cloned, + OPT_BOOL(0, "just-cloned", &opt.just_cloned, N_("overrides update mode in case the repository is a fresh clone")), OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), OPT_STRING(0, "prefix", &prefix, @@ -2618,10 +2619,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) if (argc != 1) usage_with_options(usage, options); - opt.force = !!force; - opt.quiet = !!quiet; - opt.nofetch = !!nofetch; - opt.just_cloned = !!just_cloned; opt.sm_path = argv[0]; if (opt.recursive_prefix) -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 08/20] submodule tests: test for init and update failure output 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (6 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 07/20] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 09/20] submodule--helper: remove update-module-mode Glen Choo ` (13 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Amend some submodule tests to test for the failure output of "git submodule [update|init]". The lack of such tests hid a regression in an earlier version of a subsequent commit. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- t/t7406-submodule-update.sh | 14 ++++++++++++-- t/t7408-submodule-reference.sh | 14 +++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 11cccbb333..7764c1c3cb 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -205,8 +205,18 @@ test_expect_success 'submodule update should fail due to local changes' ' (cd submodule && compare_head ) && - test_must_fail git submodule update submodule - ) + test_must_fail git submodule update submodule 2>../actual.raw + ) && + sed "s/^> //" >expect <<-\EOF && + > error: Your local changes to the following files would be overwritten by checkout: + > file + > Please commit your changes or stash them before you switch branches. + > Aborting + > fatal: Unable to checkout OID in submodule path '\''submodule'\'' + EOF + sed -e "s/checkout $SQ[^$SQ]*$SQ/checkout OID/" <actual.raw >actual && + test_cmp expect actual + ' test_expect_success 'submodule update should throw away changes with --force ' ' (cd super && diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index a3892f494b..c3a4545510 100755 --- a/t/t7408-submodule-reference.sh +++ b/t/t7408-submodule-reference.sh @@ -193,7 +193,19 @@ test_expect_success 'missing nested submodule alternate fails clone and submodul cd supersuper-clone && check_that_two_of_three_alternates_are_used && # update of the submodule fails - test_must_fail git submodule update --init --recursive + cat >expect <<-\EOF && + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\''. Retry scheduled + fatal: submodule '\''sub-dissociate'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub-dissociate'\''. Retry scheduled + fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist + Failed to clone '\''sub'\'' a second time, aborting + fatal: Failed to recurse into submodule path ... + EOF + test_must_fail git submodule update --init --recursive 2>err && + grep -e fatal: -e ^Failed err >actual.raw && + sed -e "s/path $SQ[^$SQ]*$SQ/path .../" <actual.raw >actual && + test_cmp expect actual ) ' -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 09/20] submodule--helper: remove update-module-mode 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (7 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 08/20] submodule tests: test for init and update failure output Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:35 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 10/20] submodule--helper: reorganize code for sh to C conversion Glen Choo ` (12 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason This is dead code - it has not been used since c51f8f94e5 (submodule--helper: run update procedures from C, 2021-08-24). Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4a0890954e..e0cc1c1b79 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1965,29 +1965,6 @@ static void determine_submodule_update_strategy(struct repository *r, free(key); } -static int module_update_module_mode(int argc, const char **argv, const char *prefix) -{ - const char *path, *update = NULL; - int just_cloned; - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; - - if (argc < 3 || argc > 4) - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); - - just_cloned = git_config_int("just_cloned", argv[1]); - path = argv[2]; - - if (argc == 4) - update = argv[3]; - - determine_submodule_update_strategy(the_repository, - just_cloned, path, update, - &update_strategy); - fputs(submodule_strategy_to_string(&update_strategy), stdout); - - return 0; -} - struct update_clone_data { const struct submodule *sub; struct object_id oid; @@ -3388,7 +3365,6 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-module-mode", module_update_module_mode, 0}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, {"ensure-core-worktree", ensure_core_worktree, 0}, -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 09/20] submodule--helper: remove update-module-mode 2022-02-10 9:28 ` [PATCH v7 09/20] submodule--helper: remove update-module-mode Glen Choo @ 2022-02-12 14:35 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:35 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > This is dead code - it has not been used since c51f8f94e5 > (submodule--helper: run update procedures from C, 2021-08-24). > > Signed-off-by: Glen Choo <chooglen@google.com> > --- > builtin/submodule--helper.c | 24 ------------------------ > 1 file changed, 24 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 4a0890954e..e0cc1c1b79 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -1965,29 +1965,6 @@ static void determine_submodule_update_strategy(struct repository *r, > free(key); > } > > -static int module_update_module_mode(int argc, const char **argv, const char *prefix) > -{ > - const char *path, *update = NULL; > - int just_cloned; > - struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT }; > - > - if (argc < 3 || argc > 4) > - die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]"); > - > - just_cloned = git_config_int("just_cloned", argv[1]); > - path = argv[2]; > - > - if (argc == 4) > - update = argv[3]; > - > - determine_submodule_update_strategy(the_repository, > - just_cloned, path, update, > - &update_strategy); > - fputs(submodule_strategy_to_string(&update_strategy), stdout); > - > - return 0; > -} > - > struct update_clone_data { > const struct submodule *sub; > struct object_id oid; > @@ -3388,7 +3365,6 @@ static struct cmd_struct commands[] = { > {"name", module_name, 0}, > {"clone", module_clone, 0}, > {"add", module_add, SUPPORT_SUPER_PREFIX}, > - {"update-module-mode", module_update_module_mode, 0}, > {"update-clone", update_clone, 0}, > {"run-update-procedure", run_update_procedure, 0}, > {"ensure-core-worktree", ensure_core_worktree, 0}, Nice catch! Re my comment on 04/20 in <220212.86y22gxig0.gmgdl@evledraar.gmail.com> at least 04..09/20 could be split into such a "trivial refactors for later changes" series, and it would make sense to lead with this (and any other deletions of already-dead code). ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 10/20] submodule--helper: reorganize code for sh to C conversion 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (8 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 09/20] submodule--helper: remove update-module-mode Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 11/20] submodule--helper run-update-procedure: remove --suboid Glen Choo ` (11 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Introduce a function, update_submodule2(), that performs an update for one submodule. This function will implement the functionality of run-update-procedure and its surrounding shell code in submodule.sh. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index e0cc1c1b79..0b5120734a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2553,6 +2553,11 @@ static int update_clone(int argc, const char **argv, const char *prefix) return update_submodules(&opt); } +/* + * NEEDSWORK: Use a forward declaration to avoid moving + * run_update_procedure() (which will be removed soon). + */ +static int update_submodule2(struct update_data *update_data); static int run_update_procedure(int argc, const char **argv, const char *prefix) { char *prefixed_path, *update = NULL; @@ -2610,11 +2615,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) &opt.update_strategy); free(prefixed_path); - - if (!oideq(&opt.oid, &opt.suboid) || opt.force) - return do_run_update_procedure(&opt); - - return 3; + return update_submodule2(&opt); } static int resolve_relative_path(int argc, const char **argv, const char *prefix) @@ -2978,6 +2979,15 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } +/* NEEDSWORK: this is a temporary name until we delete update_submodule() */ +static int update_submodule2(struct update_data *update_data) +{ + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) + return do_run_update_procedure(update_data); + + return 3; +} + struct add_data { const char *prefix; const char *branch; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 11/20] submodule--helper run-update-procedure: remove --suboid 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (9 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 10/20] submodule--helper: reorganize code for sh to C conversion Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote Glen Choo ` (10 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach run-update-procedure to determine the oid of the submodule's HEAD instead of doing it in git-subomdule.sh. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 12 +++++++++--- git-submodule.sh | 8 +------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0b5120734a..a26477ce04 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2585,9 +2585,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), - OPT_CALLBACK_F(0, "suboid", &opt.suboid, N_("subsha1"), - N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG, - parse_opt_object_id), OPT_END() }; @@ -2982,6 +2979,15 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) /* NEEDSWORK: this is a temporary name until we delete update_submodule() */ static int update_submodule2(struct update_data *update_data) { + /* NEEDSWORK: fix the style issues e.g. braces */ + if (update_data->just_cloned) { + oidcpy(&update_data->suboid, null_oid()); + } else { + if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); + } + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) return do_run_update_procedure(update_data); diff --git a/git-submodule.sh b/git-submodule.sh index 652861aa66..d48c314f01 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -391,14 +391,9 @@ cmd_update() displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - if test $just_cloned -eq 1 + if test $just_cloned -eq 0 then - subsha1= - else just_cloned= - subsha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify HEAD) || - die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" fi if test -n "$remote" @@ -426,7 +421,6 @@ cmd_update() ${update:+--update "$update"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${sha1:+--oid "$sha1"} \ - ${subsha1:+--suboid "$subsha1"} \ "--" \ "$sm_path") -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (10 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 11/20] submodule--helper run-update-procedure: remove --suboid Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:38 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 13/20] submodule--helper: remove ensure-core-worktree Glen Choo ` (9 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach run-update-procedure to handle --remote instead of parsing --remote in git-submodule.sh. As a result, "git submodule--helper print-default-remote" has no more callers, so remove it. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 39 ++++++++++++++++++++++--------------- git-submodule.sh | 30 +--------------------------- 2 files changed, 24 insertions(+), 45 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a26477ce04..15ae986692 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -71,21 +71,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository); } -static int print_default_remote(int argc, const char **argv, const char *prefix) -{ - char *remote; - - if (argc != 1) - die(_("submodule--helper print-default-remote takes no arguments")); - - remote = get_default_remote(); - if (remote) - printf("%s\n", remote); - - free(remote); - return 0; -} - static int starts_with_dot_slash(const char *str) { return str[0] == '.' && is_dir_sep(str[1]); @@ -2026,6 +2011,7 @@ struct update_data { unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; + unsigned int remote; }; #define UPDATE_DATA_INIT { \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ @@ -2585,6 +2571,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, parse_opt_object_id), + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), OPT_END() }; @@ -2988,6 +2976,25 @@ static int update_submodule2(struct update_data *update_data) update_data->displaypath); } + if (update_data->remote) { + char *remote_name = get_default_remote_submodule(update_data->sm_path); + const char *branch = remote_submodule_branch(update_data->sm_path); + char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch); + + if (!update_data->nofetch) { + if (fetch_in_submodule(update_data->sm_path, update_data->depth, + 0, NULL)) + die(_("Unable to fetch in submodule path '%s'"), + update_data->sm_path); + } + + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + die(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + + free(remote_ref); + } + if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) return do_run_update_procedure(update_data); @@ -3389,10 +3396,10 @@ static struct cmd_struct commands[] = { {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"status", module_status, SUPPORT_SUPER_PREFIX}, - {"print-default-remote", print_default_remote, 0}, {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, + /* NEEDSWORK: remote-branch is also obsolete */ {"remote-branch", resolve_remote_submodule_branch, 0}, {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index d48c314f01..29fd69250d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,20 +246,6 @@ cmd_deinit() git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" } -# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] -# Because arguments are positional, use an empty string to omit <depth> -# but include <sha1>. -fetch_in_submodule () ( - sanitize_submodule_env && - cd "$1" && - if test $# -eq 3 - then - echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"} - else - git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"} - fi -) - # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -396,21 +382,6 @@ cmd_update() just_cloned= fi - if test -n "$remote" - then - branch=$(git submodule--helper remote-branch "$sm_path") - if test -z "$nofetch" - then - # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" $depth || - die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" - fi - remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote) - sha1=$(sanitize_submodule_env; cd "$sm_path" && - git rev-parse --verify "${remote_name}/${branch}") || - die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" - fi - out=$(git submodule--helper run-update-procedure \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${GIT_QUIET:+--quiet} \ @@ -421,6 +392,7 @@ cmd_update() ${update:+--update "$update"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${sha1:+--oid "$sha1"} \ + ${remote:+--remote} \ "--" \ "$sm_path") -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote 2022-02-10 9:28 ` [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote Glen Choo @ 2022-02-12 14:38 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:38 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > #define UPDATE_DATA_INIT { \ > .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ > @@ -2585,6 +2571,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) > OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), > N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, > parse_opt_object_id), > + OPT_BOOL(0, "remote", &opt.remote, > + N_("use SHA-1 of submodule's remote tracking branch")), For some things the references to SHA-1 are faithfully copying existing test, but for new things let's use "object" instead. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 13/20] submodule--helper: remove ensure-core-worktree 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (11 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 14/20] submodule--helper update-clone: learn --init Glen Choo ` (8 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Move the logic of "git submodule--helper ensure-core-worktree" into run-update-procedure. Since the ensure-core-worktree command is obsolete, remove it. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 13 +++---------- git-submodule.sh | 2 -- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 15ae986692..a05aea5cd6 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2746,17 +2746,11 @@ static int push_check(int argc, const char **argv, const char *prefix) return 0; } -static int ensure_core_worktree(int argc, const char **argv, const char *prefix) +static void ensure_core_worktree(const char *path) { - const char *path; const char *cw; struct repository subrepo; - if (argc != 2) - BUG("submodule--helper ensure-core-worktree <path>"); - - path = argv[1]; - if (repo_submodule_init(&subrepo, the_repository, path, null_oid())) die(_("could not get a repository handle for submodule '%s'"), path); @@ -2776,8 +2770,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix) free(abs_path); strbuf_release(&sb); } - - return 0; } static int absorb_git_dirs(int argc, const char **argv, const char *prefix) @@ -2967,6 +2959,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) /* NEEDSWORK: this is a temporary name until we delete update_submodule() */ static int update_submodule2(struct update_data *update_data) { + ensure_core_worktree(update_data->sm_path); + /* NEEDSWORK: fix the style issues e.g. braces */ if (update_data->just_cloned) { oidcpy(&update_data->suboid, null_oid()); @@ -3390,7 +3384,6 @@ static struct cmd_struct commands[] = { {"add", module_add, SUPPORT_SUPER_PREFIX}, {"update-clone", update_clone, 0}, {"run-update-procedure", run_update_procedure, 0}, - {"ensure-core-worktree", ensure_core_worktree, 0}, {"relative-path", resolve_relative_path, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 29fd69250d..aa9c898e1c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -373,8 +373,6 @@ cmd_update() do die_if_unmatched "$quickabort" "$sha1" - git submodule--helper ensure-core-worktree "$sm_path" || exit 1 - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") if test $just_cloned -eq 0 -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 14/20] submodule--helper update-clone: learn --init 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (12 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 13/20] submodule--helper: remove ensure-core-worktree Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 15/20] submodule--helper: move functions around Glen Choo ` (7 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Teach "git submodule--helper update-clone" the --init flag and remove the corresponding shell code. When the `--init` flag is passed to the subcommand, we do not spawn a new subprocess and call `submodule--helper init` on the submodule paths, because the Git machinery is not able to pick up the configuration changes introduced by that init call. So we instead run the `init_submodule_cb()` callback over each submodule in the same process. [1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/ Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 26 ++++++++++++++++++++++++++ git-submodule.sh | 9 +++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a05aea5cd6..5635f0c48b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1989,6 +1989,7 @@ struct submodule_update_clone { int failed_clones_nr, failed_clones_alloc; int max_jobs; + unsigned int init; }; #define SUBMODULE_UPDATE_CLONE_INIT { \ .list = MODULE_LIST_INIT, \ @@ -2483,6 +2484,8 @@ static int update_clone(int argc, const char **argv, const char *prefix) struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), @@ -2536,6 +2539,29 @@ static int update_clone(int argc, const char **argv, const char *prefix) if (pathspec.nr) opt.warn_if_uninitialized = 1; + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + return update_submodules(&opt); } diff --git a/git-submodule.sh b/git-submodule.sh index aa9c898e1c..3ccf2388bf 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -347,14 +347,11 @@ cmd_update() shift done - if test -n "$init" - then - cmd_init "--" "$@" || return - fi - { - git submodule--helper update-clone ${GIT_QUIET:+--quiet} \ + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ + ${GIT_QUIET:+--quiet} \ ${progress:+"--progress"} \ + ${init:+--init} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 15/20] submodule--helper: move functions around 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (13 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 14/20] submodule--helper update-clone: learn --init Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 16/20] submodule--helper: reduce logic in run_update_procedure() Glen Choo ` (6 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason A subsequent commit will change the internals of several functions and arrange them in a more logical manner. Move these functions to their final positions so that the diff is smaller. Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 228 ++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5635f0c48b..0ab8f9d49f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2451,120 +2451,6 @@ static void update_submodule(struct update_clone_data *ucd) ucd->sub->path); } -static int update_submodules(struct submodule_update_clone *suc) -{ - int i; - - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, suc, "submodule", - "parallel/update"); - - /* - * We saved the output and put it out all at once now. - * That means: - * - the listener does not have to interleave their (checkout) - * work with our fetching. The writes involved in a - * checkout involve more straightforward sequential I/O. - * - the listener can avoid doing any work if fetching failed. - */ - if (suc->quickstop) - return 1; - - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); - - return 0; -} - -static int update_clone(int argc, const char **argv, const char *prefix) -{ - const char *update = NULL; - struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; - - struct option module_update_clone_options[] = { - OPT_BOOL(0, "init", &opt.init, - N_("initialize uninitialized submodules before update")), - OPT_STRING(0, "prefix", &prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, - N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_STRING(0, "update", &update, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), - OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), - OPT_INTEGER('j', "jobs", &opt.max_jobs, - N_("parallel jobs")), - OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), - OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), - OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), - OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), - OPT_BOOL(0, "single-branch", &opt.single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_END() - }; - - const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), - NULL - }; - opt.prefix = prefix; - - update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); - - argc = parse_options(argc, argv, prefix, module_update_clone_options, - git_submodule_helper_usage, 0); - - if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) - die(_("bad value for update parameter")); - - if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) - return 1; - - if (pathspec.nr) - opt.warn_if_uninitialized = 1; - - if (opt.init) { - struct module_list list = MODULE_LIST_INIT; - struct init_cb info = INIT_CB_INIT; - - if (module_list_compute(argc, argv, opt.prefix, - &pathspec, &list) < 0) - return 1; - - /* - * If there are no path args and submodule.active is set then, - * by default, only initialize 'active' modules. - */ - if (!argc && git_config_get_value_multi("submodule.active")) - module_list_active(&list); - - info.prefix = opt.prefix; - info.superprefix = opt.recursive_prefix; - if (opt.quiet) - info.flags |= OPT_QUIET; - - for_each_listed_submodule(&list, init_submodule_cb, &info); - } - - return update_submodules(&opt); -} - /* * NEEDSWORK: Use a forward declaration to avoid moving * run_update_procedure() (which will be removed soon). @@ -3021,6 +2907,120 @@ static int update_submodule2(struct update_data *update_data) return 3; } +static int update_submodules(struct submodule_update_clone *suc) +{ + int i; + + run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, suc, "submodule", + "parallel/update"); + + /* + * We saved the output and put it out all at once now. + * That means: + * - the listener does not have to interleave their (checkout) + * work with our fetching. The writes involved in a + * checkout involve more straightforward sequential I/O. + * - the listener can avoid doing any work if fetching failed. + */ + if (suc->quickstop) + return 1; + + for (i = 0; i < suc->update_clone_nr; i++) + update_submodule(&suc->update_clone[i]); + + return 0; +} + +static int update_clone(int argc, const char **argv, const char *prefix) +{ + const char *update = NULL; + struct pathspec pathspec; + struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + + struct option module_update_clone_options[] = { + OPT_BOOL(0, "init", &opt.init, + N_("initialize uninitialized submodules before update")), + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("path into the working tree")), + OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, + N_("path"), + N_("path into the working tree, across nested " + "submodule boundaries")), + OPT_STRING(0, "update", &update, + N_("string"), + N_("rebase, merge, checkout or none")), + OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), + N_("reference repository")), + OPT_BOOL(0, "dissociate", &opt.dissociate, + N_("use --reference only while cloning")), + OPT_STRING(0, "depth", &opt.depth, "<depth>", + N_("create a shallow clone truncated to the " + "specified number of revisions")), + OPT_INTEGER('j', "jobs", &opt.max_jobs, + N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), + OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), + OPT_BOOL(0, "progress", &opt.progress, + N_("force cloning progress")), + OPT_BOOL(0, "require-init", &opt.require_init, + N_("disallow cloning into non-empty directory")), + OPT_BOOL(0, "single-branch", &opt.single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + NULL + }; + opt.prefix = prefix; + + update_clone_config_from_gitmodules(&opt.max_jobs); + git_config(git_update_clone_config, &opt.max_jobs); + + argc = parse_options(argc, argv, prefix, module_update_clone_options, + git_submodule_helper_usage, 0); + + if (update) + if (parse_submodule_update_strategy(update, &opt.update) < 0) + die(_("bad value for update parameter")); + + if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) + return 1; + + if (pathspec.nr) + opt.warn_if_uninitialized = 1; + + if (opt.init) { + struct module_list list = MODULE_LIST_INIT; + struct init_cb info = INIT_CB_INIT; + + if (module_list_compute(argc, argv, opt.prefix, + &pathspec, &list) < 0) + return 1; + + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + + info.prefix = opt.prefix; + info.superprefix = opt.recursive_prefix; + if (opt.quiet) + info.flags |= OPT_QUIET; + + for_each_listed_submodule(&list, init_submodule_cb, &info); + } + + return update_submodules(&opt); +} + struct add_data { const char *prefix; const char *branch; -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 15/20] submodule--helper: move functions around 2022-02-10 9:28 ` [PATCH v7 15/20] submodule--helper: move functions around Glen Choo @ 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:41 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > A subsequent commit will change the internals of several functions and > arrange them in a more logical manner. Move these functions to their > final positions so that the diff is smaller. Shouldn't we do this earlier & avoid the FIXME comment in 10/20? (maybe a subsequent fixup addresses it, haven't checked...) ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 16/20] submodule--helper: reduce logic in run_update_procedure() 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (14 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 15/20] submodule--helper: move functions around Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 17/20] submodule: move core cmd_update() logic to C Glen Choo ` (5 subsequent siblings) 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason A later commit will combine the "update-clone" and "run-update-procedure" commands, so run_update_procedure() will be removed. Prepare for this by moving as much logic as possible out of run_update_procedure() and into update_submodule2(). Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0ab8f9d49f..ff7ee73e1a 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2001,9 +2001,11 @@ struct submodule_update_clone { } struct update_data { + const char *prefix; const char *recursive_prefix; const char *sm_path; const char *displaypath; + const char *update_default; struct object_id oid; struct object_id suboid; struct submodule_update_strategy update_strategy; @@ -2458,7 +2460,6 @@ static void update_submodule(struct update_clone_data *ucd) static int update_submodule2(struct update_data *update_data); static int run_update_procedure(int argc, const char **argv, const char *prefix) { - char *prefixed_path, *update = NULL; struct update_data opt = UPDATE_DATA_INIT; struct option options[] = { @@ -2471,10 +2472,10 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "just-cloned", &opt.just_cloned, N_("overrides update mode in case the repository is a fresh clone")), OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &prefix, + OPT_STRING(0, "prefix", &opt.prefix, N_("path"), N_("path into the working tree")), - OPT_STRING(0, "update", &update, + OPT_STRING(0, "update", &opt.update_default, N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), @@ -2500,18 +2501,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) opt.sm_path = argv[0]; - if (opt.recursive_prefix) - prefixed_path = xstrfmt("%s%s", opt.recursive_prefix, opt.sm_path); - else - prefixed_path = xstrdup(opt.sm_path); - - opt.displaypath = get_submodule_displaypath(prefixed_path, prefix); - - determine_submodule_update_strategy(the_repository, opt.just_cloned, - opt.sm_path, update, - &opt.update_strategy); - - free(prefixed_path); return update_submodule2(&opt); } @@ -2871,8 +2860,24 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) /* NEEDSWORK: this is a temporary name until we delete update_submodule() */ static int update_submodule2(struct update_data *update_data) { + char *prefixed_path; + ensure_core_worktree(update_data->sm_path); + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrdup(update_data->sm_path); + + update_data->displaypath = get_submodule_displaypath(prefixed_path, + update_data->prefix); + free(prefixed_path); + + determine_submodule_update_strategy(the_repository, update_data->just_cloned, + update_data->sm_path, update_data->update_default, + &update_data->update_strategy); + /* NEEDSWORK: fix the style issues e.g. braces */ if (update_data->just_cloned) { oidcpy(&update_data->suboid, null_oid()); -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 17/20] submodule: move core cmd_update() logic to C 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (15 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 16/20] submodule--helper: reduce logic in run_update_procedure() Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-10 9:34 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid Glen Choo ` (4 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason From: Atharva Raykar <raykar.ath@gmail.com> This patch completes the conversion past the flag parsing of `submodule update` by introducing a helper subcommand called `submodule--helper update`. The behaviour of `submodule update` should remain the same after this patch. We add more fields to the `struct update_data` that are required by `struct submodule_update_clone` to be able to perform a clone, when that is needed to be done. Recursing on a submodule is done by calling a subprocess that launches `submodule--helper update`, with a modified `--recursive-prefix` and `--prefix` parameter. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 312 ++++++++++++++++++++++-------------- git-submodule.sh | 105 ++---------- 2 files changed, 201 insertions(+), 216 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index ff7ee73e1a..b895e88a64 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1977,7 +1977,6 @@ struct submodule_update_clone { const char *prefix; int single_branch; - /* to be consumed by git-submodule.sh */ struct update_clone_data *update_clone; int update_clone_nr; int update_clone_alloc; @@ -1989,7 +1988,6 @@ struct submodule_update_clone { int failed_clones_nr, failed_clones_alloc; int max_jobs; - unsigned int init; }; #define SUBMODULE_UPDATE_CLONE_INIT { \ .list = MODULE_LIST_INIT, \ @@ -2010,14 +2008,54 @@ struct update_data { struct object_id suboid; struct submodule_update_strategy update_strategy; int depth; + int recommend_shallow; + int single_branch; + int max_jobs; + unsigned int init; unsigned int force; unsigned int quiet; unsigned int nofetch; unsigned int just_cloned; unsigned int remote; + unsigned int recursive; + unsigned int progress; + unsigned int dissociate; + unsigned int require_init; + unsigned warn_if_uninitialized ; + struct string_list references; + struct module_list list; }; #define UPDATE_DATA_INIT { \ + .list = MODULE_LIST_INIT, \ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \ + .recommend_shallow = -1, \ + .references = STRING_LIST_INIT_DUP, \ + .single_branch = -1, \ + .max_jobs = 1, \ +} + +static void update_clone_from_update_data(struct submodule_update_clone *suc, + struct update_data *update_data) +{ + suc->prefix = update_data->prefix; + suc->recursive_prefix = update_data->recursive_prefix; + suc->max_jobs = update_data->max_jobs; + suc->progress = update_data->progress; + suc->quiet = update_data->quiet; + suc->dissociate = update_data->dissociate; + suc->require_init = update_data->require_init; + suc->single_branch = update_data->single_branch; + suc->warn_if_uninitialized = update_data->warn_if_uninitialized; + suc->list = update_data->list; + suc->update = update_data->update_strategy; + suc->recommend_shallow = update_data->recommend_shallow; + if (update_data->depth) + suc->depth = xstrfmt("--depth=%d", update_data->depth); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + string_list_append(&suc->references, item->string); + } } static void next_submodule_warn_missing(struct submodule_update_clone *suc, @@ -2356,40 +2394,35 @@ static int run_update_command(struct update_data *ud, int subforce) if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: - printf(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); + die_message(_("Unable to checkout '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_REBASE: - printf(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); + die_message(_("Unable to rebase '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_MERGE: - printf(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); + die_message(_("Unable to merge '%s' in submodule path '%s'"), + oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - printf(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); + die_message(_("Execution of '%s %s' failed in submodule path '%s'"), + ud->update_strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", submodule_strategy_to_string(&ud->update_strategy)); } - /* - * NEEDSWORK: We are currently printing to stdout with error - * return so that the shell caller handles the error output - * properly. Once we start handling the error messages within - * C, we should use die() instead. - */ if (must_die_on_failure) - return 2; - /* - * This signifies to the caller in shell that the command - * failed without dying - */ + exit(128); + + /* the command failed, but update must continue */ return 1; } + if (ud->quiet) + return 0; + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), @@ -2415,7 +2448,7 @@ static int run_update_command(struct update_data *ud, int subforce) return 0; } -static int do_run_update_procedure(struct update_data *ud) +static int run_update_procedure(struct update_data *ud) { int subforce = is_null_oid(&ud->suboid) || ud->force; @@ -2445,76 +2478,6 @@ static int do_run_update_procedure(struct update_data *ud) return run_update_command(ud, subforce); } -static void update_submodule(struct update_clone_data *ucd) -{ - fprintf(stdout, "dummy %s %d\t%s\n", - oid_to_hex(&ucd->oid), - ucd->just_cloned, - ucd->sub->path); -} - -/* - * NEEDSWORK: Use a forward declaration to avoid moving - * run_update_procedure() (which will be removed soon). - */ -static int update_submodule2(struct update_data *update_data); -static int run_update_procedure(int argc, const char **argv, const char *prefix) -{ - struct update_data opt = UPDATE_DATA_INIT; - - struct option options[] = { - OPT__QUIET(&opt.quiet, - N_("suppress output for update by rebase or merge")), - OPT__FORCE(&opt.force, N_("force checkout updates"), - 0), - OPT_BOOL('N', "no-fetch", &opt.nofetch, - N_("don't fetch new objects from the remote site")), - OPT_BOOL(0, "just-cloned", &opt.just_cloned, - N_("overrides update mode in case the repository is a fresh clone")), - OPT_INTEGER(0, "depth", &opt.depth, N_("depth for shallow fetch")), - OPT_STRING(0, "prefix", &opt.prefix, - N_("path"), - N_("path into the working tree")), - OPT_STRING(0, "update", &opt.update_default, - N_("string"), - N_("rebase, merge, checkout or none")), - OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), - N_("path into the working tree, across nested " - "submodule boundaries")), - OPT_CALLBACK_F(0, "oid", &opt.oid, N_("sha1"), - N_("SHA1 expected by superproject"), PARSE_OPT_NONEG, - parse_opt_object_id), - OPT_BOOL(0, "remote", &opt.remote, - N_("use SHA-1 of submodule's remote tracking branch")), - OPT_END() - }; - - const char *const usage[] = { - N_("git submodule--helper run-update-procedure [<options>] <path>"), - NULL - }; - - argc = parse_options(argc, argv, prefix, options, usage, 0); - - if (argc != 1) - usage_with_options(usage, options); - - opt.sm_path = argv[0]; - - return update_submodule2(&opt); -} - -static int resolve_relative_path(int argc, const char **argv, const char *prefix) -{ - struct strbuf sb = STRBUF_INIT; - if (argc != 3) - die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc); - - printf("%s", relative_path(argv[1], argv[2], &sb)); - strbuf_release(&sb); - return 0; -} - static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; @@ -2857,8 +2820,53 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } -/* NEEDSWORK: this is a temporary name until we delete update_submodule() */ -static int update_submodule2(struct update_data *update_data) +static void update_data_to_args(struct update_data *update_data, struct strvec *args) +{ + strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); + strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + /* + * NEEDSWORK: the equivalent code in git-submodule.sh does not + * pass --prefix, so this shouldn't either + */ + if (update_data->prefix) + strvec_pushl(args, "--prefix", update_data->prefix, NULL); + if (update_data->recursive_prefix) + strvec_pushl(args, "--recursive-prefix", + update_data->recursive_prefix, NULL); + if (update_data->quiet) + strvec_push(args, "--quiet"); + if (update_data->force) + strvec_push(args, "--force"); + if (update_data->init) + strvec_push(args, "--init"); + if (update_data->remote) + strvec_push(args, "--remote"); + if (update_data->nofetch) + strvec_push(args, "--no-fetch"); + if (update_data->dissociate) + strvec_push(args, "--dissociate"); + if (update_data->progress) + strvec_push(args, "--progress"); + if (update_data->require_init) + strvec_push(args, "--require-init"); + if (update_data->depth) + strvec_pushf(args, "--depth=%d", update_data->depth); + if (update_data->update_default) + strvec_pushl(args, "--update", update_data->update_default, NULL); + if (update_data->references.nr) { + struct string_list_item *item; + for_each_string_list_item(item, &update_data->references) + strvec_pushl(args, "--reference", item->string, NULL); + } + if (update_data->recommend_shallow == 0) + strvec_push(args, "--no-recommend-shallow"); + else if (update_data->recommend_shallow == 1) + strvec_push(args, "--recommend-shallow"); + if (update_data->single_branch >= 0) + strvec_push(args, "--single-branch"); +} + +static int update_submodule(struct update_data *update_data) { char *prefixed_path; @@ -2907,18 +2915,55 @@ static int update_submodule2(struct update_data *update_data) } if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) - return do_run_update_procedure(update_data); + if (run_update_procedure(update_data)) + return 1; + + if (update_data->recursive) { + struct child_process cp = CHILD_PROCESS_INIT; + struct update_data next = *update_data; + int res; + + if (update_data->recursive_prefix) + prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix, + update_data->sm_path); + else + prefixed_path = xstrfmt("%s/", update_data->sm_path); + + next.recursive_prefix = get_submodule_displaypath(prefixed_path, + update_data->prefix); + next.prefix = NULL; + oidcpy(&next.oid, null_oid()); + oidcpy(&next.suboid, null_oid()); + + cp.dir = update_data->sm_path; + cp.git_cmd = 1; + prepare_submodule_repo_env(&cp.env_array); + update_data_to_args(&next, &cp.args); - return 3; + /* die() if child process die()'d */ + res = run_command(&cp); + if (!res) + return 0; + die_message(_("Failed to recurse into submodule path '%s'"), + update_data->displaypath); + if (res == 128) + exit(res); + else if (res) + return 1; + } + + return 0; } -static int update_submodules(struct submodule_update_clone *suc) +static int update_submodules(struct update_data *update_data) { - int i; + int i, res = 0; + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_from_update_data(&suc, update_data); + run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task, update_clone_start_failure, - update_clone_task_finished, suc, "submodule", + update_clone_task_finished, &suc, "submodule", "parallel/update"); /* @@ -2929,50 +2974,69 @@ static int update_submodules(struct submodule_update_clone *suc) * checkout involve more straightforward sequential I/O. * - the listener can avoid doing any work if fetching failed. */ - if (suc->quickstop) - return 1; + if (suc.quickstop) { + res = 1; + goto cleanup; + } - for (i = 0; i < suc->update_clone_nr; i++) - update_submodule(&suc->update_clone[i]); + for (i = 0; i < suc.update_clone_nr; i++) { + struct update_clone_data ucd = suc.update_clone[i]; - return 0; + oidcpy(&update_data->oid, &ucd.oid); + update_data->just_cloned = ucd.just_cloned; + update_data->sm_path = ucd.sub->path; + + if (update_submodule(update_data)) + res = 1; + } + +cleanup: + string_list_clear(&update_data->references, 0); + return res; } -static int update_clone(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix) { - const char *update = NULL; struct pathspec pathspec; - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT; + struct update_data opt = UPDATE_DATA_INIT; + /* NEEDSWORK: update names and strings */ struct option module_update_clone_options[] = { + OPT__FORCE(&opt.force, N_("force checkout updates"), 0), OPT_BOOL(0, "init", &opt.init, N_("initialize uninitialized submodules before update")), - OPT_STRING(0, "prefix", &prefix, + OPT_BOOL(0, "remote", &opt.remote, + N_("use SHA-1 of submodule's remote tracking branch")), + OPT_BOOL(0, "recursive", &opt.recursive, + N_("traverse submodules recursively")), + OPT_BOOL('N', "no-fetch", &opt.nofetch, + N_("don't fetch new objects from the remote site")), + OPT_STRING(0, "prefix", &opt.prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), - OPT_STRING(0, "update", &update, + OPT_STRING(0, "update", &opt.update_default, N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), - N_("reference repository")), + N_("reference repository")), OPT_BOOL(0, "dissociate", &opt.dissociate, - N_("use --reference only while cloning")), - OPT_STRING(0, "depth", &opt.depth, "<depth>", - N_("create a shallow clone truncated to the " - "specified number of revisions")), + N_("use --reference only while cloning")), + OPT_INTEGER(0, "depth", &opt.depth, + N_("create a shallow clone truncated to the " + "specified number of revisions")), OPT_INTEGER('j', "jobs", &opt.max_jobs, N_("parallel jobs")), OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow, - N_("whether the initial clone should follow the shallow recommendation")), + N_("whether the initial clone should follow the shallow recommendation")), OPT__QUIET(&opt.quiet, N_("don't print cloning progress")), OPT_BOOL(0, "progress", &opt.progress, - N_("force cloning progress")), + N_("force cloning progress")), OPT_BOOL(0, "require-init", &opt.require_init, - N_("disallow cloning into non-empty directory")), + N_("disallow cloning into non-empty directory")), OPT_BOOL(0, "single-branch", &opt.single_branch, N_("clone only one branch, HEAD or --branch")), OPT_END() @@ -2982,16 +3046,18 @@ static int update_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), NULL }; - opt.prefix = prefix; update_clone_config_from_gitmodules(&opt.max_jobs); git_config(git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); + oidcpy(&opt.oid, null_oid()); + oidcpy(&opt.suboid, null_oid()); - if (update) - if (parse_submodule_update_strategy(update, &opt.update) < 0) + if (opt.update_default) + if (parse_submodule_update_strategy(opt.update_default, + &opt.update_strategy) < 0) die(_("bad value for update parameter")); if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) @@ -3413,9 +3479,7 @@ static struct cmd_struct commands[] = { {"name", module_name, 0}, {"clone", module_clone, 0}, {"add", module_add, SUPPORT_SUPER_PREFIX}, - {"update-clone", update_clone, 0}, - {"run-update-procedure", run_update_procedure, 0}, - {"relative-path", resolve_relative_path, 0}, + {"update", module_update, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"foreach", module_foreach, SUPPORT_SUPER_PREFIX}, {"init", module_init, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index 3ccf2388bf..d176469fb1 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -50,6 +50,7 @@ single_branch= jobs= recommend_shallow= +# NEEDSWORK this is now unused die_if_unmatched () { if test "$1" = "#unmatched" @@ -347,108 +348,28 @@ cmd_update() shift done - { - git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update-clone \ + # NEEDSWORK --super-prefix isn't actually supported by this + # command - we just pass the $prefix to --recursive-prefix. + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ ${GIT_QUIET:+--quiet} \ - ${progress:+"--progress"} \ + ${force:+--force} \ + ${progress:+--progress} \ + ${dissociate:+--dissociate} \ + ${remote:+--remote} \ + ${recursive:+--recursive} \ ${init:+--init} \ + ${require_init:+--require-init} \ + ${nofetch:+--no-fetch} \ ${wt_prefix:+--prefix "$wt_prefix"} \ ${prefix:+--recursive-prefix "$prefix"} \ ${update:+--update "$update"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ - ${depth:+--depth "$depth"} \ - ${require_init:+--require-init} \ + ${depth:+"$depth"} \ $single_branch \ $recommend_shallow \ $jobs \ -- \ - "$@" || echo "#unmatched" $? - } | { - err= - while read -r quickabort sha1 just_cloned sm_path - do - die_if_unmatched "$quickabort" "$sha1" - - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") - - if test $just_cloned -eq 0 - then - just_cloned= - fi - - out=$(git submodule--helper run-update-procedure \ - ${wt_prefix:+--prefix "$wt_prefix"} \ - ${GIT_QUIET:+--quiet} \ - ${force:+--force} \ - ${just_cloned:+--just-cloned} \ - ${nofetch:+--no-fetch} \ - ${depth:+"$depth"} \ - ${update:+--update "$update"} \ - ${prefix:+--recursive-prefix "$prefix"} \ - ${sha1:+--oid "$sha1"} \ - ${remote:+--remote} \ - "--" \ - "$sm_path") - - # exit codes for run-update-procedure: - # 0: update was successful, say command output - # 1: update procedure failed, but should not die - # 2 or 128: subcommand died during execution - # 3: no update procedure was run - res="$?" - case $res in - 0) - say "$out" - ;; - 1) - err="${err};fatal: $out" - continue - ;; - 2|128) - die_with_status $res "fatal: $out" - ;; - esac - - if test -n "$recursive" - then - ( - prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix") - wt_prefix= - sanitize_submodule_env - cd "$sm_path" && - eval cmd_update - ) - res=$? - if test $res -gt 0 - then - die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -ne 2 - then - err="${err};$die_msg" - continue - else - die_with_status $res "$die_msg" - fi - fi - fi - done - - if test -n "$err" - then - OIFS=$IFS - IFS=';' - for e in $err - do - if test -n "$e" - then - echo >&2 "$e" - fi - done - IFS=$OIFS - exit 1 - fi - } + "$@" } # -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 17/20] submodule: move core cmd_update() logic to C 2022-02-10 9:28 ` [PATCH v7 17/20] submodule: move core cmd_update() logic to C Glen Choo @ 2022-02-10 9:34 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:34 UTC (permalink / raw) To: git Cc: Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Here is the diff between this tree (+) and that of v5's [1] (-). [1] https://lore.kernel.org/git/patch-v5-9.9-e8e57606ee9-20220128T125206Z-avarab@gmail.com ----- >8 --------- >8 --------- >8 --------- >8 --------- >8 ---- diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 1c28b6f479..b895e88a64 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2003,6 +2003,7 @@ struct update_data { const char *recursive_prefix; const char *sm_path; const char *displaypath; + const char *update_default; struct object_id oid; struct object_id suboid; struct submodule_update_strategy update_strategy; @@ -2355,15 +2356,8 @@ static int run_update_command(struct update_data *ud, int subforce) struct child_process cp = CHILD_PROCESS_INIT; char *oid = oid_to_hex(&ud->oid); int must_die_on_failure = 0; - struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT; - if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned) - determine_submodule_update_strategy(the_repository, ud->just_cloned, - ud->sm_path, NULL, &strategy); - else - strategy = ud->update_strategy; - - switch (strategy.type) { + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-q", NULL); @@ -2386,45 +2380,41 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: cp.use_shell = 1; - strvec_push(&cp.args, strategy.command); + strvec_push(&cp.args, ud->update_strategy.command); must_die_on_failure = 1; break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&strategy)); + submodule_strategy_to_string(&ud->update_strategy)); } strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); prepare_submodule_repo_env(&cp.env_array); if (run_command(&cp)) { - switch (strategy.type) { + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: die_message(_("Unable to checkout '%s' in submodule path '%s'"), oid, ud->displaypath); break; case SM_UPDATE_REBASE: - if (!must_die_on_failure) - break; - die(_("Unable to rebase '%s' in submodule path '%s'"), + die_message(_("Unable to rebase '%s' in submodule path '%s'"), oid, ud->displaypath); break; case SM_UPDATE_MERGE: - if (!must_die_on_failure) - break; - die(_("Unable to merge '%s' in submodule path '%s'"), + die_message(_("Unable to merge '%s' in submodule path '%s'"), oid, ud->displaypath); break; case SM_UPDATE_COMMAND: - if (!must_die_on_failure) - break; - die(_("Execution of '%s %s' failed in submodule path '%s'"), - strategy.command, oid, ud->displaypath); + die_message(_("Execution of '%s %s' failed in submodule path '%s'"), + ud->update_strategy.command, oid, ud->displaypath); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&strategy)); + submodule_strategy_to_string(&ud->update_strategy)); } + if (must_die_on_failure) + exit(128); /* the command failed, but update must continue */ return 1; @@ -2433,7 +2423,7 @@ static int run_update_command(struct update_data *ud, int subforce) if (ud->quiet) return 0; - switch (strategy.type) { + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), ud->displaypath, oid); @@ -2448,11 +2438,11 @@ static int run_update_command(struct update_data *ud, int subforce) break; case SM_UPDATE_COMMAND: printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, strategy.command, oid); + ud->displaypath, ud->update_strategy.command, oid); break; default: BUG("unexpected update strategy type: %s", - submodule_strategy_to_string(&strategy)); + submodule_strategy_to_string(&ud->update_strategy)); } return 0; @@ -2832,10 +2822,12 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) static void update_data_to_args(struct update_data *update_data, struct strvec *args) { - const char *update = submodule_strategy_to_string(&update_data->update_strategy); - strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); strvec_pushf(args, "--jobs=%d", update_data->max_jobs); + /* + * NEEDSWORK: the equivalent code in git-submodule.sh does not + * pass --prefix, so this shouldn't either + */ if (update_data->prefix) strvec_pushl(args, "--prefix", update_data->prefix, NULL); if (update_data->recursive_prefix) @@ -2859,8 +2851,8 @@ static void update_data_to_args(struct update_data *update_data, struct strvec * strvec_push(args, "--require-init"); if (update_data->depth) strvec_pushf(args, "--depth=%d", update_data->depth); - if (update) - strvec_pushl(args, "--update", update, NULL); + if (update_data->update_default) + strvec_pushl(args, "--update", update_data->update_default, NULL); if (update_data->references.nr) { struct string_list_item *item; for_each_string_list_item(item, &update_data->references) @@ -2890,6 +2882,11 @@ static int update_submodule(struct update_data *update_data) update_data->prefix); free(prefixed_path); + determine_submodule_update_strategy(the_repository, update_data->just_cloned, + update_data->sm_path, update_data->update_default, + &update_data->update_strategy); + + /* NEEDSWORK: fix the style issues e.g. braces */ if (update_data->just_cloned) { oidcpy(&update_data->suboid, null_oid()); } else { @@ -3000,10 +2997,10 @@ static int update_submodules(struct update_data *update_data) static int module_update(int argc, const char **argv, const char *prefix) { - const char *update = NULL; struct pathspec pathspec; struct update_data opt = UPDATE_DATA_INIT; + /* NEEDSWORK: update names and strings */ struct option module_update_clone_options[] = { OPT__FORCE(&opt.force, N_("force checkout updates"), 0), OPT_BOOL(0, "init", &opt.init, @@ -3021,7 +3018,7 @@ static int module_update(int argc, const char **argv, const char *prefix) N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), - OPT_STRING(0, "update", &update, + OPT_STRING(0, "update", &opt.update_default, N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"), @@ -3058,8 +3055,8 @@ static int module_update(int argc, const char **argv, const char *prefix) oidcpy(&opt.oid, null_oid()); oidcpy(&opt.suboid, null_oid()); - if (update) - if (parse_submodule_update_strategy(update, + if (opt.update_default) + if (parse_submodule_update_strategy(opt.update_default, &opt.update_strategy) < 0) die(_("bad value for update parameter")); @@ -3490,6 +3487,7 @@ static struct cmd_struct commands[] = { {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, + /* NEEDSWORK: remote-branch is also obsolete */ {"remote-branch", resolve_remote_submodule_branch, 0}, {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, diff --git a/git-submodule.sh b/git-submodule.sh index bcd8b92aab..d176469fb1 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -50,6 +50,7 @@ single_branch= jobs= recommend_shallow= +# NEEDSWORK this is now unused die_if_unmatched () { if test "$1" = "#unmatched" @@ -347,6 +348,8 @@ cmd_update() shift done + # NEEDSWORK --super-prefix isn't actually supported by this + # command - we just pass the $prefix to --recursive-prefix. git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ ${GIT_QUIET:+--quiet} \ ${force:+--force} \ ^ permalink raw reply related [flat|nested] 142+ messages in thread
* [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (16 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 17/20] submodule: move core cmd_update() logic to C Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote Glen Choo ` (3 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b895e88a64..98d8910930 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2886,14 +2886,11 @@ static int update_submodule(struct update_data *update_data) update_data->sm_path, update_data->update_default, &update_data->update_strategy); - /* NEEDSWORK: fix the style issues e.g. braces */ - if (update_data->just_cloned) { + if (update_data->just_cloned) oidcpy(&update_data->suboid, null_oid()); - } else { - if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) - die(_("Unable to find current revision in submodule path '%s'"), - update_data->displaypath); - } + else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + die(_("Unable to find current revision in submodule path '%s'"), + update_data->displaypath); if (update_data->remote) { char *remote_name = get_default_remote_submodule(update_data->sm_path); -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid 2022-02-10 9:28 ` [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid Glen Choo @ 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:41 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > Signed-off-by: Glen Choo <chooglen@google.com> > --- > builtin/submodule--helper.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index b895e88a64..98d8910930 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -2886,14 +2886,11 @@ static int update_submodule(struct update_data *update_data) > update_data->sm_path, update_data->update_default, > &update_data->update_strategy); > > - /* NEEDSWORK: fix the style issues e.g. braces */ > - if (update_data->just_cloned) { > + if (update_data->just_cloned) > oidcpy(&update_data->suboid, null_oid()); > - } else { > - if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) > - die(_("Unable to find current revision in submodule path '%s'"), > - update_data->displaypath); > - } > + else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) > + die(_("Unable to find current revision in submodule path '%s'"), > + update_data->displaypath); > > if (update_data->remote) { > char *remote_name = get_default_remote_submodule(update_data->sm_path); This fixup looks good, let's apply this fix-up to the relevant preceding commit. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (17 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:43 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 20/20] fixup! submodule: move core cmd_update() logic to C Glen Choo ` (2 subsequent siblings) 21 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 98d8910930..5d5302b50b 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2516,23 +2516,6 @@ static const char *remote_submodule_branch(const char *path) return branch; } -static int resolve_remote_submodule_branch(int argc, const char **argv, - const char *prefix) -{ - const char *ret; - struct strbuf sb = STRBUF_INIT; - if (argc != 2) - die("submodule--helper remote-branch takes exactly one arguments, got %d", argc); - - ret = remote_submodule_branch(argv[1]); - if (!ret) - die("submodule %s doesn't exist", argv[1]); - - printf("%s", ret); - strbuf_release(&sb); - return 0; -} - static int push_check(int argc, const char **argv, const char *prefix) { struct remote *remote; @@ -3484,8 +3467,6 @@ static struct cmd_struct commands[] = { {"sync", module_sync, SUPPORT_SUPER_PREFIX}, {"deinit", module_deinit, 0}, {"summary", module_summary, SUPPORT_SUPER_PREFIX}, - /* NEEDSWORK: remote-branch is also obsolete */ - {"remote-branch", resolve_remote_submodule_branch, 0}, {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, {"is-active", is_active, 0}, -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote 2022-02-10 9:28 ` [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote Glen Choo @ 2022-02-12 14:43 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:43 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > Signed-off-by: Glen Choo <chooglen@google.com> > --- > builtin/submodule--helper.c | 19 ------------------- > 1 file changed, 19 deletions(-) > > diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c > index 98d8910930..5d5302b50b 100644 > --- a/builtin/submodule--helper.c > +++ b/builtin/submodule--helper.c > @@ -2516,23 +2516,6 @@ static const char *remote_submodule_branch(const char *path) > return branch; > } > > -static int resolve_remote_submodule_branch(int argc, const char **argv, > - const char *prefix) > -{ > - const char *ret; > - struct strbuf sb = STRBUF_INIT; > - if (argc != 2) > - die("submodule--helper remote-branch takes exactly one arguments, got %d", argc); > - > - ret = remote_submodule_branch(argv[1]); > - if (!ret) > - die("submodule %s doesn't exist", argv[1]); > - > - printf("%s", ret); > - strbuf_release(&sb); > - return 0; > -} > - > static int push_check(int argc, const char **argv, const char *prefix) > { > struct remote *remote; > @@ -3484,8 +3467,6 @@ static struct cmd_struct commands[] = { > {"sync", module_sync, SUPPORT_SUPER_PREFIX}, > {"deinit", module_deinit, 0}, > {"summary", module_summary, SUPPORT_SUPER_PREFIX}, > - /* NEEDSWORK: remote-branch is also obsolete */ > - {"remote-branch", resolve_remote_submodule_branch, 0}, > {"push-check", push_check, 0}, > {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, > {"is-active", is_active, 0}, Ditto good fix-up, should squash this into the relevant commit. ^ permalink raw reply [flat|nested] 142+ messages in thread
* [PATCH v7 20/20] fixup! submodule: move core cmd_update() logic to C 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (18 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote Glen Choo @ 2022-02-10 9:28 ` Glen Choo 2022-02-12 14:45 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 2022-02-13 5:54 ` Junio C Hamano 21 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-10 9:28 UTC (permalink / raw) To: git Cc: Glen Choo, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Signed-off-by: Glen Choo <chooglen@google.com> --- builtin/submodule--helper.c | 13 +++---------- git-submodule.sh | 13 +------------ 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 5d5302b50b..3367997973 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2807,12 +2807,6 @@ static void update_data_to_args(struct update_data *update_data, struct strvec * { strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL); strvec_pushf(args, "--jobs=%d", update_data->max_jobs); - /* - * NEEDSWORK: the equivalent code in git-submodule.sh does not - * pass --prefix, so this shouldn't either - */ - if (update_data->prefix) - strvec_pushl(args, "--prefix", update_data->prefix, NULL); if (update_data->recursive_prefix) strvec_pushl(args, "--recursive-prefix", update_data->recursive_prefix, NULL); @@ -2980,8 +2974,7 @@ static int module_update(int argc, const char **argv, const char *prefix) struct pathspec pathspec; struct update_data opt = UPDATE_DATA_INIT; - /* NEEDSWORK: update names and strings */ - struct option module_update_clone_options[] = { + struct option module_update_options[] = { OPT__FORCE(&opt.force, N_("force checkout updates"), 0), OPT_BOOL(0, "init", &opt.init, N_("initialize uninitialized submodules before update")), @@ -3023,14 +3016,14 @@ static int module_update(int argc, const char **argv, const char *prefix) }; const char *const git_submodule_helper_usage[] = { - N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"), + N_("git submodule--helper update [--prefix=<path>] [<path>...]"), NULL }; update_clone_config_from_gitmodules(&opt.max_jobs); git_config(git_update_clone_config, &opt.max_jobs); - argc = parse_options(argc, argv, prefix, module_update_clone_options, + argc = parse_options(argc, argv, prefix, module_update_options, git_submodule_helper_usage, 0); oidcpy(&opt.oid, null_oid()); oidcpy(&opt.suboid, null_oid()); diff --git a/git-submodule.sh b/git-submodule.sh index d176469fb1..89f5cf393e 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -50,15 +50,6 @@ single_branch= jobs= recommend_shallow= -# NEEDSWORK this is now unused -die_if_unmatched () -{ - if test "$1" = "#unmatched" - then - exit ${2:-1} - fi -} - isnumber() { n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1" @@ -348,9 +339,7 @@ cmd_update() shift done - # NEEDSWORK --super-prefix isn't actually supported by this - # command - we just pass the $prefix to --recursive-prefix. - git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \ + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update \ ${GIT_QUIET:+--quiet} \ ${force:+--force} \ ${progress:+--progress} \ -- 2.33.GIT ^ permalink raw reply related [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (19 preceding siblings ...) 2022-02-10 9:28 ` [PATCH v7 20/20] fixup! submodule: move core cmd_update() logic to C Glen Choo @ 2022-02-12 14:45 ` Ævar Arnfjörð Bjarmason 2022-02-17 5:44 ` Glen Choo 2022-02-13 5:54 ` Junio C Hamano 21 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-12 14:45 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 10 2022, Glen Choo wrote: > This reroll contains another 'easy' preparatory patch and the fixups I > alluded to in v6 [1]. This isn't the split-up I described in the > footnote of v6, but it gets the big patch (patch 17) to what I think is > a reviewable state. > > The diff between v7 and v5 is no longer just NEEDSWORK comments, but I > think it is easier to reason about. Patch 17 resembles v5 the most (I > will include a diff in a reply to that patch); everything after patch 17 > is fixups (I did not squash them in because they would grow the diff > even more). > > I will also leave a review on patch 17 since the changes were not > originally authored by me. > > [1] https://lore.kernel.org/git/20220208083952.35036-1-chooglen@google.com > > Changes in v7: > - Split the last patch of v6 (the big one) into patches 16-17. > - Patch 16 moves logic out of run_update_procedure() (because the > command is going away), removing some noise from patch 17. This makes > the update_strategy parsing easier to reason about, but at the cost of > growing the diff vis-a-vis v5 > - Patches 18-20 are fixups that address NEEDSWORK comments from earlier > patches. Once maintaining a small diff vis-a-vis v5 stops making > sense, I will squash them in. > > Atharva Raykar (6): > submodule--helper: get remote names from any repository > submodule--helper: refactor get_submodule_displaypath() > submodule--helper: allow setting superprefix for init_submodule() > submodule--helper: run update using child process struct > builtin/submodule--helper.c: reformat designated initializers > submodule: move core cmd_update() logic to C > > Glen Choo (11): > submodule--helper: remove update-module-mode > submodule--helper: reorganize code for sh to C conversion > submodule--helper run-update-procedure: remove --suboid > submodule--helper run-update-procedure: learn --remote > submodule--helper: remove ensure-core-worktree > submodule--helper update-clone: learn --init > submodule--helper: move functions around > submodule--helper: reduce logic in run_update_procedure() > fixup! submodule--helper run-update-procedure: remove --suboid > fixup! submodule--helper run-update-procedure: learn --remote > fixup! submodule: move core cmd_update() logic to C > > Ævar Arnfjörð Bjarmason (3): > builtin/submodule--helper.c: rename option variables to "opt" > submodule--helper: don't use bitfield indirection for parse_options() > submodule tests: test for init and update failure output Thanks a lot for picking this up! This split-up is much easier to read than my v5, particularly with the end diff-stat of the "main" patch being: 2 files changed, 201 insertions(+), 216 deletions(-) Instead of: 2 files changed, 356 insertions(+), 388 deletions(-) I think sending a version of this with the fixups squashed in as a v8 would be good, and perhaps addressing some of my comments. I don't know if my suggested split-up of "prep fixes" into another series would be a good thing to pursue overall, perhaps Junio will chime in on how he'd be most comfortable in merging this down. I'd think splitting such trivial fixes into their own series be easier to review, but perhaps not. For the Signed-off-by question on v6, I think you should add your SOB to all the patches you submit. See this in SubmittingPatches: Notice that you can place your own `Signed-off-by` trailer when forwarding somebody else's patch with the above rules for D-C-O. Indeed you are encouraged to do so. Just running "git rebase -i -x 'git commit --amend --no-edit -s'" should do it. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-12 14:45 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason @ 2022-02-17 5:44 ` Glen Choo 2022-02-17 9:17 ` Ævar Arnfjörð Bjarmason 0 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2022-02-17 5:44 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Thu, Feb 10 2022, Glen Choo wrote: > >> Atharva Raykar (6): >> submodule--helper: get remote names from any repository >> submodule--helper: refactor get_submodule_displaypath() >> submodule--helper: allow setting superprefix for init_submodule() >> submodule--helper: run update using child process struct >> builtin/submodule--helper.c: reformat designated initializers >> submodule: move core cmd_update() logic to C >> >> Glen Choo (11): >> submodule--helper: remove update-module-mode >> submodule--helper: reorganize code for sh to C conversion >> submodule--helper run-update-procedure: remove --suboid >> submodule--helper run-update-procedure: learn --remote >> submodule--helper: remove ensure-core-worktree >> submodule--helper update-clone: learn --init >> submodule--helper: move functions around >> submodule--helper: reduce logic in run_update_procedure() >> fixup! submodule--helper run-update-procedure: remove --suboid >> fixup! submodule--helper run-update-procedure: learn --remote >> fixup! submodule: move core cmd_update() logic to C >> >> Ævar Arnfjörð Bjarmason (3): >> builtin/submodule--helper.c: rename option variables to "opt" >> submodule--helper: don't use bitfield indirection for parse_options() >> submodule tests: test for init and update failure output > > I think sending a version of this with the fixups squashed in as a v8 > would be good, and perhaps addressing some of my comments. > > I don't know if my suggested split-up of "prep fixes" into another > series would be a good thing to pursue overall, perhaps Junio will chime > in on how he'd be most comfortable in merging this down. I'd think > splitting such trivial fixes into their own series be easier to review, > but perhaps not. Combing through the patches again, I couldn't really convince myself that the patch 4..9 prep fixes make sense as obvious standalone fixes, except maybe: - patch 4 submodule--helper: run update using child process struct - patch 8 submodule tests: test for init and update failure output - patch 9: 087bf43aba submodule--helper: remove update-module-mode But, since the 'final' patch (ignoring the fixup!-s) is consuming a huge chunk of the work anyway, here's an alternative patch organization with the fixup!-s squashed: = Move 'easy' and 'obviously correct' code from sh->C - patches 8-9 Cleanup and introduce tests - patches 1-4 Refactor existing functions, which enables.. - patches 10-14 Move 'obviously correct' pieces of logic from sh-> C = Finalize move from sh->C i.e. combine "run-update-procedure" and "update-clone" into "update" - patches 5,7 Cleanup and prep - patches 6,15-16 Shrinking the diff - patch 17 Implement "git submodule--helper update" I'll send this if there are no objections :) ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-17 5:44 ` Glen Choo @ 2022-02-17 9:17 ` Ævar Arnfjörð Bjarmason 2022-02-17 16:14 ` Glen Choo 0 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-17 9:17 UTC (permalink / raw) To: Glen Choo Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Thu, Feb 17 2022, Glen Choo wrote: > Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > >> On Thu, Feb 10 2022, Glen Choo wrote: >> >>> Atharva Raykar (6): >>> submodule--helper: get remote names from any repository >>> submodule--helper: refactor get_submodule_displaypath() >>> submodule--helper: allow setting superprefix for init_submodule() >>> submodule--helper: run update using child process struct >>> builtin/submodule--helper.c: reformat designated initializers >>> submodule: move core cmd_update() logic to C >>> >>> Glen Choo (11): >>> submodule--helper: remove update-module-mode >>> submodule--helper: reorganize code for sh to C conversion >>> submodule--helper run-update-procedure: remove --suboid >>> submodule--helper run-update-procedure: learn --remote >>> submodule--helper: remove ensure-core-worktree >>> submodule--helper update-clone: learn --init >>> submodule--helper: move functions around >>> submodule--helper: reduce logic in run_update_procedure() >>> fixup! submodule--helper run-update-procedure: remove --suboid >>> fixup! submodule--helper run-update-procedure: learn --remote >>> fixup! submodule: move core cmd_update() logic to C >>> >>> Ævar Arnfjörð Bjarmason (3): >>> builtin/submodule--helper.c: rename option variables to "opt" >>> submodule--helper: don't use bitfield indirection for parse_options() >>> submodule tests: test for init and update failure output >> >> I think sending a version of this with the fixups squashed in as a v8 >> would be good, and perhaps addressing some of my comments. >> >> I don't know if my suggested split-up of "prep fixes" into another >> series would be a good thing to pursue overall, perhaps Junio will chime >> in on how he'd be most comfortable in merging this down. I'd think >> splitting such trivial fixes into their own series be easier to review, >> but perhaps not. > > Combing through the patches again, I couldn't really convince myself > that the patch 4..9 prep fixes make sense as obvious standalone fixes, > except maybe: > > - patch 4 submodule--helper: run update using child process struct > - patch 8 submodule tests: test for init and update failure output > - patch 9: 087bf43aba submodule--helper: remove update-module-mode > > But, since the 'final' patch (ignoring the fixup!-s) is consuming a huge > chunk of the work anyway, here's an alternative patch organization with > the fixup!-s squashed: > > = Move 'easy' and 'obviously correct' code from sh->C > - patches 8-9 Cleanup and introduce tests > - patches 1-4 Refactor existing functions, which enables.. > - patches 10-14 Move 'obviously correct' pieces of logic from sh-> C > > = Finalize move from sh->C > i.e. combine "run-update-procedure" and "update-clone" into "update" > - patches 5,7 Cleanup and prep > - patches 6,15-16 Shrinking the diff > - patch 17 Implement "git submodule--helper update" > > I'll send this if there are no objections :) Yes that sounds good, or rather, I haven't re-looked at that in detail, but I think if you think it makes sense we should go for it. Or rather, we should really be aiming to produce a patch series that makes sense in its current iteration, as opposed to optimizing for a diff against some ad-hoc re-roll I produced a few versions ago :) Thanks again for working on this & picking this up. It's great to see progress in this area! ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-17 9:17 ` Ævar Arnfjörð Bjarmason @ 2022-02-17 16:14 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-17 16:14 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: git, Junio C Hamano, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Thu, Feb 17 2022, Glen Choo wrote: > >> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: >> >>> On Thu, Feb 10 2022, Glen Choo wrote: >>> >>>> Atharva Raykar (6): >>>> submodule--helper: get remote names from any repository >>>> submodule--helper: refactor get_submodule_displaypath() >>>> submodule--helper: allow setting superprefix for init_submodule() >>>> submodule--helper: run update using child process struct >>>> builtin/submodule--helper.c: reformat designated initializers >>>> submodule: move core cmd_update() logic to C >>>> >>>> Glen Choo (11): >>>> submodule--helper: remove update-module-mode >>>> submodule--helper: reorganize code for sh to C conversion >>>> submodule--helper run-update-procedure: remove --suboid >>>> submodule--helper run-update-procedure: learn --remote >>>> submodule--helper: remove ensure-core-worktree >>>> submodule--helper update-clone: learn --init >>>> submodule--helper: move functions around >>>> submodule--helper: reduce logic in run_update_procedure() >>>> fixup! submodule--helper run-update-procedure: remove --suboid >>>> fixup! submodule--helper run-update-procedure: learn --remote >>>> fixup! submodule: move core cmd_update() logic to C >>>> >>>> Ævar Arnfjörð Bjarmason (3): >>>> builtin/submodule--helper.c: rename option variables to "opt" >>>> submodule--helper: don't use bitfield indirection for parse_options() >>>> submodule tests: test for init and update failure output >>> >>> I think sending a version of this with the fixups squashed in as a v8 >>> would be good, and perhaps addressing some of my comments. >>> >>> I don't know if my suggested split-up of "prep fixes" into another >>> series would be a good thing to pursue overall, perhaps Junio will chime >>> in on how he'd be most comfortable in merging this down. I'd think >>> splitting such trivial fixes into their own series be easier to review, >>> but perhaps not. >> >> Combing through the patches again, I couldn't really convince myself >> that the patch 4..9 prep fixes make sense as obvious standalone fixes, >> except maybe: >> >> - patch 4 submodule--helper: run update using child process struct >> - patch 8 submodule tests: test for init and update failure output >> - patch 9: 087bf43aba submodule--helper: remove update-module-mode >> >> But, since the 'final' patch (ignoring the fixup!-s) is consuming a huge >> chunk of the work anyway, here's an alternative patch organization with >> the fixup!-s squashed: >> >> = Move 'easy' and 'obviously correct' code from sh->C >> - patches 8-9 Cleanup and introduce tests >> - patches 1-4 Refactor existing functions, which enables.. >> - patches 10-14 Move 'obviously correct' pieces of logic from sh-> C >> >> = Finalize move from sh->C >> i.e. combine "run-update-procedure" and "update-clone" into "update" >> - patches 5,7 Cleanup and prep >> - patches 6,15-16 Shrinking the diff >> - patch 17 Implement "git submodule--helper update" >> >> I'll send this if there are no objections :) > > Yes that sounds good, or rather, I haven't re-looked at that in detail, > but I think if you think it makes sense we should go for it. > > Or rather, we should really be aiming to produce a patch series that > makes sense in its current iteration, as opposed to optimizing for a > diff against some ad-hoc re-roll I produced a few versions ago :) Agreed, makes sense. > Thanks again for working on this & picking this up. It's great to see > progress in this area! Thanks to you too for getting the ball rolling and lending me your thoughts :) ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo ` (20 preceding siblings ...) 2022-02-12 14:45 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason @ 2022-02-13 5:54 ` Junio C Hamano 2022-02-13 6:14 ` Junio C Hamano 21 siblings, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2022-02-13 5:54 UTC (permalink / raw) To: Glen Choo Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Glen Choo <chooglen@google.com> writes: > This reroll contains another 'easy' preparatory patch and the fixups I > alluded to in v6 [1]. This isn't the split-up I described in the > footnote of v6, but it gets the big patch (patch 17) to what I think is > a reviewable state. Thanks. This seems to heavily conflict with "clone, submodule: pass partial clone filters to submodules, 2022-02-04" by Josh Steadmon <690d2316ad518ea4551821b2b3aa652996858475.1644034886.git.steadmon@google.com> in both builtins/submodule--helper.c and git-submodule.sh. It also removes the code that "submodule: record superproject gitdir during 'update', 2022-02-03" by Emily Shaffer <20220203215914.683922-5-emilyshaffer@google.com>, so what the other topic ends up adding to the shell script needs to eventually be redone in the C code. I think "superproject aware" topic would see a reroll due to a slight redesign. I am not sure how solid the design of the "pass down partial clone filter" topic is at this moment. I may try to eject them tentatively and see how well this topic plays with the rest of the topics in flight. Thanks. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-13 5:54 ` Junio C Hamano @ 2022-02-13 6:14 ` Junio C Hamano 2022-02-14 16:37 ` Glen Choo 0 siblings, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2022-02-13 6:14 UTC (permalink / raw) To: Glen Choo Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Junio C Hamano <gitster@pobox.com> writes: > Glen Choo <chooglen@google.com> writes: > >> This reroll contains another 'easy' preparatory patch and the fixups I >> alluded to in v6 [1]. This isn't the split-up I described in the >> footnote of v6, but it gets the big patch (patch 17) to what I think is >> a reviewable state. > > Thanks. > > This seems to heavily conflict with "clone, submodule: pass partial > clone filters to submodules, 2022-02-04" by Josh Steadmon > <690d2316ad518ea4551821b2b3aa652996858475.1644034886.git.steadmon@google.com> > in both builtins/submodule--helper.c and git-submodule.sh. > > It also removes the code that "submodule: record superproject gitdir > during 'update', 2022-02-03" by Emily Shaffer > <20220203215914.683922-5-emilyshaffer@google.com>, so what the other > topic ends up adding to the shell script needs to eventually be > redone in the C code. > > I think "superproject aware" topic would see a reroll due to a > slight redesign. I am not sure how solid the design of the > "pass down partial clone filter" topic is at this moment. > > I may try to eject them tentatively and see how well this topic > plays with the rest of the topics in flight. > > Thanks. I can merge this to seen minus the above two topics and get it compile, but it also seems to have some interaction with 961b130d (branch: add --recurse-submodules option for branch creation, 2022-01-28) and makes the t3207, tests added by that other topic, fail X-<. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-13 6:14 ` Junio C Hamano @ 2022-02-14 16:37 ` Glen Choo 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason ` (2 more replies) 0 siblings, 3 replies; 142+ messages in thread From: Glen Choo @ 2022-02-14 16:37 UTC (permalink / raw) To: Junio C Hamano Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Junio C Hamano <gitster@pobox.com> writes: >> This seems to heavily conflict with "clone, submodule: pass partial >> clone filters to submodules, 2022-02-04" by Josh Steadmon >> <690d2316ad518ea4551821b2b3aa652996858475.1644034886.git.steadmon@google.com> >> in both builtins/submodule--helper.c and git-submodule.sh. >> >> It also removes the code that "submodule: record superproject gitdir >> during 'update', 2022-02-03" by Emily Shaffer >> <20220203215914.683922-5-emilyshaffer@google.com>, so what the other >> topic ends up adding to the shell script needs to eventually be >> redone in the C code. >> >> I think "superproject aware" topic would see a reroll due to a >> slight redesign. I am not sure how solid the design of the >> "pass down partial clone filter" topic is at this moment. Hm, I haven't looked at where the conflicts are yet, but I'll get to it as I'm reviewing the rest of the feedback. And on that note, what do you think of Ævar's suggestion to split off the 'easy to review' and 'obvious' patches into their own preparatory series? I wonder if this would make it harder or easier to manage the conflicts. > I can merge this to seen minus the above two topics and get it > compile, but it also seems to have some interaction with 961b130d > (branch: add --recurse-submodules option for branch creation, > 2022-01-28) and makes the t3207, tests added by that other topic, > fail X-<. Oof, that's embarrassing of me, let me take a look at that. There's a nontrivial chance that the "branch --recurse-submodules" tests caught an actual regression. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-14 16:37 ` Glen Choo @ 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason 2022-02-15 9:34 ` Glen Choo 2022-02-14 17:34 ` Junio C Hamano 2022-02-15 9:47 ` Glen Choo 2 siblings, 1 reply; 142+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-02-14 17:19 UTC (permalink / raw) To: Glen Choo Cc: Junio C Hamano, git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla On Tue, Feb 15 2022, Glen Choo wrote: > Junio C Hamano <gitster@pobox.com> writes: > >>> This seems to heavily conflict with "clone, submodule: pass partial >>> clone filters to submodules, 2022-02-04" by Josh Steadmon >>> <690d2316ad518ea4551821b2b3aa652996858475.1644034886.git.steadmon@google.com> >>> in both builtins/submodule--helper.c and git-submodule.sh. >>> >>> It also removes the code that "submodule: record superproject gitdir >>> during 'update', 2022-02-03" by Emily Shaffer >>> <20220203215914.683922-5-emilyshaffer@google.com>, so what the other >>> topic ends up adding to the shell script needs to eventually be >>> redone in the C code. >>> >>> I think "superproject aware" topic would see a reroll due to a >>> slight redesign. I am not sure how solid the design of the >>> "pass down partial clone filter" topic is at this moment. > > Hm, I haven't looked at where the conflicts are yet, but I'll get to it > as I'm reviewing the rest of the feedback. To save you some time, my v4 CL summarizes the semantic conflict between the two: https://lore.kernel.org/git/cover-v4-0.7-00000000000-20220127T143552Z-avarab@gmail.com/ I.e. Atharva Raykar had working C code to do what an older version of that superproject config series was doing, but the semantics changed in a later version. It needs some new usage of path.c (or similar) API adjusted, but I didn't (and still don't) have time to look into it. > [...] >> I can merge this to seen minus the above two topics and get it >> compile, but it also seems to have some interaction with 961b130d >> (branch: add --recurse-submodules option for branch creation, >> 2022-01-28) and makes the t3207, tests added by that other topic, >> fail X-<. > > Oof, that's embarrassing of me, let me take a look at that. There's a > nontrivial chance that the "branch --recurse-submodules" tests caught an > actual regression. FWIW one thing I did as an extra sanity check was to run the whole test suite with --tee with/without this series (or rather, my earlier version), and diffing the full test-results output (which you'll need to save in-between the two runs, and IIRC hack t/Makefile to stop removing it on successful runs). There's a lot of differences in output due to general issues in the test suite output not being reproducable (writing timestamps etc.), but I could not find any issues with the "git submodule" output being different, of course we may not have tests, or it may be piped to /dev/null.... But I've found it to be a helpful additional validation technique for this series & others where I'm not as confident in the test coverage. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason @ 2022-02-15 9:34 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-15 9:34 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: Junio C Hamano, git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, Feb 15 2022, Glen Choo wrote: > >> Junio C Hamano <gitster@pobox.com> writes: >> >>>> This seems to heavily conflict with "clone, submodule: pass partial >>>> clone filters to submodules, 2022-02-04" by Josh Steadmon >>>> <690d2316ad518ea4551821b2b3aa652996858475.1644034886.git.steadmon@google.com> >>>> in both builtins/submodule--helper.c and git-submodule.sh. >>>> >>>> It also removes the code that "submodule: record superproject gitdir >>>> during 'update', 2022-02-03" by Emily Shaffer >>>> <20220203215914.683922-5-emilyshaffer@google.com>, so what the other >>>> topic ends up adding to the shell script needs to eventually be >>>> redone in the C code. >>>> >>>> I think "superproject aware" topic would see a reroll due to a >>>> slight redesign. I am not sure how solid the design of the >>>> "pass down partial clone filter" topic is at this moment. >> >> Hm, I haven't looked at where the conflicts are yet, but I'll get to it >> as I'm reviewing the rest of the feedback. > > To save you some time, my v4 CL summarizes the semantic conflict between > the two: > https://lore.kernel.org/git/cover-v4-0.7-00000000000-20220127T143552Z-avarab@gmail.com/ > > I.e. Atharva Raykar had working C code to do what an older version of > that superproject config series was doing, but the semantics changed in > a later version. It needs some new usage of path.c (or similar) API > adjusted, but I didn't (and still don't) have time to look into it. Ah, thanks for the reminder. That should help. >>> I can merge this to seen minus the above two topics and get it >>> compile, but it also seems to have some interaction with 961b130d >>> (branch: add --recurse-submodules option for branch creation, >>> 2022-01-28) and makes the t3207, tests added by that other topic, >>> fail X-<. >> >> Oof, that's embarrassing of me, let me take a look at that. There's a >> nontrivial chance that the "branch --recurse-submodules" tests caught an >> actual regression. > > FWIW one thing I did as an extra sanity check was to run the whole test > suite with --tee with/without this series (or rather, my earlier > version), and diffing the full test-results output (which you'll need to > save in-between the two runs, and IIRC hack t/Makefile to stop removing > it on successful runs). > > There's a lot of differences in output due to general issues in the test > suite output not being reproducable (writing timestamps etc.), but I > could not find any issues with the "git submodule" output being > different, of course we may not have tests, or it may be piped to > /dev/null.... > > But I've found it to be a helpful additional validation technique for > this series & others where I'm not as confident in the test coverage. Thanks for the tip! I hadn't considered trying this, but this makes a lot of sense. I can see this being even more useful for this series since it's supposed to be a faithful conversion of sh->c. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-14 16:37 ` Glen Choo 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason @ 2022-02-14 17:34 ` Junio C Hamano 2022-02-15 9:31 ` Glen Choo 2022-02-15 9:47 ` Glen Choo 2 siblings, 1 reply; 142+ messages in thread From: Junio C Hamano @ 2022-02-14 17:34 UTC (permalink / raw) To: Glen Choo Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Glen Choo <chooglen@google.com> writes: > Hm, I haven't looked at where the conflicts are yet, but I'll get to it > as I'm reviewing the rest of the feedback. > > And on that note, what do you think of Ævar's suggestion to split off > the 'easy to review' and 'obvious' patches into their own preparatory > series? I wonder if this would make it harder or easier to manage the > conflicts. It depends on how small an interaction the "obvious and easy" part has with topics in flight. In the best case, if there aren't any the preparatory series may even graduate before the other topics that interfere with the main part of this series becomes ready. In a worse case, what the preparatory work to lay more solid foundation wants to do may contradict what some of these topics in flight want to do. Such semantic conflicts need to be resolved before the main part (and these interfering topics) can move forward, and with "split off", the core of the contradicting wish may become easier to see and what needs to be resolved may become clearer. So, I do not think of a way for such a split to make things harder for later. Of course, the "easy to review" and "obvious" part has to be justifiable on its own, i.e. "a larger series wants to build on this foundation and for it to work this part must be done in this way", when the other topics wants to do the part in question differently, becomes a much weaker justification. But if it is truly "obvious", it is unlikely that the benefit of the change becomes harder to justify. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-14 17:34 ` Junio C Hamano @ 2022-02-15 9:31 ` Glen Choo 0 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-15 9:31 UTC (permalink / raw) To: Junio C Hamano Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla, Ævar Arnfjörð Bjarmason Junio C Hamano <gitster@pobox.com> writes: > Glen Choo <chooglen@google.com> writes: > >> Hm, I haven't looked at where the conflicts are yet, but I'll get to it >> as I'm reviewing the rest of the feedback. >> >> And on that note, what do you think of Ævar's suggestion to split off >> the 'easy to review' and 'obvious' patches into their own preparatory >> series? I wonder if this would make it harder or easier to manage the >> conflicts. > > It depends on how small an interaction the "obvious and easy" part > has with topics in flight. In the best case, if there aren't any > the preparatory series may even graduate before the other topics > that interfere with the main part of this series becomes ready. > > In a worse case, what the preparatory work to lay more solid > foundation wants to do may contradict what some of these topics in > flight want to do. Such semantic conflicts need to be resolved > before the main part (and these interfering topics) can move > forward, and with "split off", the core of the contradicting wish > may become easier to see and what needs to be resolved may become > clearer. > > So, I do not think of a way for such a split to make things harder > for later. Of course, the "easy to review" and "obvious" part has > to be justifiable on its own, i.e. "a larger series wants to build > on this foundation and for it to work this part must be done in this > way", when the other topics wants to do the part in question > differently, becomes a much weaker justification. But if it is > truly "obvious", it is unlikely that the benefit of the change > becomes harder to justify. Thanks for sharing your thought process. That makes sense, I'll do that :) ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH v7 00/20] submodule: convert the rest of 'update' to C 2022-02-14 16:37 ` Glen Choo 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason 2022-02-14 17:34 ` Junio C Hamano @ 2022-02-15 9:47 ` Glen Choo 2 siblings, 0 replies; 142+ messages in thread From: Glen Choo @ 2022-02-15 9:47 UTC (permalink / raw) To: Junio C Hamano, Ævar Arnfjörð Bjarmason Cc: git, Atharva Raykar, Christian Couder, Emily Shaffer, Jonathan Nieder, Kaartic Sivaraam, pc44800, Shourya Shukla Glen Choo <chooglen@google.com> writes: > Junio C Hamano <gitster@pobox.com> writes: > >> I can merge this to seen minus the above two topics and get it >> compile, but it also seems to have some interaction with 961b130d >> (branch: add --recurse-submodules option for branch creation, >> 2022-01-28) and makes the t3207, tests added by that other topic, >> fail X-<. > > Oof, that's embarrassing of me, let me take a look at that. There's a > nontrivial chance that the "branch --recurse-submodules" tests caught an > actual regression. Looks like this is the case - t3207 caught a regression in how "git submodule update" sets the refspec of nested submodules. Looks like our concerns about the test suite are well-founded.. ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH 00/13] submodule: convert the rest of 'update' to C 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar ` (14 preceding siblings ...) 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar @ 2021-10-14 21:50 ` Glen Choo 2021-10-15 9:13 ` Atharva Raykar 15 siblings, 1 reply; 142+ messages in thread From: Glen Choo @ 2021-10-14 21:50 UTC (permalink / raw) To: Atharva Raykar, git > This series builds upon the previous conversion work on 'submodule update' and > moves out all of that shell logic in 'git-submodule.sh' into > 'builtin/submodule--helper.c'. Hey Atharva! I'm working on a series that will teach "git branch" how to handle "--recurse-submodules". I plan to do this in-process because I think this will take less overall effort than using child processes, and to make it happen, I'm planning to add a helper function like "for_each_submodule()", which would call a C callback function on each submodule. This is conceptually similar to "git submodule foreach" and for_each_listed_submodule() (though not exactly equivalent), so I'm reaching out to you in case this work is already on your radar. If so, and if it is coming soon, it might be easier to for me to base my work off yours instead of duplicating our efforts :) ^ permalink raw reply [flat|nested] 142+ messages in thread
* Re: [PATCH 00/13] submodule: convert the rest of 'update' to C 2021-10-14 21:50 ` [PATCH 00/13] " Glen Choo @ 2021-10-15 9:13 ` Atharva Raykar 0 siblings, 0 replies; 142+ messages in thread From: Atharva Raykar @ 2021-10-15 9:13 UTC (permalink / raw) To: Glen Choo; +Cc: git Glen Choo <chooglen@google.com> writes: >> This series builds upon the previous conversion work on 'submodule update' and >> moves out all of that shell logic in 'git-submodule.sh' into >> 'builtin/submodule--helper.c'. > > Hey Atharva! I'm working on a series that will teach "git branch" how to > handle "--recurse-submodules". I plan to do this in-process because I > think this will take less overall effort than using child processes, and > to make it happen, I'm planning to add a helper function like > "for_each_submodule()", which would call a C callback function on each > submodule. > > This is conceptually similar to "git submodule foreach" and > for_each_listed_submodule() (though not exactly equivalent), so I'm > reaching out to you in case this work is already on your radar. If so, > and if it is coming soon, it might be easier to for me to base my work > off yours instead of duplicating our efforts :) Thanks for reaching out. I don't have anything like this on my radar, so feel free to go ahead with your plan :) ^ permalink raw reply [flat|nested] 142+ messages in thread
end of thread, other threads:[~2022-02-17 16:14 UTC | newest] Thread overview: 142+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar 2021-09-07 11:59 ` [PATCH 01/13] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-09-07 11:59 ` [PATCH 02/13] submodule--helper: get remote names from any repository Atharva Raykar 2021-09-07 12:37 ` Ævar Arnfjörð Bjarmason 2021-09-07 13:33 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 03/13] submodule--helper: introduce get_default_remote_submodule() Atharva Raykar 2021-09-07 11:59 ` [PATCH 04/13] submodule--helper: rename helpers for update-clone Atharva Raykar 2021-09-07 11:59 ` [PATCH 05/13] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar 2021-09-07 11:59 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Atharva Raykar 2021-09-07 12:40 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 07/13] submodule: remove fetch_in_submodule shell function Atharva Raykar 2021-09-07 12:44 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 08/13] submodule--helper: remove update-clone subcommand Atharva Raykar 2021-09-07 12:46 ` Ævar Arnfjörð Bjarmason 2021-09-07 11:59 ` [PATCH 09/13] submodule--helper: remove update-module-mode subcommand Atharva Raykar 2021-09-07 12:49 ` Ævar Arnfjörð Bjarmason 2021-09-07 13:50 ` Atharva Raykar 2021-09-07 11:59 ` [PATCH 10/13] submodule--helper: remove shell interface to ensure_core_worktree() Atharva Raykar 2021-09-07 11:59 ` [PATCH 11/13] submodule--helper: remove print-default-remote subcommand Atharva Raykar 2021-09-07 11:59 ` [PATCH 12/13] submodule--helper: remove relative-path subcommand Atharva Raykar 2021-09-07 11:59 ` [PATCH 13/13] submodule--helper: remove run-update-procedure subcommand Atharva Raykar 2021-09-07 12:34 ` [PATCH 00/13] submodule: convert the rest of 'update' to C Ævar Arnfjörð Bjarmason 2021-09-07 12:53 ` Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar 2021-09-20 16:52 ` Junio C Hamano 2021-10-03 13:22 ` Atharva Raykar 2021-09-20 21:28 ` Junio C Hamano 2021-09-21 16:33 ` Jonathan Tan 2021-09-16 10:32 ` [PATCH v2 3/8] submodule--helper: rename helpers for update-clone Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 4/8] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar 2021-09-20 17:13 ` Junio C Hamano 2021-10-03 10:38 ` Atharva Raykar 2021-09-20 19:58 ` Junio C Hamano 2021-09-20 21:28 ` Junio C Hamano 2021-09-16 10:32 ` [PATCH v2 6/8] submodule--helper: remove update-clone subcommand Atharva Raykar 2021-09-16 10:32 ` [PATCH v2 7/8] submodule--helper: remove unused helpers Atharva Raykar 2021-09-20 17:19 ` Junio C Hamano 2021-09-16 10:32 ` [PATCH v2 8/8] submodule--helper: rename helper functions Atharva Raykar 2021-09-20 17:19 ` Junio C Hamano 2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 2/9] submodule--helper: get remote names from any repository Atharva Raykar 2021-10-13 5:17 ` [PATCH v3 3/9] submodule--helper: rename helpers for update-clone Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 4/9] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 5/9] submodule--helper: allow setting superprefix for init_submodule() Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 6/9] submodule--helper: run update using child process struct Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 7/9] submodule: move core cmd_update() logic to C Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 8/9] submodule--helper: remove unused helpers Atharva Raykar 2021-10-13 5:18 ` [PATCH v3 9/9] submodule--helper: rename helper functions Atharva Raykar 2021-10-14 0:05 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Junio C Hamano 2021-10-14 20:46 ` Emily Shaffer 2021-12-03 19:00 ` Junio C Hamano 2021-12-03 20:15 ` Ævar Arnfjörð Bjarmason 2021-12-04 10:38 ` Atharva Raykar 2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason 2022-01-27 18:45 ` Glen Choo 2022-01-27 16:22 ` [PATCH v4 2/7] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 3/7] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 4/7] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 5/7] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 6/7] builtin/submodule--helper.c: rename "suc" variable to "opt" Ævar Arnfjörð Bjarmason 2022-01-27 16:22 ` [PATCH v4 7/7] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason 2022-01-27 21:55 ` Glen Choo 2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 1/9] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 2/9] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 3/9] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 4/9] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 5/9] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 6/9] builtin/submodule--helper.c: rename option variables to "opt" Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 7/9] submodule--helper: don't use bitfield indirection for parse_options() Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 8/9] submodule tests: test for init and update failure output Ævar Arnfjörð Bjarmason 2022-01-28 12:56 ` [PATCH v5 9/9] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason 2022-02-03 0:18 ` Glen Choo 2022-02-03 2:26 ` Ævar Arnfjörð Bjarmason 2022-02-03 8:15 ` Ævar Arnfjörð Bjarmason 2022-02-03 17:35 ` Glen Choo 2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo 2022-02-08 8:39 ` [PATCH v6 01/16] submodule--helper: get remote names from any repository Glen Choo 2022-02-08 8:39 ` [PATCH v6 02/16] submodule--helper: refactor get_submodule_displaypath() Glen Choo 2022-02-08 8:39 ` [PATCH v6 03/16] submodule--helper: allow setting superprefix for init_submodule() Glen Choo 2022-02-08 8:39 ` [PATCH v6 04/16] submodule--helper: run update using child process struct Glen Choo 2022-02-08 8:39 ` [PATCH v6 05/16] builtin/submodule--helper.c: reformat designated initializers Glen Choo 2022-02-08 8:39 ` [PATCH v6 06/16] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo 2022-02-08 8:39 ` [PATCH v6 07/16] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo 2022-02-08 8:39 ` [PATCH v6 08/16] submodule tests: test for init and update failure output Glen Choo 2022-02-08 8:39 ` [PATCH v6 09/16] submodule--helper: remove update-module-mode Glen Choo 2022-02-08 8:39 ` [PATCH v6 10/16] submodule--helper: reorganize code for sh to C conversion Glen Choo 2022-02-08 8:39 ` [PATCH v6 11/16] submodule--helper run-update-procedure: remove --suboid Glen Choo 2022-02-08 8:39 ` [PATCH v6 12/16] submodule--helper run-update-procedure: learn --remote Glen Choo 2022-02-08 8:39 ` [PATCH v6 13/16] submodule--helper: remove ensure-core-worktree Glen Choo 2022-02-08 8:39 ` [PATCH v6 14/16] submodule--helper update-clone: learn --init Glen Choo 2022-02-08 8:39 ` [PATCH v6 15/16] submodule--helper: move functions around Glen Choo 2022-02-08 8:39 ` [PATCH v6 16/16] submodule: move core cmd_update() logic to C Glen Choo 2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo 2022-02-10 9:28 ` [PATCH v7 01/20] submodule--helper: get remote names from any repository Glen Choo 2022-02-10 9:28 ` [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() Glen Choo 2022-02-12 14:24 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() Glen Choo 2022-02-12 14:30 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 04/20] submodule--helper: run update using child process struct Glen Choo 2022-02-12 14:33 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 05/20] builtin/submodule--helper.c: reformat designated initializers Glen Choo 2022-02-10 9:28 ` [PATCH v7 06/20] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo 2022-02-10 9:28 ` [PATCH v7 07/20] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo 2022-02-10 9:28 ` [PATCH v7 08/20] submodule tests: test for init and update failure output Glen Choo 2022-02-10 9:28 ` [PATCH v7 09/20] submodule--helper: remove update-module-mode Glen Choo 2022-02-12 14:35 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 10/20] submodule--helper: reorganize code for sh to C conversion Glen Choo 2022-02-10 9:28 ` [PATCH v7 11/20] submodule--helper run-update-procedure: remove --suboid Glen Choo 2022-02-10 9:28 ` [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote Glen Choo 2022-02-12 14:38 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 13/20] submodule--helper: remove ensure-core-worktree Glen Choo 2022-02-10 9:28 ` [PATCH v7 14/20] submodule--helper update-clone: learn --init Glen Choo 2022-02-10 9:28 ` [PATCH v7 15/20] submodule--helper: move functions around Glen Choo 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 16/20] submodule--helper: reduce logic in run_update_procedure() Glen Choo 2022-02-10 9:28 ` [PATCH v7 17/20] submodule: move core cmd_update() logic to C Glen Choo 2022-02-10 9:34 ` Glen Choo 2022-02-10 9:28 ` [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid Glen Choo 2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote Glen Choo 2022-02-12 14:43 ` Ævar Arnfjörð Bjarmason 2022-02-10 9:28 ` [PATCH v7 20/20] fixup! submodule: move core cmd_update() logic to C Glen Choo 2022-02-12 14:45 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason 2022-02-17 5:44 ` Glen Choo 2022-02-17 9:17 ` Ævar Arnfjörð Bjarmason 2022-02-17 16:14 ` Glen Choo 2022-02-13 5:54 ` Junio C Hamano 2022-02-13 6:14 ` Junio C Hamano 2022-02-14 16:37 ` Glen Choo 2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason 2022-02-15 9:34 ` Glen Choo 2022-02-14 17:34 ` Junio C Hamano 2022-02-15 9:31 ` Glen Choo 2022-02-15 9:47 ` Glen Choo 2021-10-14 21:50 ` [PATCH 00/13] " Glen Choo 2021-10-15 9:13 ` Atharva Raykar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).