When working with mirrored directory structures where file contents are identical but timestamps differ, a common scenario emerges in development environments, backup systems, and deployment pipelines. The standard rsync behavior either ignores timestamps completely (-c checksum mode) or forces full file transfers when timestamps differ.
The original commands demonstrate this perfectly:
# Ignores timestamps, only checks content:
rsync --dry-run -crvv A/ B/
# Considers timestamps as change indicators:
rsync --dry-run -rvv A/ B/
To update only timestamps without transferring file contents:
rsync -rt --size-only --existing --ignore-existing A/ B/
This command combination:
- -rt: Preserves and updates timestamps
- --size-only: Skips content comparison
- --existing --ignore-existing: Prevents file creation/deletion
For systems without rsync or when more control is needed:
find A/ -type f -printf "touch -d \"%Tc\" \"B/%P\"\n" | sh
For directories with thousands of files, the rsync method is generally faster than find+touch because:
- Single process operation
- Optimized filesystem traversal
- Parallel transfer capabilities (with --progress)
To confirm timestamp synchronization:
diff <(find A/ -type f -printf "%Tc %p\n" | sort) \
<(find B/ -type f -printf "%Tc %p\n" | sort)
When managing duplicate directory structures where file contents are identical but timestamps differ, a full rsync operation would unnecessarily transfer all file contents. This creates inefficiency in both time and bandwidth usage.
The key observation from the original commands:
# With checksum (-c): shows files as uptodate
rsync --dry-run -crvv A/ B/
# Without checksum: wants to transfer everything
rsync --dry-run -rvv A/ B/
This demonstrates rsync's default behavior of using modification time and file size for comparison unless instructed otherwise.
The most efficient approach combines several rsync options:
rsync -rt --size-only --omit-dir-times A/ B/
Key options explained:
- -t: Preserve modification times
- -r: Recursive
- --size-only: Skip content comparison
- --omit-dir-times: Focus on files only
For cases where rsync isn't available, consider these methods:
Using find and touch
find A/ -type f -printf "touch -m -d \"%TY-%Tm-%Td %TH:%TM:%TS\" \"B/%P\"\n" | sh
Python Script Solution
import os
import shutil
def sync_timestamps(src, dst):
for root, dirs, files in os.walk(src):
rel_path = os.path.relpath(root, src)
dest_dir = os.path.join(dst, rel_path)
for f in files:
src_file = os.path.join(root, f)
dest_file = os.path.join(dest_dir, f)
if os.path.exists(dest_file):
stat = os.stat(src_file)
os.utime(dest_file, (stat.st_atime, stat.st_mtime))
sync_timestamps('A', 'B')
The rsync method typically offers the best performance for large directories due to its optimized delta algorithm, while the find/touch approach works well for smaller directory trees.
- Symbolic links (use rsync's -l option if needed)
- Files with spaces or special characters
- Different filesystem timestamp resolutions
- Permission requirements for timestamp modification
Always test with --dry-run before executing actual changes, especially when working with production data.