'git checkout' - how can I maintain timestamps when switching branches? 'git checkout' - how can I maintain timestamps when switching branches? git git

'git checkout' - how can I maintain timestamps when switching branches?


The situation (regarding git checkout and timestamps) should be better with Git 2.2.2+ (January 2015).

The timestamp should not move anymore for files which are already up-to-date when doing a git checkout.

See commit c5326bd by Jeff King (peff):

checkout $tree: do not throw away unchanged index entries

When we "git checkout $tree", we:

  • pull paths from $tree into the index, and then
  • check the resulting entries out to the worktree.

Our method for the first step is rather heavy-handed, though; it clobbers the entire existing index entry, even if the content is the same.
This means we lose our stat information, leading checkout_entry to later rewrite the entire file with identical content.

Instead, let's see if we have the identical entry already in the index, in which case we leave it in place. That lets checkout_entry do the right thing.
Our tests cover two interesting cases:

  1. We make sure that a file which has no changes is not rewritten.
  2. We make sure that we do update a file that is unchanged in the index (versus $tree), but has working tree changes.
    We keep the old index entry, and checkout_entry is able to realize that our stat information is out of date.


The reason that git checkout updates timestamps is that almost all build systems for source code depend on timestamps to determine if targets need to be rebuilt. If git checkout did not update timestamps on files when they are updated, these build systems would not correctly do an incremental build. In fact, git checkout should only update timestamps on files that have changed.

rsync should be efficient in updating time stamps, and not transfer any data if only metadata has changed. You can verify this with the "speedup". You can also ask recent versions of rsync to itemize changes with the -i flag. You can tell rsync not to use timestamps (and only use checksums) by leaving out -a or -t, but that's not recommended by the rsync(1) man page.


It seems that the only reason Git do it this way is that in a DVCS environment, you may use an old timestamp file to update a new timestamp file and cause a build problem. I don't think this is good, because rarely do we use an old timestamp file to update a new timestamp file.

  1. I think this can be handled in a smart way: when update file A with file B,

    file_timestamp = (timestamp(B) > timestamp(A)) ? timestamp(B) : timestamp(CURRENT);

  2. or, this could be designed as a configurable option.