diff --git a/Documentation/config.txt b/Documentation/config.txt index 178e0e1e209e066ad220d6ba95be0728c2db5e99..28fe6942cf867549e8d19120e339a14cb8347b1b 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -118,6 +118,15 @@ core.legacyheaders:: database directly (where the "http://" and "rsync://" protocols count as direct access). +core.packedGitLimit:: + Maximum number of bytes to map simultaneously into memory + from pack files. If Git needs to access more than this many + bytes at once to complete an operation it will unmap existing + regions to reclaim virtual address space within the process. + Default is 256 MiB, which should be reasonable for all + users/operating systems, except on largest Git projects. + You probably do not need to adjust this value. + alias.*:: Command aliases for the gitlink:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation diff --git a/cache.h b/cache.h index e0a26e9d04857484f07bd49f740e653085129447..816239bea0fbf53852efcb3575995cd5aef7e445 100644 --- a/cache.h +++ b/cache.h @@ -196,6 +196,7 @@ extern int warn_ambiguous_refs; extern int shared_repository; extern const char *apply_default_whitespace; extern int zlib_compression_level; +extern size_t packed_git_limit; #define GIT_REPO_VERSION 0 extern int repository_format_version; diff --git a/config.c b/config.c index fcccf7e2a4f3b7487af10d4f7b505c7ef492b9e8..0c21286cb25d6a0d1f4dca4e82e59dcb7165e0d5 100644 --- a/config.c +++ b/config.c @@ -298,6 +298,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.packedgitlimit")) { + packed_git_limit = git_config_int(var, value); + return 0; + } + if (!strcmp(var, "user.name")) { strlcpy(git_default_name, value, sizeof(git_default_name)); return 0; diff --git a/environment.c b/environment.c index a1502c4e87c0067c8cc276006317005a0da21a49..a3ddae68a7bada16edfa88d8f9244181af8e7cea 100644 --- a/environment.c +++ b/environment.c @@ -23,6 +23,7 @@ char *git_log_output_encoding; int shared_repository = PERM_UMASK; const char *apply_default_whitespace; int zlib_compression_level = Z_DEFAULT_COMPRESSION; +size_t packed_git_limit = 256 * 1024 * 1024; int pager_in_use; int pager_use_color = 1; diff --git a/sha1_file.c b/sha1_file.c index 4824a5d4d8bb5104461ea8245d9a22b5408cb537..4183f595edfe6086f5097a430cb48202db00c5c1 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -397,7 +397,6 @@ static char *find_sha1_file(const unsigned char *sha1, struct stat *st) return NULL; } -#define PACK_MAX_SZ (1<<26) static int pack_used_ctr; static unsigned long pack_mapped; struct packed_git *packed_git; @@ -490,7 +489,7 @@ int use_packed_git(struct packed_git *p) struct pack_header *hdr; pack_mapped += p->pack_size; - while (PACK_MAX_SZ < pack_mapped && unuse_one_packed_git()) + while (packed_git_limit < pack_mapped && unuse_one_packed_git()) ; /* nothing */ fd = open(p->pack_name, O_RDONLY); if (fd < 0)