From 108e13eb71c326b8c1e13a2716b0efa2ed0b1070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?= Date: Thu, 14 Nov 2024 14:56:46 +0100 Subject: [PATCH] Add fix for extremely slow shallow clones Resolves: RHEL-64984 --- git-2.43.0-slow-shallow-clones.patch | 115 ++++++++++++++++++ ...t6300-avoid-hard-coding-object-sizes.patch | 79 ++++++++++++ git.spec | 17 ++- 3 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 git-2.43.0-slow-shallow-clones.patch create mode 100644 git-2.43.0-t6300-avoid-hard-coding-object-sizes.patch diff --git a/git-2.43.0-slow-shallow-clones.patch b/git-2.43.0-slow-shallow-clones.patch new file mode 100644 index 0000000..6d1779d --- /dev/null +++ b/git-2.43.0-slow-shallow-clones.patch @@ -0,0 +1,115 @@ +From 51441e6460b505c07b4a8a6deeaa7de4bf6e8e33 Mon Sep 17 00:00:00 2001 +From: Junio C Hamano +Date: Fri, 3 May 2024 08:34:27 -0700 +Subject: [PATCH] stop using HEAD for attributes in bare repository by default + +With 23865355 (attr: read attributes from HEAD when bare repo, +2023-10-13), we started to use the HEAD tree as the default +attribute source in a bare repository. One argument for such a +behaviour is that it would make things like "git archive" run in +bare and non-bare repositories for the same commit consistent. +This changes was merged to Git 2.43 but without an explicit mention +in its release notes. + +It turns out that this change destroys performance of shallowly +cloning from a bare repository. As the "server" installations are +expected to be mostly bare, and "git pack-objects", which is the +core of driving the other side of "git clone" and "git fetch" wants +to see if a path is set not to delta with blobs from other paths via +the attribute system, the change forces the server side to traverse +the tree of the HEAD commit needlessly to find if each and every +paths the objects it sends out has the attribute that controls the +deltification. Given that (1) most projects do not configure such +an attribute, and (2) it is dubious for the server side to honor +such an end-user supplied attribute anyway, this was a poor choice +of the default. + +To mitigate the current situation, let's revert the change that uses +the tree of HEAD in a bare repository by default as the attribute +source. This will help most people who have been happy with the +behaviour of Git 2.42 and before. + +Two things to note: + + * If you are stuck with versions of Git 2.43 or newer, that is + older than the release this fix appears in, you can explicitly + set the attr.tree configuration variable to point at an empty + tree object, i.e. + + $ git config attr.tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 + + * If you like the behaviour we are reverting, you can explicitly + set the attr.tree configuration variable to HEAD, i.e. + + $ git config attr.tree HEAD + +The right fix for this is to optimize the code paths that allow +accesses to attributes in tree objects, but that is a much more +involved change and is left as a longer-term project, outside the +scope of this "first step" fix. + +Signed-off-by: Junio C Hamano +--- + attr.c | 7 ------- + t/t0003-attributes.sh | 10 ++++++++-- + t/t5001-archive-attr.sh | 3 ++- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/attr.c b/attr.c +index e62876dfd3e9be..02ab8436266289 100644 +--- a/attr.c ++++ b/attr.c +@@ -1213,13 +1213,6 @@ static void compute_default_attr_source(struct object_id *attr_source) + ignore_bad_attr_tree = 1; + } + +- if (!default_attr_source_tree_object_name && +- startup_info->have_repository && +- is_bare_repository()) { +- default_attr_source_tree_object_name = "HEAD"; +- ignore_bad_attr_tree = 1; +- } +- + if (!default_attr_source_tree_object_name || !is_null_oid(attr_source)) + return; + +diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh +index aee2298f01331a..5de46ddf67f7ff 100755 +--- a/t/t0003-attributes.sh ++++ b/t/t0003-attributes.sh +@@ -384,13 +384,19 @@ test_expect_success 'bad attr source defaults to reading .gitattributes file' ' + ) + ' + +-test_expect_success 'bare repo defaults to reading .gitattributes from HEAD' ' ++test_expect_success 'bare repo no longer defaults to reading .gitattributes from HEAD' ' + test_when_finished rm -rf test bare_with_gitattribute && + git init test && + test_commit -C test gitattributes .gitattributes "f/path test=val" && + git clone --bare test bare_with_gitattribute && +- echo "f/path: test: val" >expect && ++ ++ echo "f/path: test: unspecified" >expect && + git -C bare_with_gitattribute check-attr test -- f/path >actual && ++ test_cmp expect actual && ++ ++ echo "f/path: test: val" >expect && ++ git -C bare_with_gitattribute -c attr.tree=HEAD \ ++ check-attr test -- f/path >actual && + test_cmp expect actual + ' + +diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh +index eaf959d8f63f15..7310774af5efea 100755 +--- a/t/t5001-archive-attr.sh ++++ b/t/t5001-archive-attr.sh +@@ -133,7 +133,8 @@ test_expect_success 'git archive vs. bare' ' + ' + + test_expect_success 'git archive with worktree attributes, bare' ' +- (cd bare && git archive --worktree-attributes HEAD) >bare-worktree.tar && ++ (cd bare && ++ git -c attr.tree=HEAD archive --worktree-attributes HEAD) >bare-worktree.tar && + (mkdir bare-worktree && cd bare-worktree && "$TAR" xf -) +Date: Tue, 12 Dec 2023 18:04:55 +0100 +Subject: [PATCH] t6300: avoid hard-coding object sizes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +f4ee22b526 (ref-filter: add tests for objectsize:disk, 2018-12-24) +hard-coded the expected object sizes. Coincidentally the size of commit +and tag is the same with zlib at the default compression level. + +1f5f8f3e85 (t6300: abstract away SHA-1-specific constants, 2020-02-22) +encoded the sizes as a single value, which coincidentally also works +with sha256. + +Different compression libraries like zlib-ng may arrive at different +values. Get them from the file system instead of hard-coding them to +make switching the compression library (or changing the compression +level) easier. + +Reported-by: Ondrej Pohorelsky +Signed-off-by: René Scharfe +Signed-off-by: Junio C Hamano +--- + t/t6300-for-each-ref.sh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh +index 00a060df0b5e81..c65c795fce2a58 100755 +--- a/t/t6300-for-each-ref.sh ++++ b/t/t6300-for-each-ref.sh +@@ -20,12 +20,13 @@ setdate_and_increment () { + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE + } + +-test_expect_success setup ' +- test_oid_cache <<-EOF && +- disklen sha1:138 +- disklen sha256:154 +- EOF ++test_object_file_size () { ++ oid=$(git rev-parse "$1") ++ path=".git/objects/$(test_oid_to_path $oid)" ++ test_file_size "$path" ++} + ++test_expect_success setup ' + # setup .mailmap + cat >.mailmap <<-EOF && + A Thor A U Thor +@@ -94,7 +95,6 @@ test_atom () { + } + + hexlen=$(test_oid hexsz) +-disklen=$(test_oid disklen) + + test_atom head refname refs/heads/main + test_atom head refname: refs/heads/main +@@ -129,7 +129,7 @@ test_atom head push:strip=1 remotes/myfork/main + test_atom head push:strip=-1 main + test_atom head objecttype commit + test_atom head objectsize $((131 + hexlen)) +-test_atom head objectsize:disk $disklen ++test_atom head objectsize:disk $(test_object_file_size refs/heads/main) + test_atom head deltabase $ZERO_OID + test_atom head objectname $(git rev-parse refs/heads/main) + test_atom head objectname:short $(git rev-parse --short refs/heads/main) +@@ -203,8 +203,8 @@ test_atom tag upstream '' + test_atom tag push '' + test_atom tag objecttype tag + test_atom tag objectsize $((114 + hexlen)) +-test_atom tag objectsize:disk $disklen +-test_atom tag '*objectsize:disk' $disklen ++test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) ++test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) + test_atom tag deltabase $ZERO_OID + test_atom tag '*deltabase' $ZERO_OID + test_atom tag objectname $(git rev-parse refs/tags/testtag) diff --git a/git.spec b/git.spec index 5e4b10e..c4d817f 100644 --- a/git.spec +++ b/git.spec @@ -93,7 +93,7 @@ Name: git Version: 2.43.0 -Release: 1%{?rcrev}%{?dist} +Release: 2%{?rcrev}%{?dist} Summary: Fast Version Control System License: GPLv2 URL: https://git-scm.com/ @@ -138,6 +138,16 @@ Patch4: 0002-t-lib-git-daemon-try-harder-to-find-a-port.patch # https://github.com/tmzullinger/git/commit/aa5105dc11 Patch5: 0003-t-lib-git-svn-try-harder-to-find-a-port.patch +# attr: read attributes from HEAD when bare repo +# +# https://github.com/git/git/commit/2386535511d1181afd4e892e2a866ffe5e1d7d21 +Patch6: git-2.43.0-slow-shallow-clones.patch + +# t6300: avoid hard-coding object sizes +# +# https://github.com/git/git/commit/fbc6526ea651565889e437ce7b12c762ef858813 +Patch7: git-2.43.0-t6300-avoid-hard-coding-object-sizes.patch + %if %{with docs} # pod2man is needed to build Git.3pm BuildRequires: %{_bindir}/pod2man @@ -1099,6 +1109,11 @@ rmdir --ignore-fail-on-non-empty "$testdir" %{?with_docs:%{_pkgdocdir}/git-svn.html} %changelog +* Thu Nov 14 2024 Ondřej Pohořelský - 2.43.0-2 +- Add fix for extremely slow shallow clones +- Repair t6300 on s390x +- Resolves: RHEL-64984 + * Wed Dec 06 2023 Ondřej Pohořelský - 2.43.0-1 - Update to 2.43.0 - Resolves: RHEL-17103