How to Sync Only File Timestamps Between Directories Using Rsync


3 views

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.