Provide git_config with a callback-data parameter
[gitweb.git] / builtin-pack-objects.c
index f504cff7566159332c89f830a871da0ea05868fe..a8dc225a722c16d68b6d6e18b633a2aa60ff07dd 100644 (file)
@@ -454,6 +454,7 @@ static void write_pack_file(void)
        struct pack_header hdr;
        int do_progress = progress >> pack_to_stdout;
        uint32_t nr_remaining = nr_result;
+       time_t last_mtime = 0;
 
        if (do_progress)
                progress_state = start_progress("Writing objects", nr_result);
@@ -504,6 +505,7 @@ static void write_pack_file(void)
 
                if (!pack_to_stdout) {
                        mode_t mode = umask(0);
+                       struct stat st;
                        char *idx_tmp_name, tmpname[PATH_MAX];
 
                        umask(mode);
@@ -511,6 +513,7 @@ static void write_pack_file(void)
 
                        idx_tmp_name = write_idx_file(NULL, written_list,
                                                      nr_written, sha1);
+
                        snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
                                 base_name, sha1_to_hex(sha1));
                        if (adjust_perm(pack_tmp_name, mode))
@@ -519,6 +522,28 @@ static void write_pack_file(void)
                        if (rename(pack_tmp_name, tmpname))
                                die("unable to rename temporary pack file: %s",
                                    strerror(errno));
+
+                       /*
+                        * Packs are runtime accessed in their mtime
+                        * order since newer packs are more likely to contain
+                        * younger objects.  So if we are creating multiple
+                        * packs then we should modify the mtime of later ones
+                        * to preserve this property.
+                        */
+                       if (stat(tmpname, &st) < 0) {
+                               warning("failed to stat %s: %s",
+                                       tmpname, strerror(errno));
+                       } else if (!last_mtime) {
+                               last_mtime = st.st_mtime;
+                       } else {
+                               struct utimbuf utb;
+                               utb.actime = st.st_atime;
+                               utb.modtime = --last_mtime;
+                               if (utime(tmpname, &utb) < 0)
+                                       warning("failed utime() on %s: %s",
+                                               tmpname, strerror(errno));
+                       }
+
                        snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
                                 base_name, sha1_to_hex(sha1));
                        if (adjust_perm(idx_tmp_name, mode))
@@ -527,6 +552,7 @@ static void write_pack_file(void)
                        if (rename(idx_tmp_name, tmpname))
                                die("unable to rename temporary index file: %s",
                                    strerror(errno));
+
                        free(idx_tmp_name);
                        free(pack_tmp_name);
                        puts(sha1_to_hex(sha1));
@@ -1692,7 +1718,7 @@ static void prepare_pack(int window, int depth)
        free(delta_list);
 }
 
-static int git_pack_config(const char *k, const char *v)
+static int git_pack_config(const char *k, const char *v, void *cb)
 {
        if(!strcmp(k, "pack.window")) {
                window = git_config_int(k, v);
@@ -1745,7 +1771,7 @@ static int git_pack_config(const char *k, const char *v)
                pack_size_limit_cfg = git_config_ulong(k, v);
                return 0;
        }
-       return git_default_config(k, v);
+       return git_default_config(k, v, cb);
 }
 
 static void read_object_list_from_stdin(void)
@@ -1937,7 +1963,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        rp_av[1] = "--objects"; /* --thin will make it --objects-edge */
        rp_ac = 2;
 
-       git_config(git_pack_config);
+       git_config(git_pack_config, NULL);
        if (!pack_compression_seen && core_compression_seen)
                pack_compression_level = core_compression_level;