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>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2018-04-15 17:36:15 +02:00 коммит произвёл Junio C Hamano
Родитель ae4e89e549
Коммит 55dfe13df9
3 изменённых файлов: 31 добавлений и 8 удалений

Просмотреть файл

@ -1558,6 +1558,13 @@ gc.autoDetach::
Make `git gc --auto` return immediately and run in background
if the system supports it. Default is true.
gc.bigPackThreshold::
If non-zero, all packs larger than this limit are kept when
`git gc` is run. This is very similar to `--keep-base-pack`
except that all packs that meet the threshold are kept, not
just the base pack. Defaults to zero. Common unit suffixes of
'k', 'm', or 'g' are supported.
gc.logExpiry::
If the file gc.log exists, then `git gc --auto` won't run
unless that file is more than 'gc.logExpiry' old. Default is

Просмотреть файл

@ -56,7 +56,8 @@ single pack using `git repack -d -l`. Setting the value of `gc.auto`
to 0 disables automatic packing of loose objects.
+
If the number of packs exceeds the value of `gc.autoPackLimit`,
then existing packs (except those marked with a `.keep` file)
then existing packs (except those marked with a `.keep` file
or over `gc.bigPackThreshold` limit)
are consolidated into a single pack by using the `-A` option of
'git repack'. Setting `gc.autoPackLimit` to 0 disables
automatic consolidation of packs.
@ -86,7 +87,8 @@ be performed as well.
--keep-largest-pack::
All packs except the largest pack and those marked with a
`.keep` files are consolidated into a single pack.
`.keep` files are consolidated into a single pack. When this
option is used, `gc.bigPackThreshold` is ignored.
Configuration
-------------

Просмотреть файл

@ -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);