repack: add --name-hash-version option

The new '--name-hash-version' option for 'git repack' is a simple pass-through to the underlying 'git pack-objects' subcommand. However, this subcommand may have other options and a temporary filename as part of the subcommand execution that may not be predictable or could change over time. The existing test_subcommand method requires an exact list of arguments for the subcommand. This is too rigid for our needs here, so create a new method, test_subcommand_flex. Use it to check that the --name-hash-version option is passing through. Since we are modifying the 'git repack' command, let's bring its usage in line with the Documentation's synopsis. This removes it from the allow list in t0450 so it will remain in sync in the future. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Jan 27, 2025 at 19:02 UTC 928ef41dd879a1e12373842e865477e9e1167621
5 files changed +48 -3
Documentation/git-repack.txt
+8 -1
@@ -9,7 +9,9 @@ git-repack - Pack unpacked objects in a repository
9 SYNOPSIS
10 --------
11 [verse]
12 -'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m] [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>] [--write-midx]
12 +'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]
13 + [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]
14 + [--write-midx] [--name-hash-version=<n>]
15
16 DESCRIPTION
17 -----------
@@ -249,6 +251,11 @@ linkgit:git-multi-pack-index[1]).
251 Write a multi-pack index (see linkgit:git-multi-pack-index[1])
252 containing the non-redundant packs.
253
254 +--name-hash-version=<n>::
255 + Provide this argument to the underlying `git pack-objects` process.
256 + See linkgit:git-pack-objects[1] for full details.
257 +
258 +
259 CONFIGURATION
260 -------------
261
builtin/repack.c
+8 -1
@@ -39,7 +39,9 @@ static int run_update_server_info = 1;
39 static char *packdir, *packtmp_name, *packtmp;
40
41 static const char *const git_repack_usage[] = {
42 - N_("git repack [<options>]"),
42 + N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n"
43 + "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n"
44 + "[--write-midx] [--name-hash-version=<n>]"),
45 NULL
46 };
47
@@ -58,6 +60,7 @@ struct pack_objects_args {
60 int no_reuse_object;
61 int quiet;
62 int local;
63 + int name_hash_version;
64 struct list_objects_filter_options filter_options;
65 };
66
@@ -306,6 +309,8 @@ static void prepare_pack_objects(struct child_process *cmd,
309 strvec_pushf(&cmd->args, "--no-reuse-delta");
310 if (args->no_reuse_object)
311 strvec_pushf(&cmd->args, "--no-reuse-object");
312 + if (args->name_hash_version)
313 + strvec_pushf(&cmd->args, "--name-hash-version=%d", args->name_hash_version);
314 if (args->local)
315 strvec_push(&cmd->args, "--local");
316 if (args->quiet)
@@ -1203,6 +1208,8 @@ int cmd_repack(int argc,
1208 N_("pass --no-reuse-delta to git-pack-objects")),
1209 OPT_BOOL('F', NULL, &po_args.no_reuse_object,
1210 N_("pass --no-reuse-object to git-pack-objects")),
1211 + OPT_INTEGER(0, "name-hash-version", &po_args.name_hash_version,
1212 + N_("specify the name hash version to use for grouping similar objects by path")),
1213 OPT_NEGBIT('n', NULL, &run_update_server_info,
1214 N_("do not run git-update-server-info"), 1),
1215 OPT__QUIET(&po_args.quiet, N_("be quiet")),
t/t0450/txt-help-mismatches
-1
@@ -45,7 +45,6 @@ rebase
45 remote
46 remote-ext
47 remote-fd
48 -repack
48 reset
49 restore
50 rev-parse
t/t7700-repack.sh
+6
@@ -777,6 +777,12 @@ test_expect_success 'repack -ad cleans up old .tmp-* packs' '
777 test_must_be_empty tmpfiles
778 '
779
780 +test_expect_success '--name-hash-version option passes through to pack-objects' '
781 + GIT_TRACE2_EVENT="$(pwd)/hash-trace.txt" \
782 + git repack -a --name-hash-version=2 &&
783 + test_subcommand_flex git pack-objects --name-hash-version=2 <hash-trace.txt
784 +'
785 +
786 test_expect_success 'setup for update-server-info' '
787 git init update-server-info &&
788 test_commit -C update-server-info message
t/test-lib-functions.sh
+26
@@ -1886,6 +1886,32 @@ test_subcommand () {
1886 fi
1887 }
1888
1889 +# Check that the given subcommand was run with the given set of
1890 +# arguments in order (but with possible extra arguments).
1891 +#
1892 +# test_subcommand_flex [!] <command> <args>... < <trace>
1893 +#
1894 +# If the first parameter passed is !, this instead checks that
1895 +# the given command was not called.
1896 +#
1897 +test_subcommand_flex () {
1898 + local negate=
1899 + if test "$1" = "!"
1900 + then
1901 + negate=t
1902 + shift
1903 + fi
1904 +
1905 + local expr="$(printf '"%s".*' "$@")"
1906 +
1907 + if test -n "$negate"
1908 + then
1909 + ! grep "\[$expr\]"
1910 + else
1911 + grep "\[$expr\]"
1912 + fi
1913 +}
1914 +
1915 # Check that the given command was invoked as part of the
1916 # trace2-format trace on stdin.
1917 #