git-gc --auto: run "repack -A -d -l" as necessary.
This teaches "git-gc --auto" to consolidate many packs into one without losing unreachable objects in them by using "repack -A" when there are too many packfiles that are not marked with *.keep in the repository. gc.autopacklimit configuration can be used to set the maximum number of packs a repository is allowed to have before this mechanism kicks in. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
95143f9e68
commit
17815501a8
@ -446,6 +446,12 @@ gc.auto::
|
|||||||
light-weight garbage collection from time to time. Setting
|
light-weight garbage collection from time to time. Setting
|
||||||
this to 0 disables it.
|
this to 0 disables it.
|
||||||
|
|
||||||
|
gc.autopacklimit::
|
||||||
|
When there are more than this many packs that are not
|
||||||
|
marked with `*.keep` file in the repository, `git gc
|
||||||
|
--auto` consolidates them into one larger pack. Setting
|
||||||
|
this to 0 disables this.
|
||||||
|
|
||||||
gc.packrefs::
|
gc.packrefs::
|
||||||
`git gc` does not run `git pack-refs` in a bare repository by
|
`git gc` does not run `git pack-refs` in a bare repository by
|
||||||
default so that older dumb-transport clients can still fetch
|
default so that older dumb-transport clients can still fetch
|
||||||
|
@ -47,10 +47,15 @@ OPTIONS
|
|||||||
With this option, `git gc` checks if there are too many
|
With this option, `git gc` checks if there are too many
|
||||||
loose objects in the repository and runs
|
loose objects in the repository and runs
|
||||||
gitlink:git-repack[1] with `-d -l` option to pack them.
|
gitlink:git-repack[1] with `-d -l` option to pack them.
|
||||||
The threshold is set with `gc.auto` configuration
|
The threshold for loose objects is set with `gc.auto` configuration
|
||||||
variable, and can be disabled by setting it to 0. Some
|
variable, and can be disabled by setting it to 0. Some
|
||||||
Porcelain commands use this after they perform operation
|
Porcelain commands use this after they perform operation
|
||||||
that could create many loose objects automatically.
|
that could create many loose objects automatically.
|
||||||
|
Additionally, when there are too many packs are present,
|
||||||
|
they are consolidated into one larger pack by running
|
||||||
|
the `git-repack` command with `-A` option. The
|
||||||
|
threshold for number of packs is set with
|
||||||
|
`gc.autopacklimit` configuration variable.
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
60
builtin-gc.c
60
builtin-gc.c
@ -21,6 +21,7 @@ static const char builtin_gc_usage[] = "git-gc [--prune] [--aggressive]";
|
|||||||
static int pack_refs = 1;
|
static int pack_refs = 1;
|
||||||
static int aggressive_window = -1;
|
static int aggressive_window = -1;
|
||||||
static int gc_auto_threshold = 6700;
|
static int gc_auto_threshold = 6700;
|
||||||
|
static int gc_auto_pack_limit = 20;
|
||||||
|
|
||||||
#define MAX_ADD 10
|
#define MAX_ADD 10
|
||||||
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
|
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
|
||||||
@ -46,6 +47,10 @@ static int gc_config(const char *var, const char *value)
|
|||||||
gc_auto_threshold = git_config_int(var, value);
|
gc_auto_threshold = git_config_int(var, value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(var, "gc.autopacklimit")) {
|
||||||
|
gc_auto_pack_limit = git_config_int(var, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return git_default_config(var, value);
|
return git_default_config(var, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +83,9 @@ static int too_many_loose_objects(void)
|
|||||||
int num_loose = 0;
|
int num_loose = 0;
|
||||||
int needed = 0;
|
int needed = 0;
|
||||||
|
|
||||||
|
if (gc_auto_threshold <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (sizeof(path) <= snprintf(path, sizeof(path), "%s/17", objdir)) {
|
if (sizeof(path) <= snprintf(path, sizeof(path), "%s/17", objdir)) {
|
||||||
warning("insanely long object directory %.*s", 50, objdir);
|
warning("insanely long object directory %.*s", 50, objdir);
|
||||||
return 0;
|
return 0;
|
||||||
@ -100,21 +108,61 @@ static int too_many_loose_objects(void)
|
|||||||
return needed;
|
return needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int too_many_packs(void)
|
||||||
|
{
|
||||||
|
struct packed_git *p;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
if (gc_auto_pack_limit <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prepare_packed_git();
|
||||||
|
for (cnt = 0, p = packed_git; p; p = p->next) {
|
||||||
|
char path[PATH_MAX];
|
||||||
|
size_t len;
|
||||||
|
int keep;
|
||||||
|
|
||||||
|
if (!p->pack_local)
|
||||||
|
continue;
|
||||||
|
len = strlen(p->pack_name);
|
||||||
|
if (PATH_MAX <= len + 1)
|
||||||
|
continue; /* oops, give up */
|
||||||
|
memcpy(path, p->pack_name, len-5);
|
||||||
|
memcpy(path + len - 5, ".keep", 6);
|
||||||
|
keep = access(p->pack_name, F_OK) && (errno == ENOENT);
|
||||||
|
if (keep)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Perhaps check the size of the pack and count only
|
||||||
|
* very small ones here?
|
||||||
|
*/
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return gc_auto_pack_limit <= cnt;
|
||||||
|
}
|
||||||
|
|
||||||
static int need_to_gc(void)
|
static int need_to_gc(void)
|
||||||
{
|
{
|
||||||
int ac = 0;
|
int ac = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setting gc.auto to 0 or negative can disable the
|
* Setting gc.auto and gc.autopacklimit to 0 or negative can
|
||||||
* automatic gc
|
* disable the automatic gc.
|
||||||
*/
|
*/
|
||||||
if (gc_auto_threshold <= 0)
|
if (gc_auto_threshold <= 0 && gc_auto_pack_limit <= 0)
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!too_many_loose_objects())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are too many loose objects, but not too many
|
||||||
|
* packs, we run "repack -d -l". If there are too many packs,
|
||||||
|
* we run "repack -A -d -l". Otherwise we tell the caller
|
||||||
|
* there is no need.
|
||||||
|
*/
|
||||||
argv_repack[ac++] = "repack";
|
argv_repack[ac++] = "repack";
|
||||||
|
if (too_many_packs())
|
||||||
|
argv_repack[ac++] = "-A";
|
||||||
|
else if (!too_many_loose_objects())
|
||||||
|
return 0;
|
||||||
argv_repack[ac++] = "-d";
|
argv_repack[ac++] = "-d";
|
||||||
argv_repack[ac++] = "-l";
|
argv_repack[ac++] = "-l";
|
||||||
argv_repack[ac++] = NULL;
|
argv_repack[ac++] = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user