git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org,  Christian Couder <chriscool@tuxfamily.org>
Subject: Re: [PATCH] git: extend --no-lazy-fetch to work across subprocesses
Date: Tue, 27 Feb 2024 08:48:29 -0800	[thread overview]
Message-ID: <xmqq1q8xx38i.fsf@gitster.g> (raw)
In-Reply-To: <20240227074903.GD3263678@coredump.intra.peff.net> (Jeff King's message of "Tue, 27 Feb 2024 02:49:03 -0500")

Jeff King <peff@peff.net> writes:

> There's some prior art there, I think, in how GIT_CEILING_DIRECTORIES
> works, or even something like "git --literal-pathspecs", neither of
> which appear in local_repo_env.

Unlike GIT_CEILING_DIRECTORIES that is more or less permanent and a
part of configuring an everyday environment for real work, I view
this --no-lazy-fetch thing as solely a debugging aid.  A repository
with promisor wouldn't be able to "fill the gap" by forbidding
on-demand fetching of promised objects while running say "git fetch"
from elsewhere and it just will die with "some objects we are
supposed to have are missing from this repository".

So I do not have a strong opinion either way, if it is more
convenient to propagate the request out to other repositories when
we run processes in two or more repositories (e.g. "git clone
--local"), or if it is more convenient to make sure that the request
is limited to the target repository.  Here is a version without the
local_repo_env[] change.

----- >8 --------- >8 --------- >8 --------- >8 --------- >8 -----
Subject: [PATCH v3 3/3] 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 <gitster@pobox.com>
---
Range-diff:
1:  5fa7ddbf68 ! 1:  ea40bb9a1d git: extend --no-lazy-fetch to work across subprocesses
    @@ Commit message
         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 <gitster@pobox.com>
     
      ## Documentation/git.txt ##
    @@ Documentation/git.txt: for full details.
      	track of the reason why the ref was updated (which is
     
      ## environment.c ##
    -@@ environment.c: const char * const local_repo_env[] = {
    - 	GRAFT_ENVIRONMENT,
    - 	INDEX_ENVIRONMENT,
    - 	NO_REPLACE_OBJECTS_ENVIRONMENT,
    -+	NO_LAZY_FETCH_ENVIRONMENT,
    - 	GIT_REPLACE_REF_BASE_ENVIRONMENT,
    - 	GIT_PREFIX_ENVIRONMENT,
    - 	GIT_SHALLOW_FILE_ENVIRONMENT,
     @@ environment.c: void setup_git_env(const char *git_dir)
      	shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
      	if (shallow_file)

 Documentation/git.txt    |  7 +++++++
 environment.c            |  3 +++
 environment.h            |  1 +
 git.c                    |  3 +++
 t/t0410-partial-clone.sh | 15 +++++++++++++++
 5 files changed, 29 insertions(+)

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 `<path>` then use
 	Do not fetch missing objects from the promisor remote on
 	demand.  Useful together with `git cat-file -e <object>` 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 &&
-- 
2.44.0-35-ga2082dbdd3



  reply	other threads:[~2024-02-27 16:48 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-08 23:17 [PATCH] git: --no-lazy-fetch option Junio C Hamano
2024-02-13 20:23 ` Linus Arver
2024-02-13 20:37   ` Linus Arver
2024-02-13 20:49     ` Junio C Hamano
2024-02-15  5:30 ` Jeff King
2024-02-15 17:04   ` Junio C Hamano
2024-02-16 17:22     ` Junio C Hamano
2024-02-16 21:09       ` [PATCH] git: extend --no-lazy-fetch to work across subprocesses Junio C Hamano
2024-02-16 22:30         ` Linus Arver
2024-02-16 23:01           ` Junio C Hamano
2024-02-16 23:12             ` Linus Arver
2024-02-17  5:40         ` Jeff King
2024-02-27  6:04           ` Junio C Hamano
2024-02-27  7:49             ` Jeff King
2024-02-27 16:48               ` Junio C Hamano [this message]
2024-03-07  9:56                 ` Jeff King
2024-03-07 20:33                   ` Junio C Hamano
2024-02-17  5:29       ` [PATCH] git: --no-lazy-fetch option Jeff King
2024-03-09  1:57         ` Linus Arver
2024-02-15 20:59   ` Linus Arver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqq1q8xx38i.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).