From ac863dd26b0f2caddeb69a9108656de83243ce7b Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 17 Dec 2025 14:10:37 +0000 Subject: [PATCH 1/2] scalar: add run_git_argv Add ability to run Git commands for Scalar by passing a struct strvec rather than having to use varargs. Signed-off-by: Matthew John Cheetham --- scalar.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/scalar.c b/scalar.c index 4ad7dbd53c0ce5..7677e07b417f1f 100644 --- a/scalar.c +++ b/scalar.c @@ -88,13 +88,30 @@ static void setup_enlistment_directory(int argc, const char **argv, static int git_retries = 3; +static int run_git_argv(const struct strvec *argv) +{ + int res = 0, attempts; + + for (attempts = 0, res = 1; + res && attempts < git_retries; + attempts++) { + struct child_process cmd = CHILD_PROCESS_INIT; + + cmd.git_cmd = 1; + strvec_pushv(&cmd.args, argv->v); + res = run_command(&cmd); + } + + return res; +} + LAST_ARG_MUST_BE_NULL static int run_git(const char *arg, ...) { va_list args; const char *p; struct strvec argv = STRVEC_INIT; - int res = 0, attempts; + int res; va_start(args, arg); strvec_push(&argv, arg); @@ -102,15 +119,7 @@ static int run_git(const char *arg, ...) strvec_push(&argv, p); va_end(args); - for (attempts = 0, res = 1; - res && attempts < git_retries; - attempts++) { - struct child_process cmd = CHILD_PROCESS_INIT; - - cmd.git_cmd = 1; - strvec_pushv(&cmd.args, argv.v); - res = run_command(&cmd); - } + res = run_git_argv(&argv); strvec_clear(&argv); return res; From 33c414df357f6f5286064edde85793ab508e1e96 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 17 Dec 2025 14:11:33 +0000 Subject: [PATCH 2/2] scalar: add --ref-format option to scalar clone Add the `--ref-format` option to the `scalar clone` command. This will allow users to opt-in to creating a Scalar repository using alternative ref storage backends, such as reftable. Example: scalar clone --ref-format reftable $URL Signed-off-by: Matthew John Cheetham --- scalar.c | 26 +++++++++++++++++++++----- t/t9211-scalar-clone.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/scalar.c b/scalar.c index 7677e07b417f1f..421e23cf1b50ce 100644 --- a/scalar.c +++ b/scalar.c @@ -774,6 +774,7 @@ static int cmd_clone(int argc, const char **argv) const char *cache_server_url = NULL, *local_cache_root = NULL; char *default_cache_server_url = NULL, *local_cache_root_abs = NULL; int gvfs_protocol = -1; + const char *ref_format = NULL; struct option clone_options[] = { OPT_STRING('b', "branch", &branch, N_(""), @@ -797,18 +798,22 @@ static int cmd_clone(int argc, const char **argv) OPT_STRING(0, "local-cache-path", &local_cache_root, N_(""), N_("override the path for the local Scalar cache")), + OPT_STRING(0, "ref-format", &ref_format, N_("format"), + N_("specify the reference format to use")), OPT_HIDDEN_BOOL(0, "no-fetch-commits-and-trees", &dummy, N_("no longer used")), OPT_END(), }; const char * const clone_usage[] = { N_("scalar clone [--single-branch] [--branch ] [--full-clone]\n" - "\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] []"), + "\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] [--ref-format ]\n" + "\t []"), NULL }; const char *url; char *enlistment = NULL, *dir = NULL; struct strbuf buf = STRBUF_INIT; + struct strvec init_argv = STRVEC_INIT; int res; argc = parse_options(argc, argv, NULL, clone_options, clone_usage, 0); @@ -856,16 +861,26 @@ static int cmd_clone(int argc, const char **argv) if (!local_cache_root) die(_("could not determine local cache root")); - strbuf_reset(&buf); + strvec_clear(&init_argv); + strvec_pushf(&init_argv, "-c"); if (branch) - strbuf_addf(&buf, "init.defaultBranch=%s", branch); + strvec_pushf(&init_argv, "init.defaultBranch=%s", branch); else { char *b = repo_default_branch_name(the_repository, 1); - strbuf_addf(&buf, "init.defaultBranch=%s", b); + strvec_pushf(&init_argv, "init.defaultBranch=%s", b); free(b); } - if ((res = run_git("-c", buf.buf, "init", "--", dir, NULL))) + strvec_push(&init_argv, "init"); + + if (ref_format) { + strvec_push(&init_argv, "--ref-format"); + strvec_push(&init_argv, ref_format); + } + + strvec_push(&init_argv, "--"); + strvec_push(&init_argv, dir); + if ((res = run_git_argv(&init_argv))) goto cleanup; if (chdir(dir) < 0) { @@ -1015,6 +1030,7 @@ static int cmd_clone(int argc, const char **argv) free(enlistment); free(dir); strbuf_release(&buf); + strvec_clear(&init_argv); free(default_cache_server_url); free(local_cache_root_abs); return res; diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh index bfbf22a4621843..e4b2caa37758c5 100755 --- a/t/t9211-scalar-clone.sh +++ b/t/t9211-scalar-clone.sh @@ -201,4 +201,34 @@ test_expect_success '`scalar clone --no-src`' ' test_cmp with without ' +test_expect_success '`scalar clone --ref-format`' ' + scalar clone "file://$(pwd)/to-clone" refs-default && + scalar clone --ref-format files "file://$(pwd)/to-clone" refs-files && + scalar clone --ref-format reftable "file://$(pwd)/to-clone" refs-reftable && + + test_path_is_dir refs-default/src && + test_path_is_dir refs-files/src && + test_path_is_dir refs-reftable/src && + + ( + cd refs-default/src && + case test_detect_ref_format in + files) + test_must_fail git config --local extensions.refstorage + ;; + reftable) + test_cmp_config reftable extensions.refstorage + ;; + esac + ) && + ( + cd refs-files/src && + test_must_fail git config --local extensions.refstorage + ) && + ( + cd refs-reftable/src && + test_cmp_config reftable extensions.refstorage + ) +' + test_done