diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index f504cff756..777f272668 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 73968e02b0..a18235e6d0 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -68,6 +68,7 @@ #include #include #include +#include #ifndef NO_SYS_SELECT_H #include #endif