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
find
command, 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
stat
command (-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
find
command to therestore_mtimes
file
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)