submodule--helper: run update procedures from C
Add a new submodule--helper subcommand `run-update-procedure` that runs the update procedure if the SHA1 of the submodule does not match what the superproject expects. This is an intermediate change that works towards total conversion of `submodule update` from shell to C. Specific error codes are returned so that the shell script calling the subcommand can take a decision on the control flow, and preserve the error messages across subsequent recursive calls of `cmd_update`. This change is more focused on doing a faithful conversion, so for now we are not too concerned with trying to reduce subprocess spawns. 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>maint
							parent
							
								
									5d213e46bb
								
							
						
					
					
						commit
						c51f8f94e5
					
				|  | @ -2045,6 +2045,20 @@ struct submodule_update_clone { | ||||||
| 	.max_jobs = 1, \ | 	.max_jobs = 1, \ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct update_data { | ||||||
|  | 	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 depth; | ||||||
|  | 	unsigned int force: 1; | ||||||
|  | 	unsigned int quiet: 1; | ||||||
|  | 	unsigned int nofetch: 1; | ||||||
|  | 	unsigned int just_cloned: 1; | ||||||
|  | }; | ||||||
|  | #define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT } | ||||||
|  |  | ||||||
| static void next_submodule_warn_missing(struct submodule_update_clone *suc, | static void next_submodule_warn_missing(struct submodule_update_clone *suc, | ||||||
| 		struct strbuf *out, const char *displaypath) | 		struct strbuf *out, const char *displaypath) | ||||||
|  | @ -2298,6 +2312,181 @@ static int git_update_clone_config(const char *var, const char *value, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int is_tip_reachable(const char *path, struct object_id *oid) | ||||||
|  | { | ||||||
|  | 	struct child_process cp = CHILD_PROCESS_INIT; | ||||||
|  | 	struct strbuf rev = STRBUF_INIT; | ||||||
|  | 	char *hex = oid_to_hex(oid); | ||||||
|  |  | ||||||
|  | 	cp.git_cmd = 1; | ||||||
|  | 	cp.dir = xstrdup(path); | ||||||
|  | 	cp.no_stderr = 1; | ||||||
|  | 	strvec_pushl(&cp.args, "rev-list", "-n", "1", hex, "--not", "--all", NULL); | ||||||
|  |  | ||||||
|  | 	prepare_submodule_repo_env(&cp.env_array); | ||||||
|  |  | ||||||
|  | 	if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len) | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int fetch_in_submodule(const char *module_path, int depth, int quiet, struct object_id *oid) | ||||||
|  | { | ||||||
|  | 	struct child_process cp = CHILD_PROCESS_INIT; | ||||||
|  |  | ||||||
|  | 	prepare_submodule_repo_env(&cp.env_array); | ||||||
|  | 	cp.git_cmd = 1; | ||||||
|  | 	cp.dir = xstrdup(module_path); | ||||||
|  |  | ||||||
|  | 	strvec_push(&cp.args, "fetch"); | ||||||
|  | 	if (quiet) | ||||||
|  | 		strvec_push(&cp.args, "--quiet"); | ||||||
|  | 	if (depth) | ||||||
|  | 		strvec_pushf(&cp.args, "--depth=%d", depth); | ||||||
|  | 	if (oid) { | ||||||
|  | 		char *hex = oid_to_hex(oid); | ||||||
|  | 		char *remote = get_default_remote(); | ||||||
|  | 		strvec_pushl(&cp.args, remote, hex, NULL); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return run_command(&cp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int run_update_command(struct update_data *ud, int subforce) | ||||||
|  | { | ||||||
|  | 	struct strvec args = STRVEC_INIT; | ||||||
|  | 	struct strvec child_env = STRVEC_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); | ||||||
|  | 		if (subforce) | ||||||
|  | 			strvec_push(&args, "-f"); | ||||||
|  | 		break; | ||||||
|  | 	case SM_UPDATE_REBASE: | ||||||
|  | 		git_cmd = 1; | ||||||
|  | 		strvec_push(&args, "rebase"); | ||||||
|  | 		if (ud->quiet) | ||||||
|  | 			strvec_push(&args, "--quiet"); | ||||||
|  | 		must_die_on_failure = 1; | ||||||
|  | 		break; | ||||||
|  | 	case SM_UPDATE_MERGE: | ||||||
|  | 		git_cmd = 1; | ||||||
|  | 		strvec_push(&args, "merge"); | ||||||
|  | 		if (ud->quiet) | ||||||
|  | 			strvec_push(&args, "--quiet"); | ||||||
|  | 		must_die_on_failure = 1; | ||||||
|  | 		break; | ||||||
|  | 	case SM_UPDATE_COMMAND: | ||||||
|  | 		git_cmd = 0; | ||||||
|  | 		strvec_push(&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); | ||||||
|  |  | ||||||
|  | 	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)); | ||||||
|  | 		} | ||||||
|  | 		/* | ||||||
|  | 		 * 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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int do_run_update_procedure(struct update_data *ud) | ||||||
|  | { | ||||||
|  | 	int subforce = is_null_oid(&ud->suboid) || ud->force; | ||||||
|  |  | ||||||
|  | 	if (!ud->nofetch) { | ||||||
|  | 		/* | ||||||
|  | 		 * Run fetch only if `oid` isn't present or it | ||||||
|  | 		 * is not reachable from a ref. | ||||||
|  | 		 */ | ||||||
|  | 		if (!is_tip_reachable(ud->sm_path, &ud->oid) && | ||||||
|  | 		    fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, NULL) && | ||||||
|  | 		    !ud->quiet) | ||||||
|  | 			fprintf_ln(stderr, | ||||||
|  | 				   _("Unable to fetch in submodule path '%s'; " | ||||||
|  | 				     "trying to directly fetch %s:"), | ||||||
|  | 				   ud->displaypath, oid_to_hex(&ud->oid)); | ||||||
|  | 		/* | ||||||
|  | 		 * Now we tried the usual fetch, but `oid` may | ||||||
|  | 		 * not be reachable from any of the refs. | ||||||
|  | 		 */ | ||||||
|  | 		if (!is_tip_reachable(ud->sm_path, &ud->oid) && | ||||||
|  | 		    fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, &ud->oid)) | ||||||
|  | 			die(_("Fetched in submodule path '%s', but it did not " | ||||||
|  | 			      "contain %s. Direct fetching of that commit failed."), | ||||||
|  | 			    ud->displaypath, oid_to_hex(&ud->oid)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return run_update_command(ud, subforce); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void update_submodule(struct update_clone_data *ucd) | static void update_submodule(struct update_clone_data *ucd) | ||||||
| { | { | ||||||
| 	fprintf(stdout, "dummy %s %d\t%s\n", | 	fprintf(stdout, "dummy %s %d\t%s\n", | ||||||
|  | @ -2395,6 +2584,73 @@ static int update_clone(int argc, const char **argv, const char *prefix) | ||||||
| 	return update_submodules(&suc); | 	return update_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 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) | static int resolve_relative_path(int argc, const char **argv, const char *prefix) | ||||||
| { | { | ||||||
| 	struct strbuf sb = STRBUF_INIT; | 	struct strbuf sb = STRBUF_INIT; | ||||||
|  | @ -2951,6 +3207,7 @@ static struct cmd_struct commands[] = { | ||||||
| 	{"add-clone", add_clone, 0}, | 	{"add-clone", add_clone, 0}, | ||||||
| 	{"update-module-mode", module_update_module_mode, 0}, | 	{"update-module-mode", module_update_module_mode, 0}, | ||||||
| 	{"update-clone", update_clone, 0}, | 	{"update-clone", update_clone, 0}, | ||||||
|  | 	{"run-update-procedure", run_update_procedure, 0}, | ||||||
| 	{"ensure-core-worktree", ensure_core_worktree, 0}, | 	{"ensure-core-worktree", ensure_core_worktree, 0}, | ||||||
| 	{"relative-path", resolve_relative_path, 0}, | 	{"relative-path", resolve_relative_path, 0}, | ||||||
| 	{"resolve-relative-url", resolve_relative_url, 0}, | 	{"resolve-relative-url", resolve_relative_url, 0}, | ||||||
|  |  | ||||||
							
								
								
									
										104
									
								
								git-submodule.sh
								
								
								
								
							
							
						
						
									
										104
									
								
								git-submodule.sh
								
								
								
								
							|  | @ -369,13 +369,6 @@ cmd_deinit() | ||||||
| 	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" | 	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@" | ||||||
| } | } | ||||||
|  |  | ||||||
| is_tip_reachable () ( |  | ||||||
| 	sanitize_submodule_env && |  | ||||||
| 	cd "$1" && |  | ||||||
| 	rev=$(git rev-list -n 1 "$2" --not --all 2>/dev/null) && |  | ||||||
| 	test -z "$rev" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| # usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] | # usage: fetch_in_submodule <module_path> [<depth>] [<sha1>] | ||||||
| # Because arguments are positional, use an empty string to omit <depth> | # Because arguments are positional, use an empty string to omit <depth> | ||||||
| # but include <sha1>. | # but include <sha1>. | ||||||
|  | @ -519,14 +512,13 @@ cmd_update() | ||||||
|  |  | ||||||
| 		git submodule--helper ensure-core-worktree "$sm_path" || exit 1 | 		git submodule--helper ensure-core-worktree "$sm_path" || exit 1 | ||||||
|  |  | ||||||
| 		update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update) |  | ||||||
|  |  | ||||||
| 		displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") | 		displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") | ||||||
|  |  | ||||||
| 		if test $just_cloned -eq 1 | 		if test $just_cloned -eq 1 | ||||||
| 		then | 		then | ||||||
| 			subsha1= | 			subsha1= | ||||||
| 		else | 		else | ||||||
|  | 			just_cloned= | ||||||
| 			subsha1=$(sanitize_submodule_env; cd "$sm_path" && | 			subsha1=$(sanitize_submodule_env; cd "$sm_path" && | ||||||
| 				git rev-parse --verify HEAD) || | 				git rev-parse --verify HEAD) || | ||||||
| 			die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" | 			die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")" | ||||||
|  | @ -547,70 +539,38 @@ cmd_update() | ||||||
| 			die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" | 			die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
| 		if test "$subsha1" != "$sha1" || test -n "$force" | 		out=$(git submodule--helper run-update-procedure \ | ||||||
| 		then | 			  ${wt_prefix:+--prefix "$wt_prefix"} \ | ||||||
| 			subforce=$force | 			  ${GIT_QUIET:+--quiet} \ | ||||||
| 			# If we don't already have a -f flag and the submodule has never been checked out | 			  ${force:+--force} \ | ||||||
| 			if test -z "$subsha1" && test -z "$force" | 			  ${just_cloned:+--just-cloned} \ | ||||||
| 			then | 			  ${nofetch:+--no-fetch} \ | ||||||
| 				subforce="-f" | 			  ${depth:+"$depth"} \ | ||||||
| 			fi | 			  ${update:+--update "$update"} \ | ||||||
|  | 			  ${prefix:+--recursive-prefix "$prefix"} \ | ||||||
|  | 			  ${sha1:+--oid "$sha1"} \ | ||||||
|  | 			  ${subsha1:+--suboid "$subsha1"} \ | ||||||
|  | 			  "--" \ | ||||||
|  | 			  "$sm_path") | ||||||
|  |  | ||||||
| 			if test -z "$nofetch" | 		# exit codes for run-update-procedure: | ||||||
| 			then | 		# 0: update was successful, say command output | ||||||
| 				# Run fetch only if $sha1 isn't present or it | 		# 1: update procedure failed, but should not die | ||||||
| 				# is not reachable from a ref. | 		# 2 or 128: subcommand died during execution | ||||||
| 				is_tip_reachable "$sm_path" "$sha1" || | 		# 3: no update procedure was run | ||||||
| 				fetch_in_submodule "$sm_path" $depth || | 		res="$?" | ||||||
| 				say "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'; trying to directly fetch \$sha1:")" | 		case $res in | ||||||
|  | 		0) | ||||||
| 				# Now we tried the usual fetch, but $sha1 may | 			say "$out" | ||||||
| 				# not be reachable from any of the refs | 			;; | ||||||
| 				is_tip_reachable "$sm_path" "$sha1" || | 		1) | ||||||
| 				fetch_in_submodule "$sm_path" "$depth" "$sha1" || | 			err="${err};fatal: $out" | ||||||
| 				die "fatal: $(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")" | 			continue | ||||||
| 			fi | 			;; | ||||||
|  | 		2|128) | ||||||
| 			must_die_on_failure= | 			die_with_status $res "fatal: $out" | ||||||
| 			case "$update_module" in | 			;; | ||||||
| 			checkout) | 		esac | ||||||
| 				command="git checkout $subforce -q" |  | ||||||
| 				die_msg="fatal: $(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" |  | ||||||
| 				say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")" |  | ||||||
| 				;; |  | ||||||
| 			rebase) |  | ||||||
| 				command="git rebase ${GIT_QUIET:+--quiet}" |  | ||||||
| 				die_msg="fatal: $(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")" |  | ||||||
| 				say_msg="$(eval_gettext "Submodule path '\$displaypath': rebased into '\$sha1'")" |  | ||||||
| 				must_die_on_failure=yes |  | ||||||
| 				;; |  | ||||||
| 			merge) |  | ||||||
| 				command="git merge ${GIT_QUIET:+--quiet}" |  | ||||||
| 				die_msg="fatal: $(eval_gettext "Unable to merge '\$sha1' in submodule path '\$displaypath'")" |  | ||||||
| 				say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")" |  | ||||||
| 				must_die_on_failure=yes |  | ||||||
| 				;; |  | ||||||
| 			!*) |  | ||||||
| 				command="${update_module#!}" |  | ||||||
| 				die_msg="fatal: $(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")" |  | ||||||
| 				say_msg="$(eval_gettext "Submodule path '\$displaypath': '\$command \$sha1'")" |  | ||||||
| 				must_die_on_failure=yes |  | ||||||
| 				;; |  | ||||||
| 			*) |  | ||||||
| 				die "fatal: $(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")" |  | ||||||
| 			esac |  | ||||||
|  |  | ||||||
| 			if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1") |  | ||||||
| 			then |  | ||||||
| 				say "$say_msg" |  | ||||||
| 			elif test -n "$must_die_on_failure" |  | ||||||
| 			then |  | ||||||
| 				die_with_status 2 "$die_msg" |  | ||||||
| 			else |  | ||||||
| 				err="${err};$die_msg" |  | ||||||
| 				continue |  | ||||||
| 			fi |  | ||||||
| 		fi |  | ||||||
|  |  | ||||||
| 		if test -n "$recursive" | 		if test -n "$recursive" | ||||||
| 		then | 		then | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Atharva Raykar
						Atharva Raykar