Merge branch 'dh/pack'
authorJunio C Hamano <junkio@cox.net>
Sun, 20 May 2007 09:19:19 +0000 (02:19 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 20 May 2007 09:19:19 +0000 (02:19 -0700)
* dh/pack:
Custom compression levels for objects and packs

Documentation/config.txt
Documentation/git-pack-objects.txt
builtin-pack-objects.c
cache.h
config.c
csum-file.c
csum-file.h
environment.c
index b8d48d1013c46fd46d0da13f80552971a5f58644..ee1c35e8eb952967980884d521d12a76622f38f4 100644 (file)
@@ -204,10 +204,16 @@ core.warnAmbiguousRefs::
        and might match multiple refs in the .git/refs/ tree. True by default.
 
 core.compression::
+       An integer -1..9, indicating a default compression level.
+       -1 is the zlib default. 0 means no compression,
+       and 1..9 are various speed/size tradeoffs, 9 being slowest.
+
+core.loosecompression::
        An integer -1..9, indicating the compression level for objects that
-       are not in a pack file. -1 is the zlib and git default. 0 means no
+       are not in a pack file. -1 is the zlib default. 0 means no
        compression, and 1..9 are various speed/size tradeoffs, 9 being
-       slowest.
+       slowest.  If not set,  defaults to core.compression.  If that is
+       not set,  defaults to 0 (best speed).
 
 core.packedGitWindowSize::
        Number of bytes of a pack file to map into memory in a
@@ -542,6 +548,13 @@ pack.depth::
        The maximum delta depth used by gitlink:git-pack-objects[1] when no
        maximum depth is given on the command line. Defaults to 50.
 
+pack.compression::
+       An integer -1..9, indicating the compression level for objects
+       in a pack file. -1 is the zlib default. 0 means no
+       compression, and 1..9 are various speed/size tradeoffs, 9 being
+       slowest.  If not set,  defaults to core.compression.  If that is
+       not set,  defaults to -1.
+
 pull.octopus::
        The default merge strategy to use when pulling multiple branches
        at once.
index ce892147ddc373e2ffcadc5911a4947dc409e36b..2531238df45a39ad6a60ae8d489cdac871ad45b3 100644 (file)
@@ -130,10 +130,22 @@ base-name::
 --no-reuse-object::
        This flag tells the command not to reuse existing object data at all,
        including non deltified object, forcing recompression of everything.
-       This implies --no-reuse-delta. Useful only in the obscur case where
+       This implies --no-reuse-delta. Useful only in the obscure case where
        wholesale enforcement of a different compression level on the
        packed data is desired.
 
+--compression=[N]::
+       Specifies compression level for newly-compressed data in the
+       generated pack.  If not specified,  pack compression level is
+       determined first by pack.compression,  then by core.compression,
+       and defaults to -1,  the zlib default,  if neither is set.
+       Data copied from loose objects will be recompressed
+       if core.legacyheaders was true when they were created or if
+       the loose compression level (see core.loosecompression and
+       core.compression) is now a different value than the pack
+       compression level.  Add --no-reuse-object if you want to force
+       a uniform compression level on all data no matter the source.
+
 --delta-base-offset::
        A packed archive can express base object of a delta as
        either 20-byte object name or as an offset in the
index 5fa98132fe665bf511be77b926d8bc976ed64613..d165f10288558d55fee5e8a7ae88ac9fccfbc3d7 100644 (file)
@@ -68,6 +68,8 @@ static int depth = 50;
 static int pack_to_stdout;
 static int num_preferred_base;
 static struct progress progress_state;
+static int pack_compression_level = Z_DEFAULT_COMPRESSION;
+static int pack_compression_seen;
 
 /*
  * The object names in objects array are hashed with this hashtable,
@@ -418,7 +420,7 @@ static unsigned long write_object(struct sha1file *f,
                        sha1write(f, entry->delta->sha1, 20);
                        hdrlen += 20;
                }
-               datalen = sha1write_compressed(f, buf, size);
+               datalen = sha1write_compressed(f, buf, size, pack_compression_level);
                free(buf);
        }
        else {
@@ -1427,6 +1429,16 @@ static int git_pack_config(const char *k, const char *v)
                depth = git_config_int(k, v);
                return 0;
        }
+       if (!strcmp(k, "pack.compression")) {
+               int level = git_config_int(k, v);
+               if (level == -1)
+                       level = Z_DEFAULT_COMPRESSION;
+               else if (level < 0 || level > Z_BEST_COMPRESSION)
+                       die("bad pack compression level %d", level);
+               pack_compression_level = level;
+               pack_compression_seen = 1;
+               return 0;
+       }
        return git_default_config(k, v);
 }
 
@@ -1538,6 +1550,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        rp_ac = 2;
 
        git_config(git_pack_config);
+       if (!pack_compression_seen && core_compression_seen)
+               pack_compression_level = core_compression_level;
 
        progress = isatty(2);
        for (i = 1; i < argc; i++) {
@@ -1558,6 +1572,18 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                        incremental = 1;
                        continue;
                }
+               if (!prefixcmp(arg, "--compression=")) {
+                       char *end;
+                       int level = strtoul(arg+14, &end, 0);
+                       if (!arg[14] || *end)
+                               usage(pack_usage);
+                       if (level == -1)
+                               level = Z_DEFAULT_COMPRESSION;
+                       else if (level < 0 || level > Z_BEST_COMPRESSION)
+                               die("bad pack compression level %d", level);
+                       pack_compression_level = level;
+                       continue;
+               }
                if (!prefixcmp(arg, "--window=")) {
                        char *end;
                        window = strtoul(arg+9, &end, 0);
diff --git a/cache.h b/cache.h
index f98ccd0e20e6a4d0970db125814135df10e26e73..65b4685c1fedf4fd7da1b5f4ab3c4ba9645331e3 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -282,6 +282,8 @@ extern int warn_ambiguous_refs;
 extern int shared_repository;
 extern const char *apply_default_whitespace;
 extern int zlib_compression_level;
+extern int core_compression_level;
+extern int core_compression_seen;
 extern size_t packed_git_window_size;
 extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
index 521ebef3819bff1705d652684780434d6ab3fca7..0614c2b29fa93b66065ec6bc20712d38193aec89 100644 (file)
--- a/config.c
+++ b/config.c
@@ -12,6 +12,8 @@
 static FILE *config_file;
 static const char *config_file_name;
 static int config_linenr;
+static int zlib_compression_seen;
+
 static int get_next_char(void)
 {
        int c;
@@ -299,13 +301,27 @@ int git_default_config(const char *var, const char *value)
                return 0;
        }
 
-       if (!strcmp(var, "core.compression")) {
+       if (!strcmp(var, "core.loosecompression")) {
                int level = git_config_int(var, value);
                if (level == -1)
                        level = Z_DEFAULT_COMPRESSION;
                else if (level < 0 || level > Z_BEST_COMPRESSION)
                        die("bad zlib compression level %d", level);
                zlib_compression_level = level;
+               zlib_compression_seen = 1;
+               return 0;
+       }
+
+       if (!strcmp(var, "core.compression")) {
+               int level = git_config_int(var, value);
+               if (level == -1)
+                       level = Z_DEFAULT_COMPRESSION;
+               else if (level < 0 || level > Z_BEST_COMPRESSION)
+                       die("bad zlib compression level %d", level);
+               core_compression_level = level;
+               core_compression_seen = 1;
+               if (!zlib_compression_seen)
+                       zlib_compression_level = level;
                return 0;
        }
 
index 7c806ada48d0fd58c091f9415fc8bb2f61bdd2e6..7088f6e93f02985f5fa5c687eb59f90ae4c13f7c 100644 (file)
@@ -119,14 +119,14 @@ struct sha1file *sha1fd(int fd, const char *name)
        return f;
 }
 
-int sha1write_compressed(struct sha1file *f, void *in, unsigned int size)
+int sha1write_compressed(struct sha1file *f, void *in, unsigned int size, int level)
 {
        z_stream stream;
        unsigned long maxsize;
        void *out;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
+       deflateInit(&stream, level);
        maxsize = deflateBound(&stream, size);
        out = xmalloc(maxsize);
 
index 7e1339189dcdc6e271fad5df7ad427954642ae9e..4e8b83e0936f255e0fff57127da56288a988a5fe 100644 (file)
@@ -16,7 +16,7 @@ extern struct sha1file *sha1fd(int fd, const char *name);
 extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern int sha1close(struct sha1file *, unsigned char *, int);
 extern int sha1write(struct sha1file *, void *, unsigned int);
-extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
+extern int sha1write_compressed(struct sha1file *, void *, unsigned int, int);
 extern void crc32_begin(struct sha1file *);
 extern uint32_t crc32_end(struct sha1file *);
 
index 54e3abae98db6606702b597bb3bf47c27d027232..9d3e5eb72fea51eb30a201151aeffe1dfbb549d3 100644 (file)
@@ -23,7 +23,9 @@ const char *git_commit_encoding;
 const char *git_log_output_encoding;
 int shared_repository = PERM_UMASK;
 const char *apply_default_whitespace;
-int zlib_compression_level = Z_DEFAULT_COMPRESSION;
+int zlib_compression_level = Z_BEST_SPEED;
+int core_compression_level;
+int core_compression_seen;
 size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
 size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
 size_t delta_base_cache_limit = 16 * 1024 * 1024;