From 14e94bf04e5ae3895eb61253be9c6d0a0fe56328 Mon Sep 17 00:00:00 2001 From: ZheNing Hu Date: Tue, 24 Dec 2024 18:52:46 +0800 Subject: [PATCH 1/2] gc: add `--expire-to` option This commit extends the functionality of `git gc` by adding a new option, `--expire-to=`. Previously, this feature was implemented in `git repack` (see 91badeb), allowing users to specify a directory where unreachable and expired cruft packs are stored during garbage collection. However, users had to run `git repack --cruft --expire-to=` followed by `git prune` to achieve similar results within `git gc`. By introducing `--expire-to=` directly into `git gc`, we simplify the process for users who wish to manage their repository's cleanup more efficiently. This change involves passing the `--expire-to=` parameter through to `git repack`, making it easier for users to set up a backup location for cruft packs that will be pruned. Signed-off-by: ZheNing Hu --- Documentation/git-gc.txt | 6 ++++++ builtin/gc.c | 6 +++++- t/t6500-gc.sh | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index 370e22faaeb55e..b4c0cf0297287a 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -69,6 +69,12 @@ be performed as well. the `--max-cruft-size` option of linkgit:git-repack[1] for more. +--expire-to=:: + When packing unreachable objects into a cruft pack, write a cruft + pack containing pruned objects (if any) to the directory ``. + See the `--expire-to` option of linkgit:git-repack[1] for + more. + --prune=:: Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable `gc.pruneExpire`). diff --git a/builtin/gc.c b/builtin/gc.c index d52735354c9f87..77904694c9f60d 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -136,6 +136,7 @@ struct gc_config { char *prune_worktrees_expire; char *repack_filter; char *repack_filter_to; + char *repack_expire_to; unsigned long big_pack_threshold; unsigned long max_delta_cache_size; }; @@ -441,6 +442,8 @@ static void add_repack_all_option(struct gc_config *cfg, if (cfg->max_cruft_size) strvec_pushf(&repack, "--max-cruft-size=%lu", cfg->max_cruft_size); + if (cfg->repack_expire_to) + strvec_pushf(&repack, "--expire-to=%s", cfg->repack_expire_to); } else { strvec_push(&repack, "-A"); if (cfg->prune_expire) @@ -675,7 +678,6 @@ struct repository *repo UNUSED) const char *prune_expire_sentinel = "sentinel"; const char *prune_expire_arg = prune_expire_sentinel; int ret; - struct option builtin_gc_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), { OPTION_STRING, 0, "prune", &prune_expire_arg, N_("date"), @@ -694,6 +696,8 @@ struct repository *repo UNUSED) PARSE_OPT_NOCOMPLETE), OPT_BOOL(0, "keep-largest-pack", &keep_largest_pack, N_("repack all other packs except the largest pack")), + OPT_STRING(0, "expire-to", &cfg.repack_expire_to, N_("dir"), + N_("pack prefix to store a pack containing pruned objects")), OPT_END() }; diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index ee074b99b708c3..d4b0653a9b7456 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -339,6 +339,12 @@ test_expect_success 'gc.maxCruftSize sets appropriate repack options' ' test_subcommand $cruft_max_size_opts --max-cruft-size=3145728 Date: Mon, 30 Dec 2024 19:51:05 +0800 Subject: [PATCH 2/2] fix(gc): make --prune=now compatible with --expire-to The original `git gc --prune=now` attempted to delete all unreachable objects. However, after the introduction of `--cruft` and `--expire-to=` in git gc, `--prune=now` can now compress unreachable objects into a cruft pack and store them in the specified instead of deleting them directly. This is beneficial for recovery in case of data corruption during repository GC. Therefore, update the handling logic of `--prune=now` in gc so that `-a` parameter is only passed to the repack command when neither `--cruft` nor `--expire-to` are used. Signed-off-by: ZheNing Hu --- builtin/gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin/gc.c b/builtin/gc.c index 77904694c9f60d..8656e1caff0990 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -433,7 +433,8 @@ static int keep_one_pack(struct string_list_item *item, void *data UNUSED) static void add_repack_all_option(struct gc_config *cfg, struct string_list *keep_pack) { - if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now")) + if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now") + && !(cfg->cruft_packs && cfg->repack_expire_to)) strvec_push(&repack, "-a"); else if (cfg->cruft_packs) { strvec_push(&repack, "--cruft");