scalar: add --no-tags option to 'scalar clone'

Some large repositories use tags to track a huge list of release versions. While this choice is costly on the ref advertisement, it is further wasteful for clients who do not need those tags. Allow clients to optionally skip the tag advertisement. This behavior is similar to that of 'git clone --no-tags' implemented in 0dab2468ee5 (clone: add a --no-tags option to clone without tags, 2017-04-26), including the modification of the remote.origin.tagOpt config value to include "--no-tags". One thing that is opposite of the 'git clone' implementation is that this allows '--tags' as an assumed option, which can be naturally negated with '--no-tags'. The clone command does not accept '--tags' but allows "--no-no-tags" as the negation of its '--no-tags' option. While testing this option, combine the test with the previously untested '--no-src' option introduced in 4527db8ff8c (scalar: add --[no-]src option, 2023-08-28). Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Sep 6, 2024 at 20:21 UTC ce31b82ca95ba13aba424a1e3d09a292637f6f1d
3 files changed +37 -3
Documentation/scalar.txt
+7
@@ -86,6 +86,13 @@ cloning. If the HEAD at the remote did not point at any branch when
86 `<entlistment>/src` directory. Use `--no-src` to place the cloned
87 repository directly in the `<enlistment>` directory.
88
89 +--[no-]tags::
90 + By default, `scalar clone` will fetch the tag objects advertised by
91 + the remote and future `git fetch` commands will do the same. Use
92 + `--no-tags` to avoid fetching tags in `scalar clone` and to configure
93 + the repository to avoid fetching tags in the future. To fetch tags after
94 + cloning with `--no-tags`, run `git fetch --tags`.
95 +
96 --[no-]full-clone::
97 A sparse-checkout is initialized by default. This behavior can be
98 turned off via `--full-clone`.
scalar.c
+12 -3
@@ -410,7 +410,7 @@ static int cmd_clone(int argc, const char **argv)
410 {
411 const char *branch = NULL;
412 int full_clone = 0, single_branch = 0, show_progress = isatty(2);
413 - int src = 1;
413 + int src = 1, tags = 1;
414 struct option clone_options[] = {
415 OPT_STRING('b', "branch", &branch, N_("<branch>"),
416 N_("branch to checkout after clone")),
@@ -421,11 +421,13 @@ static int cmd_clone(int argc, const char **argv)
421 "be checked out")),
422 OPT_BOOL(0, "src", &src,
423 N_("create repository within 'src' directory")),
424 + OPT_BOOL(0, "tags", &tags,
425 + N_("specify if tags should be fetched during clone")),
426 OPT_END(),
427 };
428 const char * const clone_usage[] = {
429 N_("scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n"
428 - "\t[--[no-]src] <url> [<enlistment>]"),
430 + "\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]"),
431 NULL
432 };
433 const char *url;
@@ -504,6 +506,11 @@ static int cmd_clone(int argc, const char **argv)
506 goto cleanup;
507 }
508
509 + if (!tags && set_config("remote.origin.tagOpt=--no-tags")) {
510 + res = error(_("could not disable tags in '%s'"), dir);
511 + goto cleanup;
512 + }
513 +
514 if (!full_clone &&
515 (res = run_git("sparse-checkout", "init", "--cone", NULL)))
516 goto cleanup;
@@ -513,7 +520,9 @@ static int cmd_clone(int argc, const char **argv)
520
521 if ((res = run_git("fetch", "--quiet",
522 show_progress ? "--progress" : "--no-progress",
516 - "origin", NULL))) {
523 + "origin",
524 + (tags ? NULL : "--no-tags"),
525 + NULL))) {
526 warning(_("partial clone failed; attempting full clone"));
527
528 if (set_config("remote.origin.promisor") ||
t/t9210-scalar.sh
+18
@@ -169,6 +169,24 @@ test_expect_success 'scalar clone' '
169 )
170 '
171
172 +test_expect_success 'scalar clone --no-... opts' '
173 + # Note: redirect stderr always to avoid having a verbose test
174 + # run result in a difference in the --[no-]progress option.
175 + GIT_TRACE2_EVENT="$(pwd)/no-opt-trace" scalar clone \
176 + --no-tags --no-src \
177 + "file://$(pwd)" no-opts --single-branch 2>/dev/null &&
178 +
179 + test_subcommand git fetch --quiet --no-progress \
180 + origin --no-tags <no-opt-trace &&
181 + (
182 + cd no-opts &&
183 +
184 + test_cmp_config --no-tags remote.origin.tagopt &&
185 + git for-each-ref --format="%(refname)" refs/tags/ >tags &&
186 + test_line_count = 0 tags
187 + )
188 +'
189 +
190 test_expect_success 'scalar reconfigure' '
191 git init one/src &&
192 scalar register one &&