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
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.
--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
-------------
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;
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);
}
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;
}
}
* 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;
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);