summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 95143f9)
raw | patch | inline | side by side (parent: 95143f9)
author | Junio C Hamano <gitster@pobox.com> | |
Mon, 17 Sep 2007 07:55:13 +0000 (00:55 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 18 Sep 2007 06:12:16 +0000 (23:12 -0700) |
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>
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>
Documentation/config.txt | patch | blob | history | |
Documentation/git-gc.txt | patch | blob | history | |
builtin-gc.c | patch | blob | history |
index 6b6553d9da8f92813ed4a79e310d14d0cc8b690f..b0390f82b85b17287b9e90c5ea57839517c040cf 100644 (file)
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
light-weight garbage collection from time to time. Setting
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::
`git gc` does not run `git pack-refs` in a bare repository by
default so that older dumb-transport clients can still fetch
index 40c1ce4a21302b315c8f88802645ce0161a0c47c..b9d5660eacee03bde2360b97b80f3378972fe678 100644 (file)
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
With this option, `git gc` checks if there are too many
loose objects in the repository and runs
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
Porcelain commands use this after they perform operation
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
-------------
diff --git a/builtin-gc.c b/builtin-gc.c
index 34ce35befb53397cab0edd0960b6a5df872f32e9..23ad2b6a21a81f469e813173ba04d626949e972f 100644 (file)
--- a/builtin-gc.c
+++ b/builtin-gc.c
static int pack_refs = 1;
static int aggressive_window = -1;
static int gc_auto_threshold = 6700;
+static int gc_auto_pack_limit = 20;
#define MAX_ADD 10
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
gc_auto_threshold = git_config_int(var, value);
return 0;
}
+ if (!strcmp(var, "gc.autopacklimit")) {
+ gc_auto_pack_limit = git_config_int(var, value);
+ return 0;
+ }
return git_default_config(var, value);
}
int num_loose = 0;
int needed = 0;
+ if (gc_auto_threshold <= 0)
+ return 0;
+
if (sizeof(path) <= snprintf(path, sizeof(path), "%s/17", objdir)) {
warning("insanely long object directory %.*s", 50, objdir);
return 0;
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)
{
int ac = 0;
/*
- * Setting gc.auto to 0 or negative can disable the
- * automatic gc
+ * Setting gc.auto and gc.autopacklimit to 0 or negative can
+ * disable the automatic gc.
*/
- if (gc_auto_threshold <= 0)
- return 0;
-
- if (!too_many_loose_objects())
+ if (gc_auto_threshold <= 0 && gc_auto_pack_limit <= 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";
+ if (too_many_packs())
+ argv_repack[ac++] = "-A";
+ else if (!too_many_loose_objects())
+ return 0;
argv_repack[ac++] = "-d";
argv_repack[ac++] = "-l";
argv_repack[ac++] = NULL;