How to Make rsync Ignore File Permissions and Sync by Size Only


8 views

When synchronizing PHP applications between directories, you might encounter situations where file permissions differ between source and destination. A common scenario is when files in the source directory accidentally have 755 permissions while the destination maintains correct permissions.

rsync performs comprehensive checks by default, comparing:

  • File sizes
  • Modification times
  • Permissions (mode bits)
  • Ownership

This thorough checking ensures complete synchronization but can be problematic when you only want to sync content changes.

To make rsync ignore permissions and focus solely on file sizes, use:

rsync -rvz --size-only /source/directory/ /destination/directory/

If you need more control over what rsync compares, consider these options:

# Ignore permissions and ownership
rsync -rvz --no-perms --no-owner --no-group /source/ /destination/

# Compare checksums instead of size (more accurate but slower)
rsync -rvz -c /source/ /destination/

For your PHP application synchronization scenario:

rsync -rvz --size-only --exclude='*.log' \
--exclude='tmp/' /var/www/source_app/ /var/www/production_app/

This command will:

  • Sync only changed files based on size
  • Preserve destination permissions
  • Exclude log files and temp directories

Remember that --size-only has limitations:

  • Files with identical sizes but different content won't be synced
  • Use with caution in critical environments
  • Consider -c (checksum) option for more reliable comparisons

When synchronizing PHP applications between development and production environments, file permissions often become a pain point. By default, rsync checks both file contents and permissions, which can lead to unwanted permission changes when the source directory has incorrect permissions (like 755 instead of the preferred 644 for PHP files).

The most effective solution combines these rsync flags:

rsync -rvz --no-perms --no-owner --no-group --size-only src/ dest/

This command:

  • -rvz: Recursive, verbose, compression
  • --no-perms: Prevents permission preservation
  • --no-owner: Ignores ownership changes
  • --no-group: Ignores group changes
  • --size-only: Compares files by size only

For a typical PHP application deployment where you want to preserve destination permissions:

rsync -avz \
    --no-perms --no-owner --no-group \
    --exclude='.git/' \
    --exclude='config.php' \
    /var/www/dev-app/ user@production:/var/www/live-app/

If you need more accurate change detection than just size comparison:

rsync -rvzc --no-perms --checksum src/ dest/

The -c or --checksum flag makes rsync compare checksums rather than just size and modification time.

Remember that:

  • This approach won't fix existing permission problems - use chmod separately for that
  • For security-critical files, you might still want to enforce permissions
  • Consider adding --dry-run first to verify changes

For regular deployments, create a wrapper script:

#!/bin/bash
SRC="/path/to/source"
DEST="user@server:/path/to/dest"

rsync -avz \
    --no-perms --no-owner --no-group \
    --exclude-from='rsync_exclude.txt' \
    $SRC $DEST

# Optional: Set correct permissions remotely
ssh user@server "find /path/to/dest -type f -exec chmod 644 {} \;"
ssh user@server "find /path/to/dest -type d -exec chmod 755 {} \;"