aboutsummaryrefslogtreecommitdiffstats
path: root/t
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-02-12 10:08:51 -0800
committerJunio C Hamano <gitster@pobox.com>2025-02-12 10:08:51 -0800
commitaae91a86fb2a71ff89a71b63ccec3a947b26ca51 (patch)
tree3bfc421ac1b1f445d22bae71a3b3524ec993fb4c /t
parent388218fac77d0405a5083cd4b4ee20f6694609c3 (diff)
parentb4cf68476a983ff063846b43cd46ee9805f2c0bb (diff)
downloadgit-aae91a86fb2a71ff89a71b63ccec3a947b26ca51.tar.gz
Merge branch 'ds/name-hash-tweaks'
"git pack-objects" and its wrapper "git repack" learned an option to use an alternative path-hash function to improve delta-base selection to produce a packfile with deeper history than window size. * ds/name-hash-tweaks: pack-objects: prevent name hash version change test-tool: add helper for name-hash values p5313: add size comparison test pack-objects: add GIT_TEST_NAME_HASH_VERSION repack: add --name-hash-version option pack-objects: add --name-hash-version option pack-objects: create new name-hash function version
Diffstat (limited to 't')
-rw-r--r--t/README4
-rw-r--r--t/helper/meson.build1
-rw-r--r--t/helper/test-name-hash.c23
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rwxr-xr-xt/perf/p5313-pack-objects.sh70
-rwxr-xr-xt/perf/p5314-name-hash.sh31
-rw-r--r--t/t0450/txt-help-mismatches1
-rwxr-xr-xt/t5300-pack-object.sh34
-rwxr-xr-xt/t5310-pack-bitmaps.sh35
-rwxr-xr-xt/t5333-pseudo-merge-bitmaps.sh3
-rwxr-xr-xt/t5510-fetch.sh7
-rwxr-xr-xt/t6020-bundle-misc.sh6
-rwxr-xr-xt/t7406-submodule-update.sh4
-rwxr-xr-xt/t7700-repack.sh16
-rw-r--r--t/test-lib-functions.sh26
16 files changed, 255 insertions, 8 deletions
diff --git a/t/README b/t/README
index e84824dc00..53e5b4a710 100644
--- a/t/README
+++ b/t/README
@@ -471,6 +471,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_NAME_HASH_VERSION=<int>, when set, causes 'git pack-objects' to
+assume '--name-hash-version=<n>'.
+
+
Naming Tests
------------
diff --git a/t/helper/meson.build b/t/helper/meson.build
index f502d1aaa3..1d6154ce97 100644
--- a/t/helper/meson.build
+++ b/t/helper/meson.build
@@ -34,6 +34,7 @@ test_tool_sources = [
'test-match-trees.c',
'test-mergesort.c',
'test-mktemp.c',
+ 'test-name-hash.c',
'test-online-cpus.c',
'test-pack-mtimes.c',
'test-parse-options.c',
diff --git a/t/helper/test-name-hash.c b/t/helper/test-name-hash.c
new file mode 100644
index 0000000000..af1d52de10
--- /dev/null
+++ b/t/helper/test-name-hash.c
@@ -0,0 +1,23 @@
+/*
+ * test-name-hash.c: Read a list of paths over stdin and report on their
+ * name-hash and full name-hash.
+ */
+
+#include "test-tool.h"
+#include "git-compat-util.h"
+#include "pack-objects.h"
+#include "strbuf.h"
+
+int cmd__name_hash(int argc UNUSED, const char **argv UNUSED)
+{
+ struct strbuf line = STRBUF_INIT;
+
+ while (!strbuf_getline(&line, stdin)) {
+ printf("%10u ", pack_name_hash(line.buf));
+ printf("%10u ", pack_name_hash_v2((unsigned const char *)line.buf));
+ printf("%s\n", line.buf);
+ }
+
+ strbuf_release(&line);
+ return 0;
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index e8bc94862e..50dc4dac4e 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -44,6 +44,7 @@ static struct test_cmd cmds[] = {
{ "match-trees", cmd__match_trees },
{ "mergesort", cmd__mergesort },
{ "mktemp", cmd__mktemp },
+ { "name-hash", cmd__name_hash },
{ "online-cpus", cmd__online_cpus },
{ "pack-mtimes", cmd__pack_mtimes },
{ "parse-options", cmd__parse_options },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index fb4c609254..6d62a5b53d 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -37,6 +37,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv);
int cmd__match_trees(int argc, const char **argv);
int cmd__mergesort(int argc, const char **argv);
int cmd__mktemp(int argc, const char **argv);
+int cmd__name_hash(int argc, const char **argv);
int cmd__online_cpus(int argc, const char **argv);
int cmd__pack_mtimes(int argc, const char **argv);
int cmd__parse_options(int argc, const char **argv);
diff --git a/t/perf/p5313-pack-objects.sh b/t/perf/p5313-pack-objects.sh
new file mode 100755
index 0000000000..be5229a0ec
--- /dev/null
+++ b/t/perf/p5313-pack-objects.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+test_description='Tests pack performance using bitmaps'
+. ./perf-lib.sh
+
+GIT_TEST_PASSING_SANITIZE_LEAK=0
+export GIT_TEST_PASSING_SANITIZE_LEAK
+
+test_perf_large_repo
+
+test_expect_success 'create rev input' '
+ cat >in-thin <<-EOF &&
+ $(git rev-parse HEAD)
+ ^$(git rev-parse HEAD~1)
+ EOF
+
+ cat >in-big <<-EOF &&
+ $(git rev-parse HEAD)
+ ^$(git rev-parse HEAD~1000)
+ EOF
+
+ cat >in-shallow <<-EOF
+ $(git rev-parse HEAD)
+ --shallow $(git rev-parse HEAD)
+ EOF
+'
+
+for version in 1 2
+do
+ export version
+
+ test_perf "thin pack with version $version" '
+ git pack-objects --thin --stdout --revs --sparse \
+ --name-hash-version=$version <in-thin >out
+ '
+
+ test_size "thin pack size with version $version" '
+ test_file_size out
+ '
+
+ test_perf "big pack with version $version" '
+ git pack-objects --stdout --revs --sparse \
+ --name-hash-version=$version <in-big >out
+ '
+
+ test_size "big pack size with version $version" '
+ test_file_size out
+ '
+
+ test_perf "shallow fetch pack with version $version" '
+ git pack-objects --stdout --revs --sparse --shallow \
+ --name-hash-version=$version <in-shallow >out
+ '
+
+ test_size "shallow pack size with version $version" '
+ test_file_size out
+ '
+
+ test_perf "repack with version $version" '
+ git repack -adf --name-hash-version=$version
+ '
+
+ test_size "repack size with version $version" '
+ gitdir=$(git rev-parse --git-dir) &&
+ pack=$(ls $gitdir/objects/pack/pack-*.pack) &&
+ test_file_size "$pack"
+ '
+done
+
+test_done
diff --git a/t/perf/p5314-name-hash.sh b/t/perf/p5314-name-hash.sh
new file mode 100755
index 0000000000..4ef0ba7711
--- /dev/null
+++ b/t/perf/p5314-name-hash.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='Tests pack performance using bitmaps'
+. ./perf-lib.sh
+
+GIT_TEST_PASSING_SANITIZE_LEAK=0
+export GIT_TEST_PASSING_SANITIZE_LEAK
+
+test_perf_large_repo
+
+test_size 'paths at head' '
+ git ls-tree -r --name-only HEAD >path-list &&
+ wc -l <path-list &&
+ test-tool name-hash <path-list >name-hashes
+'
+
+for version in 1 2
+do
+ test_size "distinct hash value: v$version" '
+ awk "{ print \$$version; }" <name-hashes | sort | \
+ uniq -c >name-hash-count &&
+ wc -l <name-hash-count
+ '
+
+ test_size "maximum multiplicity: v$version" '
+ sort -nr <name-hash-count | head -n 1 | \
+ awk "{ print \$1; }"
+ '
+done
+
+test_done
diff --git a/t/t0450/txt-help-mismatches b/t/t0450/txt-help-mismatches
index 28003f18c9..c4a15fd0cb 100644
--- a/t/t0450/txt-help-mismatches
+++ b/t/t0450/txt-help-mismatches
@@ -45,7 +45,6 @@ rebase
remote
remote-ext
remote-fd
-repack
reset
restore
rev-parse
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index d1d6248558..5ac8d39094 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -689,4 +689,38 @@ do
'
done
+test_expect_success 'valid and invalid --name-hash-versions' '
+ sane_unset GIT_TEST_NAME_HASH_VERSION &&
+
+ # Valid values are hard to verify other than "do not fail".
+ # Performance tests will be more valuable to validate these versions.
+ # Negative values are converted to version 1.
+ for value in -1 1 2
+ do
+ git pack-objects base --all --name-hash-version=$value || return 1
+ done &&
+
+ # Invalid values have clear post-conditions.
+ for value in 0 3
+ do
+ test_must_fail git pack-objects base --all --name-hash-version=$value 2>err &&
+ test_grep "invalid --name-hash-version option" err || return 1
+ done
+'
+
+# The following test is not necessarily a permanent choice, but since we do not
+# have a "name hash version" bit in the .bitmap file format, we cannot write the
+# hash values into the .bitmap file without risking breakage later.
+#
+# TODO: Make these compatible in the future and replace this test with the
+# expected behavior when both are specified.
+test_expect_success '--name-hash-version=2 and --write-bitmap-index are incompatible' '
+ git pack-objects base --all --name-hash-version=2 --write-bitmap-index 2>err &&
+ test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err &&
+
+ # --stdout option silently removes --write-bitmap-index
+ git pack-objects --stdout --all --name-hash-version=2 --write-bitmap-index >out 2>err &&
+ ! test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err
+'
+
test_done
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index eabfcd7ff6..621bbbdd26 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -26,6 +26,36 @@ has_any () {
grep -Ff "$1" "$2"
}
+# Since name-hash values are stored in the .bitmap files, add a test
+# that checks that the name-hash calculations are stable across versions.
+# Not exhaustive, but these hashing algorithms would be hard to change
+# without causing deviations here.
+test_expect_success 'name-hash value stability' '
+ cat >names <<-\EOF &&
+ first
+ second
+ third
+ a/one-long-enough-for-collisions
+ b/two-long-enough-for-collisions
+ many/parts/to/this/path/enough/to/collide/in/v2
+ enough/parts/to/this/path/enough/to/collide/in/v2
+ EOF
+
+ test-tool name-hash <names >out &&
+
+ cat >expect <<-\EOF &&
+ 2582249472 1763573760 first
+ 2289942528 1188134912 second
+ 2300837888 1130758144 third
+ 2544516325 3963087891 a/one-long-enough-for-collisions
+ 2544516325 4013419539 b/two-long-enough-for-collisions
+ 1420111091 1709547268 many/parts/to/this/path/enough/to/collide/in/v2
+ 1420111091 1709547268 enough/parts/to/this/path/enough/to/collide/in/v2
+ EOF
+
+ test_cmp expect out
+'
+
test_bitmap_cases () {
writeLookupTable=false
for i in "$@"
@@ -419,7 +449,10 @@ test_bitmap_cases () {
cat >expect <<-\EOF &&
error: missing value for '\''pack.preferbitmaptips'\''
EOF
- git repack -adb 2>actual &&
+
+ # Disable name hash version adjustment due to stderr comparison.
+ GIT_TEST_NAME_HASH_VERSION=1 \
+ 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 1dd6284756..3905cb6e4f 100755
--- a/t/t5333-pseudo-merge-bitmaps.sh
+++ b/t/t5333-pseudo-merge-bitmaps.sh
@@ -208,7 +208,8 @@ test_expect_success 'bitmapPseudoMerge.stableThreshold creates stable groups' '
'
test_expect_success 'out of order thresholds are rejected' '
- test_must_fail git \
+ # Disable the test var to remove a stderr message.
+ test_must_fail env GIT_TEST_NAME_HASH_VERSION=1 git \
-c bitmapPseudoMerge.test.pattern="refs/*" \
-c bitmapPseudoMerge.test.threshold=1.month.ago \
-c bitmapPseudoMerge.test.stableThreshold=1.week.ago \
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 0b89aca77e..4680e0f644 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -1237,7 +1237,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 a different 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_NAME_HASH_VERSION=1 \
+ git bundle create twoside-boundary.bdl main --since="$ad" &&
test_bundle_object_count --thin twoside-boundary.bdl 3
'
diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh
index 4ce62feaa2..b3807e8f35 100755
--- a/t/t6020-bundle-misc.sh
+++ b/t/t6020-bundle-misc.sh
@@ -246,7 +246,11 @@ test_expect_success 'create bundle with --since option' '
EOF
test_cmp expect actual &&
- git bundle create since.bdl \
+ # If a different name hash function is used, then one fewer
+ # delta base is found and this counts a different number
+ # of objects after performing --fix-thin.
+ GIT_TEST_NAME_HASH_VERSION=1 \
+ 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 297c6c3b5c..c562bad042 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -1093,7 +1093,9 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s
) &&
git clone super4 super5 &&
(cd super5 &&
- git submodule update --quiet --init --depth=1 submodule3 >out 2>err &&
+ # This test var can mess with the stderr output checked in this test.
+ GIT_TEST_NAME_HASH_VERSION=1 \
+ 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 be1188e736..611755cc13 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -308,7 +308,10 @@ test_expect_success 'no bitmaps created if .keep files present' '
keep=${pack%.pack}.keep &&
test_when_finished "rm -f \"\$keep\"" &&
>"$keep" &&
- git -C bare.git repack -ad 2>stderr &&
+
+ # Disable --name-hash-version test due to stderr comparison.
+ GIT_TEST_NAME_HASH_VERSION=1 \
+ git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
@@ -319,7 +322,10 @@ 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 &&
- git -C bare.git repack -ad 2>stderr &&
+
+ # Disable --name-hash-version test due to stderr comparison.
+ GIT_TEST_NAME_HASH_VERSION=1 \
+ git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
@@ -776,6 +782,12 @@ test_expect_success 'repack -ad cleans up old .tmp-* packs' '
test_must_be_empty tmpfiles
'
+test_expect_success '--name-hash-version option passes through to pack-objects' '
+ GIT_TRACE2_EVENT="$(pwd)/hash-trace.txt" \
+ git repack -a --name-hash-version=2 &&
+ test_subcommand_flex git pack-objects --name-hash-version=2 <hash-trace.txt
+'
+
test_expect_success 'setup for update-server-info' '
git init update-server-info &&
test_commit -C update-server-info message
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 14d511f509..b93736e0d5 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1896,6 +1896,32 @@ test_subcommand () {
fi
}
+# Check that the given subcommand was run with the given set of
+# arguments in order (but with possible extra arguments).
+#
+# test_subcommand_flex [!] <command> <args>... < <trace>
+#
+# If the first parameter passed is !, this instead checks that
+# the given command was not called.
+#
+test_subcommand_flex () {
+ local negate=
+ if test "$1" = "!"
+ then
+ negate=t
+ shift
+ fi
+
+ local expr="$(printf '"%s".*' "$@")"
+
+ if test -n "$negate"
+ then
+ ! grep "\[$expr\]"
+ else
+ grep "\[$expr\]"
+ fi
+}
+
# Check that the given command was invoked as part of the
# trace2-format trace on stdin.
#