diff mbox series

[3/7] pack-objects: add GIT_TEST_FULL_NAME_HASH

Message ID 259734e0bcea952c2c09b0fb3a017e139922b975.1730775908.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series pack-objects: Create an alternative name hash algorithm (recreated) | expand

Commit Message

Derrick Stolee Nov. 5, 2024, 3:05 a.m. UTC
From: Derrick Stolee <stolee@gmail.com>

Add a new environment variable to opt-in to the --full-name-hash option
in 'git pack-objects'. This allows for extra testing of the feature
without repeating all of the test scenarios.

But this option isn't free. There are a few tests that change behavior
with the variable enabled.

First, there are a few tests that are very sensitive to certain delta
bases being picked. These are both involving the generation of thin
bundles and then counting their objects via 'git index-pack --fix-thin'
which pulls the delta base into the new packfile. For these tests,
disable the option as a decent long-term option.

Second, there are two tests in t5616-partial-clone.sh that I believe are
actually broken scenarios. While the client is set up to clone the
'promisor-server' repo via a treeless partial clone filter (tree:0),
that filter does not translate to the 'server' repo. Thus, fetching from
these repos causes the server to think that the client has all reachable
trees and blobs from the commits advertised as 'haves'. This leads the
server to providing a thin pack assuming those objects as delta bases.
Changing the name-hash algorithm presents new delta bases and thus
breaks the expectations of these tests. An alternative could be to set
up 'server' as a promisor server with the correct filter enabled. This
may also point out more issues with partial clone being set up as a
remote-based filtering mechanism and not a repository-wide setting. For
now, do the minimal change to make the test work by disabling the test
variable.

Third, there are some tests that compare the exact output of a 'git
pack-objects' process when using bitmaps. The warning that disables the
--full-name-hash option causes these tests to fail. Disable the
environment variable to get around this issue.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
---
 builtin/pack-objects.c          |  7 +++++--
 ci/run-build-and-tests.sh       |  1 +
 t/README                        |  4 ++++
 t/t5310-pack-bitmaps.sh         |  3 +++
 t/t5333-pseudo-merge-bitmaps.sh |  4 ++++
 t/t5510-fetch.sh                |  7 ++++++-
 t/t5616-partial-clone.sh        | 26 ++++++++++++++++++++++++--
 t/t6020-bundle-misc.sh          |  6 +++++-
 t/t7406-submodule-update.sh     |  2 ++
 t/t7700-repack.sh               |  6 ++++++
 10 files changed, 60 insertions(+), 6 deletions(-)

Comments

Taylor Blau Nov. 21, 2024, 8:15 p.m. UTC | #1
On Tue, Nov 05, 2024 at 03:05:03AM +0000, Derrick Stolee via GitGitGadget wrote:
> diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
> index 2e28d02b20f..75b40f07bbd 100755
> --- a/ci/run-build-and-tests.sh
> +++ b/ci/run-build-and-tests.sh
> @@ -30,6 +30,7 @@ linux-TEST-vars)
>  	export GIT_TEST_NO_WRITE_REV_INDEX=1
>  	export GIT_TEST_CHECKOUT_WORKERS=2
>  	export GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=1
> +	export GIT_TEST_FULL_NAME_HASH=1
>  	;;
>  linux-clang)
>  	export GIT_TEST_DEFAULT_HASH=sha1

Hmm. I appreciate what this new GIT_TEST_ variable is trying to do, but
I am somewhat saddened to see this list in linux-TEST-vars growing
rather than shrinking.

I'm most definitely part of the problem here, but I think too often we
add new entries to this list and let them languish without ever removing
them after they have served their intended purpose.

So I think the question is: what do we hope to get out of running the
test suite in a mode where we use the full-name hash all of the time? I
can't imagine any interesting breakage (other than individual tests'
sensitivity to specific delta/base pairs) that would be caught by merely
changing the hash function here.

I dunno. Maybe there is some exotic behavior that this shook out for you
during development which I'm not aware of. If that were the case, I
think that keeping this variable around makes sense, since the appearance
of that exotic behavior proves that the variable is useful at shaking
out bugs.

But assuming not, I think that I would just as soon avoid this test
variable entirely, which I think in this case amounts to dropping this
patch from the series.

Thanks,
Taylor
Jonathan Tan Nov. 22, 2024, 1:13 a.m. UTC | #2
"Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
> Second, there are two tests in t5616-partial-clone.sh that I believe are
> actually broken scenarios. 

I took a look...this is a tricky one.

> While the client is set up to clone the
> 'promisor-server' repo via a treeless partial clone filter (tree:0),
> that filter does not translate to the 'server' repo. Thus, fetching from
> these repos causes the server to think that the client has all reachable
> trees and blobs from the commits advertised as 'haves'. This leads the
> server to providing a thin pack assuming those objects as delta bases.

It is expected that the server sometimes sends deltas based on objects
that the client doesn't have. In fact, this test tests the ability of
Git to lazy-fetch delta bases.

> Changing the name-hash algorithm presents new delta bases and thus
> breaks the expectations of these tests.

To be precise, the change resulted in no deltas being sent (before this
change, one delta was sent). Here's what is meant to happen. The server has:

 commitB - treeB - file1 ("make the tree big\nanother line\n"), file2...file100
  |
 commitA - treeA - file1...file100 ("make the tree big\n")

The client only has commitA. (The client does not have treeA or any
blob, since it was cloned with --filter=tree:0.)

When GIT_TEST_FULL_NAME_HASH=0 (matching the current behavior), the
server sends a non-delta commitB, a delta treeB (with base treeA), and
a non-delta blob "make the tree big\nanother line\n". This triggers a
lazy fetch of treeA, and thus treeB is inflated successfully. During
the subsequent connectivity check (with --exclude-promisor-objects,
see connected.c), it is noticed that the "make the tree big\n" blob is
missing, but since it is a promisor object (referenced by treeA, which
was fetched from the promisor remote), the connectivity check since
passes.

When GIT_TEST_FULL_NAME_HASH=1, the server sends a non-delta commitB,
a non-delta treeB, and a non-delta blob "make the tree big\nanother
line\n". No lazy fetch is triggered. During the subsequent connectivity
check, the "make the tree big\n" blob (referenced by treeB) is missing.
There is nothing that can vouch for it (the client does not have treeA,
remember) so the client does not consider it a promisor object, and thus
the connectivity check fails.

Investigating this was made a bit harder due to a missing "git -C
promisor-remote config --local uploadpack.allowfilter 1" in the test.
The above behavior is after this is included in the test.

I think the solution is to have an algorithm that preserves the property
that treeB is sent as a delta object - if not, we need to find another
way to test the lazy-fetch of delta bases. My proposal in [1] does do
that.

[1] https://lore.kernel.org/git/20241121235014.2554033-1-jonathantanmy@google.com/
Junio C Hamano Nov. 22, 2024, 3:23 a.m. UTC | #3
Jonathan Tan <jonathantanmy@google.com> writes:

> ... During the subsequent connectivity
> check, the "make the tree big\n" blob (referenced by treeB) is missing.
> There is nothing that can vouch for it (the client does not have treeA,
> remember) so the client does not consider it a promisor object, and thus
> the connectivity check fails.

It is sad that it is a (probably unfixable) flaw in the "promisor
object" concept that the "promisor object"-ness of blobA depends on
the lazy-fetch status of treeA.  This is not merely a test failure,
but it would cause blobA pruned if such a lazy fetch happens in the
wild and then "git gc" triggers, no?  It may not manifest as a
repository corruption, since we would lazily fetch it again if the
user requests to fully fetch what commitA and treeA need, but it
does feel somewhat suboptimal.

Thanks for a detailed explanation on what is going on.
Derrick Stolee Nov. 22, 2024, 12:09 p.m. UTC | #4
On 11/21/24 3:15 PM, Taylor Blau wrote:
> On Tue, Nov 05, 2024 at 03:05:03AM +0000, Derrick Stolee via GitGitGadget wrote:
>> diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
>> index 2e28d02b20f..75b40f07bbd 100755
>> --- a/ci/run-build-and-tests.sh
>> +++ b/ci/run-build-and-tests.sh
>> @@ -30,6 +30,7 @@ linux-TEST-vars)
>>   	export GIT_TEST_NO_WRITE_REV_INDEX=1
>>   	export GIT_TEST_CHECKOUT_WORKERS=2
>>   	export GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=1
>> +	export GIT_TEST_FULL_NAME_HASH=1
>>   	;;
>>   linux-clang)
>>   	export GIT_TEST_DEFAULT_HASH=sha1
> 
> Hmm. I appreciate what this new GIT_TEST_ variable is trying to do, but
> I am somewhat saddened to see this list in linux-TEST-vars growing
> rather than shrinking.
You make good points that this does not need to be here.

It's enough that someone could manually check the test suite
with this test variable to make sure that enough of the other
options are tested with this feature.

Thanks,
-Stolee
Jonathan Tan Nov. 22, 2024, 6:01 p.m. UTC | #5
Junio C Hamano <gitster@pobox.com> writes:
> It is sad that it is a (probably unfixable) flaw in the "promisor
> object" concept that the "promisor object"-ness of blobA depends on
> the lazy-fetch status of treeA.  This is not merely a test failure,
> but it would cause blobA pruned if such a lazy fetch happens in the
> wild and then "git gc" triggers, no?  

Right now, it won't be pruned since we never prune promisor objects
(we just concatenate all of them into one file). But in the future, we
might only keep reachable promisor objects, in which case, yes, blobA
will be pruned. In this case, though, I think blobA is like any other
unreachable object in git. If a user memorizes a commit hash but does
not point a ref to it (or point a ref to one of its descendants), that
commit is still subject to being lost by GC. I think it's the same case
here.
Junio C Hamano Nov. 25, 2024, 12:39 a.m. UTC | #6
Jonathan Tan <jonathantanmy@google.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>> It is sad that it is a (probably unfixable) flaw in the "promisor
>> object" concept that the "promisor object"-ness of blobA depends on
>> the lazy-fetch status of treeA.  This is not merely a test failure,
>> but it would cause blobA pruned if such a lazy fetch happens in the
>> wild and then "git gc" triggers, no?  
>
> Right now, it won't be pruned since we never prune promisor objects
> (we just concatenate all of them into one file).

Sorry, but I am lost.  In the scenario discussed, you have two
commits A and B with their trees and blobs.  You initially only have
commit A because the partial clone is done with "tree:0".  Then you
fetch commit B (A's child), tree B in non-delta form, and blob B
contained within tree B.  Due to the tweak in the name hash
function, we do not know of tree A (we used to learn about it
because tree B was sent as a delta against it with the old name
hash).  If blob B was sent as a delta against blob A, lazy fetch
would later materialize blob A even if you do not still have tree A,
no?

I thought the story was that we would not know who refers to blobA
when treeA hasn't been lazily fetched, hence we cannot tell if blobA
is a "promisor object" to begin with, no?

The blob in such a scenario may be reclaimed by GC and we may still
be able to refetch from the promisor, so it may not be the end of
the world, but feels suboptimal.
Jonathan Tan Nov. 25, 2024, 7:45 p.m. UTC | #7
Junio C Hamano <gitster@pobox.com> writes:
> Jonathan Tan <jonathantanmy@google.com> writes:
> 
> > Junio C Hamano <gitster@pobox.com> writes:
> >> It is sad that it is a (probably unfixable) flaw in the "promisor
> >> object" concept that the "promisor object"-ness of blobA depends on
> >> the lazy-fetch status of treeA.  This is not merely a test failure,
> >> but it would cause blobA pruned if such a lazy fetch happens in the
> >> wild and then "git gc" triggers, no?  
> >
> > Right now, it won't be pruned since we never prune promisor objects
> > (we just concatenate all of them into one file).
> 
> Sorry, but I am lost.  In the scenario discussed, you have two
> commits A and B with their trees and blobs.  You initially only have
> commit A because the partial clone is done with "tree:0".  Then you
> fetch commit B (A's child), tree B in non-delta form, and blob B
> contained within tree B.  Due to the tweak in the name hash
> function, we do not know of tree A (we used to learn about it
> because tree B was sent as a delta against it with the old name
> hash).  

Yes, that's correct.

> If blob B was sent as a delta against blob A, lazy fetch
> would later materialize blob A even if you do not still have tree A,
> no?

Just to be clear, this is not happening right now (blob B is sent whole,
not as a delta). But let's suppose that blob B was sent as a delta, then
yes, the lazy fetch would materialize blob A...

> I thought the story was that we would not know who refers to blobA
> when treeA hasn't been lazily fetched, hence we cannot tell if blobA
> is a "promisor object" to begin with, no?

...ah, in this case, blob A vouches for itself. Whenever we lazy fetch,
all objects that are fetched go into promisor packs (packfiles with an
associated .promisor file), so we know that they are promisor objects.
Junio C Hamano Nov. 26, 2024, 1:29 a.m. UTC | #8
Jonathan Tan <jonathantanmy@google.com> writes:

> ...ah, in this case, blob A vouches for itself. Whenever we lazy fetch,
> all objects that are fetched go into promisor packs (packfiles with an
> associated .promisor file), so we know that they are promisor objects.

Thanks.
Patrick Steinhardt Nov. 26, 2024, 8:26 a.m. UTC | #9
On Tue, Nov 05, 2024 at 03:05:03AM +0000, Derrick Stolee via GitGitGadget wrote:
> diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
> index c53e93be2f7..425aa8d8789 100755
> --- a/t/t5616-partial-clone.sh
> +++ b/t/t5616-partial-clone.sh
> @@ -516,7 +516,18 @@ test_expect_success 'fetch lazy-fetches only to resolve deltas' '
>  	# Exercise to make sure it works. Git will not fetch anything from the
>  	# promisor remote other than for the big tree (because it needs to
>  	# resolve the delta).
> -	GIT_TRACE_PACKET="$(pwd)/trace" git -C client \
> +	#
> +	# TODO: the --full-name-hash option is disabled here, since this test
> +	# is fundamentally broken! When GIT_TEST_FULL_NAME_HASH=1, the server
> +	# recognizes delta bases in a different way and then sends a _blob_ to
> +	# the client with a delta base that the client does not have! This is
> +	# because the client is cloned from "promisor-server" with tree:0 but
> +	# is now fetching from "server" withot any filter. This is violating the

s/withot/without/

Also present in copies of this comment.

> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
> index 0f0c86f9cb2..03f8c976720 100755
> --- a/t/t7406-submodule-update.sh
> +++ b/t/t7406-submodule-update.sh
> @@ -1094,6 +1094,8 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s
>  	) &&
>  	git clone super4 super5 &&
>  	(cd super5 &&
> +	 # This test var can mess with the stderr output checked in this test.
> +	 GIT_TEST_FULL_NAME_HASH=0 \
>  	 git submodule update --quiet --init --depth=1 submodule3 >out 2>err &&

Nit: This line should now be indented.

>  	 test_must_be_empty out &&
>  	 test_must_be_empty err
> diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
> index fc2cc9d37be..e3787bacdad 100755
> --- a/t/t7700-repack.sh
> +++ b/t/t7700-repack.sh
> @@ -309,6 +309,9 @@ test_expect_success 'no bitmaps created if .keep files present' '
>  	keep=${pack%.pack}.keep &&
>  	test_when_finished "rm -f \"\$keep\"" &&
>  	>"$keep" &&
> +
> +	# Disable --full-name-hash test due to stderr comparison.
> +	GIT_TEST_FULL_NAME_HASH=0 \
>  	git -C bare.git repack -ad 2>stderr &&

Same here.

>  	test_must_be_empty stderr &&
>  	find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
> @@ -320,6 +323,9 @@ test_expect_success 'auto-bitmaps do not complain if unavailable' '
>  	blob=$(test-tool genrandom big $((1024*1024)) |
>  	       git -C bare.git hash-object -w --stdin) &&
>  	git -C bare.git update-ref refs/tags/big $blob &&
> +
> +	# Disable --full-name-hash test due to stderr comparison.
> +	GIT_TEST_FULL_NAME_HASH=0 \
>  	git -C bare.git repack -ad 2>stderr &&

And here.

Patrick
diff mbox series

Patch

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 85595dfcd88..7cb6f0e0942 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -266,7 +266,7 @@  struct configured_exclusion {
 static struct oidmap configured_exclusions;
 
 static struct oidset excluded_by_config;
-static int use_full_name_hash;
+static int use_full_name_hash = -1;
 
 static inline uint32_t pack_name_hash_fn(const char *name)
 {
@@ -4586,7 +4586,10 @@  int cmd_pack_objects(int argc,
 	if (pack_to_stdout || !rev_list_all)
 		write_bitmap_index = 0;
 
-	if (write_bitmap_index && use_full_name_hash) {
+	if (use_full_name_hash < 0)
+		use_full_name_hash = git_env_bool("GIT_TEST_FULL_NAME_HASH", 0);
+
+	if (write_bitmap_index && use_full_name_hash > 0) {
 		warning(_("currently, the --full-name-hash option is incompatible with --write-bitmap-index"));
 		use_full_name_hash = 0;
 	}
diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
index 2e28d02b20f..75b40f07bbd 100755
--- a/ci/run-build-and-tests.sh
+++ b/ci/run-build-and-tests.sh
@@ -30,6 +30,7 @@  linux-TEST-vars)
 	export GIT_TEST_NO_WRITE_REV_INDEX=1
 	export GIT_TEST_CHECKOUT_WORKERS=2
 	export GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=1
+	export GIT_TEST_FULL_NAME_HASH=1
 	;;
 linux-clang)
 	export GIT_TEST_DEFAULT_HASH=sha1
diff --git a/t/README b/t/README
index 8c0319b58e5..fe3f89b5b28 100644
--- a/t/README
+++ b/t/README
@@ -492,6 +492,10 @@  a test and then fails then the whole test run will abort. This can help to make
 sure the expected tests are executed and not silently skipped when their
 dependency breaks or is simply not present in a new environment.
 
+GIT_TEST_FULL_NAME_HASH=<boolean>, when true, sets the default name-hash
+function in 'git pack-objects' to be the one used by the --full-name-hash
+option.
+
 Naming Tests
 ------------
 
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 7044c7d7c6d..caa3c125548 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -420,6 +420,9 @@  test_bitmap_cases () {
 			cat >expect <<-\EOF &&
 			error: missing value for '\''pack.preferbitmaptips'\''
 			EOF
+
+			# Disable --full-name-hash test due to stderr comparison.
+			GIT_TEST_FULL_NAME_HASH=0 \
 			git repack -adb 2>actual &&
 			test_cmp expect actual
 		)
diff --git a/t/t5333-pseudo-merge-bitmaps.sh b/t/t5333-pseudo-merge-bitmaps.sh
index eca4a1eb8c6..0c7c3e33986 100755
--- a/t/t5333-pseudo-merge-bitmaps.sh
+++ b/t/t5333-pseudo-merge-bitmaps.sh
@@ -209,6 +209,10 @@  test_expect_success 'bitmapPseudoMerge.stableThreshold creates stable groups' '
 '
 
 test_expect_success 'out of order thresholds are rejected' '
+	# Disable this option to avoid stderr message
+	GIT_TEST_FULL_NAME_HASH=0 &&
+	export GIT_TEST_FULL_NAME_HASH &&
+
 	test_must_fail git \
 		-c bitmapPseudoMerge.test.pattern="refs/*" \
 		-c bitmapPseudoMerge.test.threshold=1.month.ago \
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 0890b9f61c5..be79c72495e 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -1062,7 +1062,12 @@  test_expect_success 'all boundary commits are excluded' '
 	test_tick &&
 	git merge otherside &&
 	ad=$(git log --no-walk --format=%ad HEAD) &&
-	git bundle create twoside-boundary.bdl main --since="$ad" &&
+
+	# If the --full-name-hash function is used here, then no delta
+	# pair is found and the bundle does not expand to three objects
+	# when fixing the thin object.
+	GIT_TEST_FULL_NAME_HASH=0 \
+		git bundle create twoside-boundary.bdl main --since="$ad" &&
 	test_bundle_object_count --thin twoside-boundary.bdl 3
 '
 
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index c53e93be2f7..425aa8d8789 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -516,7 +516,18 @@  test_expect_success 'fetch lazy-fetches only to resolve deltas' '
 	# Exercise to make sure it works. Git will not fetch anything from the
 	# promisor remote other than for the big tree (because it needs to
 	# resolve the delta).
-	GIT_TRACE_PACKET="$(pwd)/trace" git -C client \
+	#
+	# TODO: the --full-name-hash option is disabled here, since this test
+	# is fundamentally broken! When GIT_TEST_FULL_NAME_HASH=1, the server
+	# recognizes delta bases in a different way and then sends a _blob_ to
+	# the client with a delta base that the client does not have! This is
+	# because the client is cloned from "promisor-server" with tree:0 but
+	# is now fetching from "server" withot any filter. This is violating the
+	# promise to the server that all reachable objects exist and could be
+	# used as delta bases!
+	GIT_TRACE_PACKET="$(pwd)/trace" \
+	GIT_TEST_FULL_NAME_HASH=0 \
+		git -C client \
 		fetch "file://$(pwd)/server" main &&
 
 	# Verify the assumption that the client needed to fetch the delta base
@@ -535,7 +546,18 @@  test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' '
 	# Exercise to make sure it works. Git will not fetch anything from the
 	# promisor remote other than for the big blob (because it needs to
 	# resolve the delta).
-	GIT_TRACE_PACKET="$(pwd)/trace" git -C client \
+	#
+	# TODO: the --full-name-hash option is disabled here, since this test
+	# is fundamentally broken! When GIT_TEST_FULL_NAME_HASH=1, the server
+	# recognizes delta bases in a different way and then sends a _blob_ to
+	# the client with a delta base that the client does not have! This is
+	# because the client is cloned from "promisor-server" with tree:0 but
+	# is now fetching from "server" withot any filter. This is violating the
+	# promise to the server that all reachable objects exist and could be
+	# used as delta bases!
+	GIT_TRACE_PACKET="$(pwd)/trace" \
+	GIT_TEST_FULL_NAME_HASH=0 \
+		git -C client \
 		fetch "file://$(pwd)/server" main &&
 
 	# Verify that protocol version 2 was used.
diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh
index 34b5cd62c20..553a20d10e9 100755
--- a/t/t6020-bundle-misc.sh
+++ b/t/t6020-bundle-misc.sh
@@ -247,7 +247,11 @@  test_expect_success 'create bundle with --since option' '
 	EOF
 	test_cmp expect actual &&
 
-	git bundle create since.bdl \
+	# If the --full-name-hash option is used, then one fewer
+	# delta base is found and this counts a different number
+	# of objects after performing --fix-thin.
+	GIT_TEST_FULL_NAME_HASH=0 \
+		git bundle create since.bdl \
 		--since "Thu Apr 7 15:27:00 2005 -0700" \
 		--all &&
 
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 0f0c86f9cb2..03f8c976720 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -1094,6 +1094,8 @@  test_expect_success 'submodule update --quiet passes quietness to fetch with a s
 	) &&
 	git clone super4 super5 &&
 	(cd super5 &&
+	 # This test var can mess with the stderr output checked in this test.
+	 GIT_TEST_FULL_NAME_HASH=0 \
 	 git submodule update --quiet --init --depth=1 submodule3 >out 2>err &&
 	 test_must_be_empty out &&
 	 test_must_be_empty err
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index fc2cc9d37be..e3787bacdad 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -309,6 +309,9 @@  test_expect_success 'no bitmaps created if .keep files present' '
 	keep=${pack%.pack}.keep &&
 	test_when_finished "rm -f \"\$keep\"" &&
 	>"$keep" &&
+
+	# Disable --full-name-hash test due to stderr comparison.
+	GIT_TEST_FULL_NAME_HASH=0 \
 	git -C bare.git repack -ad 2>stderr &&
 	test_must_be_empty stderr &&
 	find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
@@ -320,6 +323,9 @@  test_expect_success 'auto-bitmaps do not complain if unavailable' '
 	blob=$(test-tool genrandom big $((1024*1024)) |
 	       git -C bare.git hash-object -w --stdin) &&
 	git -C bare.git update-ref refs/tags/big $blob &&
+
+	# Disable --full-name-hash test due to stderr comparison.
+	GIT_TEST_FULL_NAME_HASH=0 \
 	git -C bare.git repack -ad 2>stderr &&
 	test_must_be_empty stderr &&
 	find bare.git/objects/pack -type f -name "*.bitmap" >actual &&