From: Junio C Hamano Date: Tue, 27 Feb 2024 16:48:29 +0000 (-0800) Subject: git: extend --no-lazy-fetch to work across subprocesses X-Git-Tag: v2.45.0-rc0~134^2 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fgit.git;a=commitdiff_plain;h=e6d5479e7ac301ae8d11daa3d8ef748e891c91c3 git: extend --no-lazy-fetch to work across subprocesses Modeling after how the `--no-replace-objects` option is made usable across subprocess spawning (e.g., cURL based remote helpers are spawned as a separate process while running "git fetch"), allow the `--no-lazy-fetch` option to be passed across process boundaries. Do not model how the value of GIT_NO_REPLACE_OBJECTS environment variable is ignored, though. Just use the usual git_env_bool() to allow "export GIT_NO_LAZY_FETCH=0" and "unset GIT_NO_LAZY_FETCH" to be equivalents. Also do not model how the request is not propagated to subprocesses we spawn (e.g. "git clone --local" that spawns a new process to work in the origin repository, while the original one working in the newly created one) by the "--no-replace-objects" option, as this "do not lazily fetch from the promisor" is more about a per-request debugging aid, not "this repository's promisor should not be relied upon" property specific to a repository. Signed-off-by: Junio C Hamano --- diff --git a/Documentation/git.txt b/Documentation/git.txt index b1f754e84b..a517d94a7a 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -183,6 +183,8 @@ If you just want to run git as if it was started in `` then use Do not fetch missing objects from the promisor remote on demand. Useful together with `git cat-file -e ` to see if the object is locally available. + This is equivalent to setting the `GIT_NO_LAZY_FETCH` + environment variable to `1`. --literal-pathspecs:: Treat pathspecs literally (i.e. no globbing, no pathspec magic). @@ -900,6 +902,11 @@ for full details. Setting this Boolean environment variable to true will cause Git to treat all pathspecs as case-insensitive. +`GIT_NO_LAZY_FETCH`:: + Setting this Boolean environment variable to true tells Git + not to lazily fetch missing objects from the promisor remote + on demand. + `GIT_REFLOG_ACTION`:: When a ref is updated, reflog entries are created to keep track of the reason why the ref was updated (which is diff --git a/environment.c b/environment.c index 9e37bf58c0..0ae5bbd4a1 100644 --- a/environment.c +++ b/environment.c @@ -207,6 +207,9 @@ void setup_git_env(const char *git_dir) shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); if (shallow_file) set_alternate_shallow_file(the_repository, shallow_file, 0); + + if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) + fetch_if_missing = 0; } int is_bare_repository(void) diff --git a/environment.h b/environment.h index e5351c9dd9..5cec19cecc 100644 --- a/environment.h +++ b/environment.h @@ -36,6 +36,7 @@ const char *getenv_safe(struct strvec *argv, const char *name); #define CEILING_DIRECTORIES_ENVIRONMENT "GIT_CEILING_DIRECTORIES" #define NO_REPLACE_OBJECTS_ENVIRONMENT "GIT_NO_REPLACE_OBJECTS" #define GIT_REPLACE_REF_BASE_ENVIRONMENT "GIT_REPLACE_REF_BASE" +#define NO_LAZY_FETCH_ENVIRONMENT "GIT_NO_LAZY_FETCH" #define GITATTRIBUTES_FILE ".gitattributes" #define INFOATTRIBUTES_FILE "info/attributes" #define ATTRIBUTE_MACRO_PREFIX "[attr]" diff --git a/git.c b/git.c index 28e8bf7497..d11d4dc77b 100644 --- a/git.c +++ b/git.c @@ -189,6 +189,9 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-lazy-fetch")) { fetch_if_missing = 0; + setenv(NO_LAZY_FETCH_ENVIRONMENT, "1", 1); + if (envchanged) + *envchanged = 1; } else if (!strcmp(cmd, "--no-replace-objects")) { disable_replace_refs(); setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1); diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 5b7bee888d..c282851af7 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -665,6 +665,21 @@ test_expect_success 'lazy-fetch when accessing object not in the_repository' ' git -C partial.git rev-list --objects --missing=print HEAD >out && grep "[?]$FILE_HASH" out && + # The no-lazy-fetch mechanism prevents Git from fetching + test_must_fail env GIT_NO_LAZY_FETCH=1 \ + git -C partial.git cat-file -e "$FILE_HASH" && + + # The same with command line option to "git" + test_must_fail git --no-lazy-fetch -C partial.git cat-file -e "$FILE_HASH" && + + # The same, forcing a subprocess via an alias + test_must_fail git --no-lazy-fetch -C partial.git \ + -c alias.foo="!git cat-file" foo -e "$FILE_HASH" && + + # Sanity check that the file is still missing + git -C partial.git rev-list --objects --missing=print HEAD >out && + grep "[?]$FILE_HASH" out && + git -C full cat-file -s "$FILE_HASH" >expect && test-tool partial-clone object-info partial.git "$FILE_HASH" >actual && test_cmp expect actual &&