aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-pack-objects.c26
-rw-r--r--git-compat-util.h1
2 files changed, 27 insertions, 0 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index f504cff75..777f27266 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -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));
diff --git a/git-compat-util.h b/git-compat-util.h
index 73968e02b..a18235e6d 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -68,6 +68,7 @@
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <utime.h>
#ifndef NO_SYS_SELECT_H
#include <sys/select.h>
#endif