[PATCH v4 0/7] submodule: convert the rest of 'update' to C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx/
2. https://lore.kernel.org/git/CADi-XoThCqfvPnBd0p6yAhrtotK_3z2pQQMugWPsYpHLbXge7w@xxxxxxxxxxxxxx/
3. https://lore.kernel.org/git/211203.86o85xqw7o.gmgdl@xxxxxxxxxxxxxxxxxxx/
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@xxxxxxxxx>
         Signed-off-by: Atharva Raykar <raykar.ath@xxxxxxxxx>
         Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## 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@xxxxxxxxx>
         Signed-off-by: Atharva Raykar <raykar.ath@xxxxxxxxx>
         Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## 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@xxxxxxxxx>
         Signed-off-by: Atharva Raykar <raykar.ath@xxxxxxxxx>
         Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## 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@xxxxxxxxx>
         Signed-off-by: Atharva Raykar <raykar.ath@xxxxxxxxx>
         Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## 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@xxxxxxxxx>
         Signed-off-by: Atharva Raykar <raykar.ath@xxxxxxxxx>
         Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## 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




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux