I recently needed to keep the exact file modification times as a part of a git repository. Since git doesn't support such functionality out of the box, I used a simple combination of find and touch commands as a part of the pre-commit hook.
Here are two versions of this approach, one with the stat command, and the other one with just the combination of find and touch.
1st version (stat)
find . -type f -exec stat -c 'touch -d "%y" "%n"' {} \; > restore_mtimes
Explanation:
- Using the
findcommand, we're recursively iterating over all files (-type f) in all subdirectories, starting from the current directory (.) - for each file, we're executing (-exec flag) the
stat ...command (The string{}is replaced by the current file name) - we're using the formatted output of
statcommand (-c flag) to generatetouch -d "%y" "%n"lines as a part of our restore script ("%y" is modification time, "%n" is file name). - we're redirecting the whole output of the
findcommand to therestore_mtimesfile
The resulting restore_mtimes file looks something like this:
touch -d "2022-09-26 15:55:10.127898032 +0200" "./f2"
touch -d "2022-09-26 15:55:11.651909078 +0200" "./f3"
touch -d "2022-09-26 15:55:06.751873534 +0200" "./f1"
You can execute this file to restore the original modification times (either by making it executable with chmod +x restore_mtimes or sourcing it directly with . restore_mtimes).
2nd version (find & touch)
Since we only need the file modification time, we could optimize things by removing the unnecessary call to the stat command, and simply use the modification time provided by find command:
find . -type f -printf 'touch -d "%t" "%p"\n' > restore_mtimes
- "%t" is modification time, "%p" is file name
- unlike with
stat -c, we also need to explicitly add a newline character at the end
The time format returned by find is a bit different (but it should be also parsed correctly by touch):
touch -d "Mon Sep 26 15:55:10.1278980320 2022" "./f2"
touch -d "Mon Sep 26 15:55:11.6519090780 2022" "./f3"
touch -d "Mon Sep 26 15:55:06.7518735340 2022" "./f1"
Alternatives and additional things to consider:
VCS commit times
One alternative to backing up file modification times is reusing the last commit time from your versioning control system, e.g.: restoring file mtimes with git.
touch --no-create
In cases where you're planning to restore the modification times to a tree where some files may be deleted, it may be useful to add the --no-create flag (which will prevent touch from creating any new files).
Note: This is a snapshot of the wiki page from the BetterWays.dev wiki, you can find the latest, better formatted version here: betterways.dev/cli-backing-up-and-restoring-file-modification-times.
Top comments (0)