summaryrefslogtreecommitdiff
path: root/builtin/gc.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2018-04-15 17:36:15 +0200
committerJunio C Hamano <gitster@pobox.com>2018-04-16 13:52:29 +0900
commit55dfe13df9bb38809bc45b8d6d5c7f5bf0470c11 (patch)
tree17ae0d2ce6d7525a2042e691166c51124736d048 /builtin/gc.c
parentae4e89e549b76b561a1c384dd7314c9b671c22bc (diff)
downloadgit-55dfe13df9bb38809bc45b8d6d5c7f5bf0470c11.tar.gz
gc: add gc.bigPackThreshold config
The --keep-largest-pack option is not very convenient to use because you need to tell gc to do this explicitly (and probably on just a few large repos). Add a config key that enables this mode when packs larger than a limit are found. Note that there's a slight behavior difference compared to --keep-largest-pack: all packs larger than the threshold are kept, not just the largest one. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/gc.c')
-rw-r--r--builtin/gc.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index f251662a8f..81ecdc5ffa 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -41,6 +41,7 @@ static timestamp_t gc_log_expire_time;
static const char *gc_log_expire = "1.day.ago";
static const char *prune_expire = "2.weeks.ago";
static const char *prune_worktrees_expire = "3.months.ago";
+static unsigned long big_pack_threshold;
static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
static struct argv_array reflog = ARGV_ARRAY_INIT;
@@ -128,6 +129,8 @@ static void gc_config(void)
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
git_config_get_expiry("gc.logexpiry", &gc_log_expire);
+ git_config_get_ulong("gc.bigpackthreshold", &big_pack_threshold);
+
git_config(git_default_config, NULL);
}
@@ -166,14 +169,17 @@ static int too_many_loose_objects(void)
return needed;
}
-static void find_base_packs(struct string_list *packs)
+static void find_base_packs(struct string_list *packs, unsigned long limit)
{
struct packed_git *p, *base = NULL;
for (p = get_packed_git(the_repository); p; p = p->next) {
if (!p->pack_local)
continue;
- if (!base || base->pack_size < p->pack_size) {
+ if (limit) {
+ if (p->pack_size >= limit)
+ string_list_append(packs, p->pack_name);
+ } else if (!base || base->pack_size < p->pack_size) {
base = p;
}
}
@@ -244,9 +250,15 @@ static int need_to_gc(void)
* we run "repack -A -d -l". Otherwise we tell the caller
* there is no need.
*/
- if (too_many_packs())
- add_repack_all_option(NULL);
- else if (too_many_loose_objects())
+ if (too_many_packs()) {
+ struct string_list keep_pack = STRING_LIST_INIT_NODUP;
+
+ if (big_pack_threshold)
+ find_base_packs(&keep_pack, big_pack_threshold);
+
+ add_repack_all_option(&keep_pack);
+ string_list_clear(&keep_pack, 0);
+ } else if (too_many_loose_objects())
add_repack_incremental_option();
else
return 0;
@@ -464,7 +476,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (keep_base_pack != -1) {
if (keep_base_pack)
- find_base_packs(&keep_pack);
+ find_base_packs(&keep_pack, 0);
+ } else if (big_pack_threshold) {
+ find_base_packs(&keep_pack, big_pack_threshold);
}
add_repack_all_option(&keep_pack);