From 822ec7a946b82c3acbfe5bd070338164b9867b8a Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 4 Oct 2022 08:01:17 -0400 Subject: [PATCH 1/3] abspath: make strip_last_path_component() global The strip_last_component() method is helpful for finding the parent directory of a path stored in a strbuf. Extract it to a global method advertised in path.h. With that additional visibility, it is helpful to rename it to be more specific to paths. Signed-off-by: Derrick Stolee --- abspath.c | 6 +++--- path.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/abspath.c b/abspath.c index 7a5f114382f182..058e638e986e98 100644 --- a/abspath.c +++ b/abspath.c @@ -12,7 +12,7 @@ int is_directory(const char *path) } /* removes the last path component from 'path' except if 'path' is root */ -static void strip_last_component(struct strbuf *path) +void strip_last_path_component(struct strbuf *path) { size_t offset = offset_1st_component(path->buf); size_t len = path->len; @@ -117,7 +117,7 @@ static char *strbuf_realpath_1(struct strbuf *resolved, const char *path, continue; /* '.' component */ } else if (next.len == 2 && !strcmp(next.buf, "..")) { /* '..' component; strip the last path component */ - strip_last_component(resolved); + strip_last_path_component(resolved); continue; } @@ -169,7 +169,7 @@ static char *strbuf_realpath_1(struct strbuf *resolved, const char *path, * strip off the last component since it will * be replaced with the contents of the symlink */ - strip_last_component(resolved); + strip_last_path_component(resolved); } /* diff --git a/path.h b/path.h index 0a59c85a62eda0..db417a43bd859d 100644 --- a/path.h +++ b/path.h @@ -179,6 +179,10 @@ const char *git_path_auto_merge(struct repository *r); const char *git_path_fetch_head(struct repository *r); const char *git_path_shallow(struct repository *r); +/** + * Remove the last path component from 'path' except if 'path' is root. + */ +void strip_last_path_component(struct strbuf *path); int ends_with_path_components(const char *path, const char *components); From 35434e13331b56fda48df85a6dc8b045a2c84095 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 30 Sep 2022 12:41:27 -0400 Subject: [PATCH 2/3] scalar: .scalarCache should live above enlistment We should not be putting the .scalarCache inside the enlistment as a sibling to the 'src' directory. This only happens in "unattended" mode, but it also negates any benefit of a shared object cache because each enlistment absolutely does not share any objects with others. Move the shared object cache in this case to a level above the enlistment, so at least there is some hope that it can be reused. This is also critical to the upcoming --no-src option, since the shared object cache cannot be located within the Git repository. Signed-off-by: Derrick Stolee --- scalar.c | 10 ++++++++-- t/t9210-scalar.sh | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scalar.c b/scalar.c index 08bac10525273f..003aaeab9b02be 100644 --- a/scalar.c +++ b/scalar.c @@ -16,6 +16,7 @@ #include "help.h" #include "json-parser.h" #include "remote.h" +#include "path.h" static int is_unattended(void) { return git_env_bool("Scalar_UNATTENDED", 0); @@ -470,8 +471,13 @@ static char *default_cache_root(const char *root) { const char *env; - if (is_unattended()) - return xstrfmt("%s/.scalarCache", root); + if (is_unattended()) { + struct strbuf path = STRBUF_INIT; + strbuf_addstr(&path, root); + strip_last_path_component(&path); + strbuf_addstr(&path, "/.scalarCache"); + return strbuf_detach(&path, NULL); + } #ifdef WIN32 (void)env; diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 6acf279afd740d..548bff71aeb094 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -306,7 +306,7 @@ test_expect_success '`scalar clone` with GVFS-enabled server' ' cache_key="url_$(printf "%s" http://$HOST_PORT/ | tr A-Z a-z | test-tool sha1)" && - echo "$(pwd)/using-gvfs/.scalarCache/$cache_key" >expect && + echo "$(pwd)/.scalarCache/$cache_key" >expect && git -C using-gvfs/src config gvfs.sharedCache >actual && test_cmp expect actual && From 78fa0e8d6d76537eb05809aa109fcd37e59fe894 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 30 Sep 2022 12:44:27 -0400 Subject: [PATCH 3/3] scalar: add --no-src option Some users have strong aversions to Scalar's opinion that the repository should be in a 'src' directory, even though it creates a clean slate for placing build outputs in adjacent directories. The --no-src option allows users to opt-out of the default behavior. The parse-opt logic automatically figures out that '--src' is a possible flag that negates '--no-src'. Signed-off-by: Derrick Stolee --- Documentation/scalar.txt | 5 ++++- scalar.c | 14 ++++++++++++-- t/t9210-scalar.sh | 8 ++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Documentation/scalar.txt b/Documentation/scalar.txt index 0424d020d9b9f4..35f67801e92a98 100644 --- a/Documentation/scalar.txt +++ b/Documentation/scalar.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] scalar clone [--single-branch] [--branch ] [--full-clone] - [--local-cache-path ] [--cache-server-url ] + [--local-cache-path ] [--cache-server-url ] [--[no-]src] [] scalar list scalar register [] @@ -83,6 +83,9 @@ remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when `--single-branch` clone was made, no remote-tracking branch is created. +--no-src:: + Skip adding a `src` directory within the target enlistment. + --[no-]full-clone:: A sparse-checkout is initialized by default. This behavior can be turned off via `--full-clone`. diff --git a/scalar.c b/scalar.c index 003aaeab9b02be..0b0d6297da2771 100644 --- a/scalar.c +++ b/scalar.c @@ -701,6 +701,8 @@ static int cmd_clone(int argc, const char **argv) int full_clone = 0, single_branch = 0, show_progress = isatty(2); const char *cache_server_url = NULL, *local_cache_root = NULL; char *default_cache_server_url = NULL, *local_cache_root_abs = NULL; + const char *enlistment_parent; + int no_src = 0; struct option clone_options[] = { OPT_STRING('b', "branch", &branch, N_(""), N_("branch to checkout after clone")), @@ -709,6 +711,8 @@ static int cmd_clone(int argc, const char **argv) OPT_BOOL(0, "single-branch", &single_branch, N_("only download metadata for the branch that will " "be checked out")), + OPT_BOOL(0, "no-src", &no_src, + N_("skip creating a 'src' directory")), OPT_STRING(0, "cache-server-url", &cache_server_url, N_(""), N_("the url or friendly name of the cache server")), @@ -759,7 +763,13 @@ static int cmd_clone(int argc, const char **argv) ensure_absolute_path(enlistment, &enlistment); - dir = xstrfmt("%s/src", enlistment); + if (!no_src) { + dir = xstrfmt("%s/src", enlistment); + enlistment_parent = "../.."; + } else { + dir = xstrdup(enlistment); + enlistment_parent = ".."; + } if (!local_cache_root) local_cache_root = local_cache_root_abs = @@ -800,7 +810,7 @@ static int cmd_clone(int argc, const char **argv) struct strbuf path = STRBUF_INIT; strbuf_addstr(&path, enlistment); - if (chdir("../..") < 0 || + if (chdir(enlistment_parent) < 0 || remove_dir_recursively(&path, 0) < 0) die(_("'--local-cache-path' cannot be inside the src " "folder;\nCould not remove '%s'"), enlistment); diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 548bff71aeb094..43c4208cdc31b1 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -391,4 +391,12 @@ test_expect_success '`scalar delete` with existing repo' ' test_path_is_missing existing ' +test_expect_success '`scalar clone --no-src`' ' + scalar clone --src "file://$(pwd)" with-src && + scalar clone --no-src "file://$(pwd)" without-src && + + test_path_is_dir with-src/src && + test_path_is_missing without-src/src +' + test_done