Backing up a mercurial repository while preserving timestamps

backup, mercurial, timestamp

Solution

I suggest using `hg pull` instead of `hg clone`. So you'll keep a mirror of the repository on your server and update it periodically with `hg pull`. You then let your backup program take a backup of that. When you use `hg pull` you will transfer the newest history and only changed files under `.hg/store/data` which were actually effected by the pull.

Here I tested this by making a small repo with two files: `a.txt` and `b.txt`. I then cloned the repository "to the server" using `hg clone --noupdate`. That ensures that we have no working copy on the server -- it only needs the history found in `.hg`.

The timestamps looked like this after the clone:

% ll --time-style=full .hg/store/data
total 8.0K
-rw-r--r-- 1 mg mg 76 2009-11-25 20:07:52.000000000 +0100 a.txt.i
-rw-r--r-- 1 mg mg 69 2009-11-25 20:07:52.000000000 +0100 b.txt.i

As you noted, they are all identical since the files were all just created by the clone operation. I then changed the original repository (the one on the client) and made a commit. After pulling the changeset I got these timestamps:

% ll --time-style=full .hg/store/data
total 8.0K
-rw-r--r-- 1 mg mg 159 2009-11-25 20:08:47.000000000 +0100 a.txt.i
-rw-r--r-- 1 mg mg  69 2009-11-25 20:07:52.000000000 +0100 b.txt.i

Notice how the timestamp for `a.txt.i` has been updated (I only touched `a.txt` in my commit) while the timestamp for `b.txt.i` has been left alone.

If your backup software is smart, it will even notice that Mercurial has only appended data to `a.txt.i`. This means that the new `a.txt.i` file is identical to the old `a.txt.i` file up to certain point -- the backup program should therefore only copy the final part of the file. Rsync is an example of a backup program that will notice this.

Problem

Is there a way to back up a mercurial repository while preserving the files' timestamps? Right now, I'm using `hg clone` to copy the repository to a staging directory, and the backup program picks up the files from there. I'm not pointing the backup program directly at the repository because I don't want it to be changing (from commits) while the backup is happening. The problem is that `hg clone` changes all the files' timestamps to the current time, so the backup program (which I cannot change) thinks everything has been modified.

Original source