gc: add `gc.repackFilterTo` config option

A previous commit implemented the `gc.repackFilter` config option to specify a filter that should be used by `git gc` when performing repacks. Another previous commit has implemented `git repack --filter-to=<dir>` to specify the location of the packfile containing filtered out objects when using a filter. Let's implement the `gc.repackFilterTo` config option to specify that location in the config when `gc.repackFilter` is used. Now when `git gc` will perform a repack with a <dir> configured through this option and not empty, the repack process will be passed a corresponding `--filter-to=<dir>` argument. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Oct 2, 2023 at 18:55 UTC 9b96046b9239589756cde8fbcbafe05ac7ec4611
3 files changed +27 -1
Documentation/config/gc.txt
+11
@@ -150,6 +150,17 @@ gc.repackFilter::
150 objects into a separate packfile. See the
151 `--filter=<filter-spec>` option of linkgit:git-repack[1].
152
153 +gc.repackFilterTo::
154 + When repacking and using a filter, see `gc.repackFilter`, the
155 + specified location will be used to create the packfile
156 + containing the filtered out objects. **WARNING:** The
157 + specified location should be accessible, using for example the
158 + Git alternates mechanism, otherwise the repo could be
159 + considered corrupt by Git as it migh not be able to access the
160 + objects in that packfile. See the `--filter-to=<dir>` option
161 + of linkgit:git-repack[1] and the `objects/info/alternates`
162 + section of linkgit:gitrepository-layout[5].
163 +
164 gc.rerereResolved::
165 Records of conflicted merge you resolved earlier are
166 kept for this many days when 'git rerere gc' is run.
builtin/gc.c
+4
@@ -62,6 +62,7 @@ static const char *gc_log_expire = "1.day.ago";
62 static const char *prune_expire = "2.weeks.ago";
63 static const char *prune_worktrees_expire = "3.months.ago";
64 static char *repack_filter;
65 +static char *repack_filter_to;
66 static unsigned long big_pack_threshold;
67 static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
68
@@ -172,6 +173,7 @@ static void gc_config(void)
173 git_config_get_ulong("pack.deltacachesize", &max_delta_cache_size);
174
175 git_config_get_string("gc.repackfilter", &repack_filter);
176 + git_config_get_string("gc.repackfilterto", &repack_filter_to);
177
178 git_config(git_default_config, NULL);
179 }
@@ -361,6 +363,8 @@ static void add_repack_all_option(struct string_list *keep_pack)
363
364 if (repack_filter && *repack_filter)
365 strvec_pushf(&repack, "--filter=%s", repack_filter);
366 + if (repack_filter_to && *repack_filter_to)
367 + strvec_pushf(&repack, "--filter-to=%s", repack_filter_to);
368 }
369
370 static void add_repack_incremental_option(void)
t/t6500-gc.sh
+12 -1
@@ -203,7 +203,6 @@ test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "e
203 '
204
205 test_expect_success 'gc.repackFilter launches repack with a filter' '
206 - test_when_finished "rm -rf bare.git" &&
206 git clone --no-local --bare . bare.git &&
207
208 git -C bare.git -c gc.cruftPacks=false gc &&
@@ -215,6 +214,18 @@ test_expect_success 'gc.repackFilter launches repack with a filter' '
214 grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out
215 '
216
217 +test_expect_success 'gc.repackFilterTo store filtered out objects' '
218 + test_when_finished "rm -rf bare.git filtered.git" &&
219 +
220 + git init --bare filtered.git &&
221 + git -C bare.git -c gc.repackFilter=blob:none \
222 + -c gc.repackFilterTo=../filtered.git/objects/pack/pack \
223 + -c repack.writeBitmaps=false -c gc.cruftPacks=false gc &&
224 +
225 + test_stdout_line_count = 1 ls bare.git/objects/pack/*.pack &&
226 + test_stdout_line_count = 1 ls filtered.git/objects/pack/*.pack
227 +'
228 +
229 prepare_cruft_history () {
230 test_commit base &&
231