diff mbox series

[RFC,20/20] submodule: add a subprocess-less submodule.useBuiltin setting

Message ID RFC-patch-20.20-b2aaad5c008-20220610T011725Z-avarab@gmail.com (mailing list archive)
State New, archived
Headers show
Series submodule: remove git-submodule.sh, create bare builtin/submodule.c | expand

Commit Message

Ævar Arnfjörð Bjarmason June 10, 2022, 2:01 a.m. UTC
Add an experimental setting to avoid the subprocess invocation of "git
submodule--helper", instead we'll call cmd_submodule__helper()
directly.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/config/submodule.txt |  4 ++++
 builtin/submodule.c                | 35 ++++++++++++++++++++++++++++--
 ci/run-build-and-tests.sh          |  1 +
 t/README                           |  4 ++++
 4 files changed, 42 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/config/submodule.txt b/Documentation/config/submodule.txt
index 6490527b45b..aa761f331c9 100644
--- a/Documentation/config/submodule.txt
+++ b/Documentation/config/submodule.txt
@@ -79,6 +79,10 @@  setting.
 * `branch` is supported only if `submodule.propagateBranches` is
 enabled
 
+submodule.useBuiltin::
+	Set to `true` to use a faster but possibly less stable subprocess-less
+	implementation of linkgit:git-submodule[1]. Is `false` by default.
+
 submodule.propagateBranches::
 	[EXPERIMENTAL] A boolean that enables branching support when
 	using `--recurse-submodules` or `submodule.recurse=true`.
diff --git a/builtin/submodule.c b/builtin/submodule.c
index b777787169e..9bb731ce87a 100644
--- a/builtin/submodule.c
+++ b/builtin/submodule.c
@@ -6,6 +6,7 @@ 
 #include "parse-options.h"
 #include "run-command.h"
 #include "strvec.h"
+#include "config.h"
 
 #define BUILTIN_SUBMODULE_USAGE \
 	"git submodule [--quiet] [--cached]"
@@ -105,17 +106,33 @@  static void setup_helper_args(int argc, const char **argv, const char *prefix,
 	strvec_pushv(args, argv);
 }
 
+static int get_use_builtin(void)
+{
+	int v;
+
+	if (git_env_bool("GIT_TEST_SUBMODULE_USE_BUILTIN", 0))
+		v = 1;
+	else if (!git_config_get_bool("submodule.usebuiltin", &v))
+		;
+	else if (!git_config_get_bool("feature.experimental", &v))
+	      ;
+
+	return v;
+}
+
 int cmd_submodule(int argc, const char **argv, const char *prefix)
 {
 	int opt_quiet = 0;
 	int opt_cached = 0;
 	struct child_process cp = CHILD_PROCESS_INIT;
+	struct strvec args = STRVEC_INIT;
 	struct option options[] = {
 		OPT__QUIET(&opt_quiet, N_("be quiet")),
 		OPT_BOOL(0, "cached", &opt_cached,
 			 N_("print the OID of submodules")),
 		OPT_END()
 	};
+	const int use_builtin = get_use_builtin();
 	int ret;
 
 	argc = parse_options(argc, argv, prefix, options, git_submodule_usage,
@@ -125,14 +142,28 @@  int cmd_submodule(int argc, const char **argv, const char *prefix)
 	 * Tell the rest of git that any URLs we get don't come
 	 * directly from the user, so it can apply policy as appropriate.
 	 */
-	strvec_push(&cp.env_array, "GIT_PROTOCOL_FROM_USER=0");
+	if (use_builtin)
+		xsetenv("GIT_PROTOCOL_FROM_USER", "0", 1);
+	else
+		strvec_push(&cp.env_array, "GIT_PROTOCOL_FROM_USER=0");
+
 	setup_helper_args(argc, argv, prefix, opt_quiet, opt_cached,
-			  &cp.args);
+			  use_builtin ? &args : &cp.args);
+
+	if (use_builtin) {
+		ret = cmd_submodule__helper(args.nr, args.v, prefix);
+		goto cleanup;
+	}
 
 	cp.git_cmd = 1;
 	cp.no_stdin = 0; /* for git submodule foreach */
 	cp.dir = startup_info->original_cwd;
 	ret = run_command(&cp);
 
+cleanup:
+	if (!use_builtin)
+		/* TODO: Double free? */
+		strvec_clear(&args);
+
 	return ret;
 }
diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
index 8ebff425967..06d40fc94aa 100755
--- a/ci/run-build-and-tests.sh
+++ b/ci/run-build-and-tests.sh
@@ -27,6 +27,7 @@  linux-TEST-vars)
 	export GIT_TEST_MULTI_PACK_INDEX=1
 	export GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=1
 	export GIT_TEST_ADD_I_USE_BUILTIN=0
+	export GIT_TEST_SUBMODULE_USE_BUILTIN=1
 	export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
 	export GIT_TEST_WRITE_REV_INDEX=1
 	export GIT_TEST_CHECKOUT_WORKERS=2
diff --git a/t/README b/t/README
index 309a31133c6..20c2e74723d 100644
--- a/t/README
+++ b/t/README
@@ -423,6 +423,10 @@  GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when false, disables the
 built-in version of git add -i. See 'add.interactive.useBuiltin' in
 git-config(1).
 
+GIT_TEST_SUBMODULE_USE_BUILTIN=<boolean>, when true, enables the
+built-in subprocess-less invocation of "git submodule--helper".
+See 'submodule.useBuiltin' in git-config(1).
+
 GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
 of the index for the whole test suite by bypassing the default number of
 cache entries and thread minimums. Setting this to 1 will make the