aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2008-03-13 14:59:29 -0400
committerJunio C Hamano <gitster@pobox.com>2008-03-13 22:51:30 -0700
commitf746bae84e4746a861d9ebed29fd9255e5cd929f (patch)
tree04361153853f68efce7e726929426e55d91478ab
parentb75aaa546e0593440d85c77d380c9b53e126ea02 (diff)
downloadgit-f746bae84e4746a861d9ebed29fd9255e5cd929f.tar.gz
git-f746bae84e4746a861d9ebed29fd9255e5cd929f.tar.xz
pack-objects: proper pack time stamping with --max-pack-size
Runtime pack access is done in the pack file mtime order since recent packs are more likely to contain frequently used objects than old packs. However the --max-pack-size option can produce multiple packs with mtime in the reversed order as newer objects are always written first. Let's modify mtime of later pack files (when any) so they appear older than preceding ones when a repack creates multiple packs. Signed-off-by: Nicolas Pitre <nico@cam.org>
-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