gc: add gc.repackFilter config option

A previous commit has implemented `git repack --filter=<filter-spec>` to
allow users to filter out some objects from the main pack and move them
into a new different pack.

Users might want to perform such a cleanup regularly at the same time as
they perform other repacks and cleanups, so as part of `git gc`.

Let's allow them to configure a <filter-spec> for that purpose using a
new gc.repackFilter config option.

Now when `git gc` will perform a repack with a <filter-spec> configured
through this option and not empty, the repack process will be passed a
corresponding `--filter=<filter-spec>` argument.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Christian Couder
2023-10-02 18:55:02 +02:00
committed by Junio C Hamano
parent 48a9b67b43
commit 1cd43a9ed9
3 changed files with 24 additions and 0 deletions

View File

@ -145,6 +145,11 @@ Multiple hooks are supported, but all must exit successfully, else the
operation (either generating a cruft pack or unpacking unreachable operation (either generating a cruft pack or unpacking unreachable
objects) will be halted. objects) will be halted.
gc.repackFilter::
When repacking, use the specified filter to move certain
objects into a separate packfile. See the
`--filter=<filter-spec>` option of linkgit:git-repack[1].
gc.rerereResolved:: gc.rerereResolved::
Records of conflicted merge you resolved earlier are Records of conflicted merge you resolved earlier are
kept for this many days when 'git rerere gc' is run. kept for this many days when 'git rerere gc' is run.

View File

@ -61,6 +61,7 @@ static timestamp_t gc_log_expire_time;
static const char *gc_log_expire = "1.day.ago"; static const char *gc_log_expire = "1.day.ago";
static const char *prune_expire = "2.weeks.ago"; static const char *prune_expire = "2.weeks.ago";
static const char *prune_worktrees_expire = "3.months.ago"; static const char *prune_worktrees_expire = "3.months.ago";
static char *repack_filter;
static unsigned long big_pack_threshold; static unsigned long big_pack_threshold;
static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE; static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
@ -170,6 +171,8 @@ static void gc_config(void)
git_config_get_ulong("gc.bigpackthreshold", &big_pack_threshold); git_config_get_ulong("gc.bigpackthreshold", &big_pack_threshold);
git_config_get_ulong("pack.deltacachesize", &max_delta_cache_size); git_config_get_ulong("pack.deltacachesize", &max_delta_cache_size);
git_config_get_string("gc.repackfilter", &repack_filter);
git_config(git_default_config, NULL); git_config(git_default_config, NULL);
} }
@ -355,6 +358,9 @@ static void add_repack_all_option(struct string_list *keep_pack)
if (keep_pack) if (keep_pack)
for_each_string_list(keep_pack, keep_one_pack, NULL); for_each_string_list(keep_pack, keep_one_pack, NULL);
if (repack_filter && *repack_filter)
strvec_pushf(&repack, "--filter=%s", repack_filter);
} }
static void add_repack_incremental_option(void) static void add_repack_incremental_option(void)

View File

@ -202,6 +202,19 @@ test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "e
grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out
' '
test_expect_success 'gc.repackFilter launches repack with a filter' '
test_when_finished "rm -rf bare.git" &&
git clone --no-local --bare . bare.git &&
git -C bare.git -c gc.cruftPacks=false gc &&
test_stdout_line_count = 1 ls bare.git/objects/pack/*.pack &&
GIT_TRACE=$(pwd)/trace.out git -C bare.git -c gc.repackFilter=blob:none \
-c repack.writeBitmaps=false -c gc.cruftPacks=false gc &&
test_stdout_line_count = 2 ls bare.git/objects/pack/*.pack &&
grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out
'
prepare_cruft_history () { prepare_cruft_history () {
test_commit base && test_commit base &&