Mirroring a directory with rsync is destructive when the destination must stop carrying files that disappeared from the source. A destination used for static-site publishing, staging exports, or replica handoff can look current while still serving stale files unless the sync explicitly deletes destination-only paths.

The --delete option makes rsync remove files and directories that exist in the destination but not in the source. Pair it with a dry run first so the same source path, destination path, and mirror options show the planned deletions before any file is copied or removed.

Use a trailing slash on the source directory when the destination should receive the source contents rather than a new top-level source directory. The final check should produce no file or deletion entries, which means the destination tree already matches the source for the options in the verification command.

Steps to mirror a directory with rsync and delete extra files:

  1. Confirm the source and destination paths before adding deletion.
    Source: /srv/source/
    Destination: /srv/mirror/

    The trailing slash on /srv/source/ copies the contents of the source directory into /srv/mirror/. Without the slash, rsync creates a nested source directory under the destination.

  2. Run a dry run with deletion enabled.
    $ rsync -av --dry-run --delete /srv/source/ /srv/mirror/
    sending incremental file list
    deleting cache.tmp
    assets.txt
    deleting releases/old.txt
    releases/current.txt
    
    sent 150 bytes  received 56 bytes  412.00 bytes/sec
    total size is 34  speedup is 0.17 (DRY RUN)

    --delete removes destination-only files during the live run. Stop here if any deleting line names a file that must remain on the destination.

  3. Repeat the dry run with excludes when destination-only files should stay outside the mirror.
    $ rsync -av --dry-run --delete --exclude 'cache/' /srv/source/ /srv/mirror/

    Keep the same exclude rules in the dry run, live run, and verification command so rsync compares the same mirror scope each time.

  4. Run the live mirror after the dry run lists only the intended files and deletions.
    $ rsync -av --delete /srv/source/ /srv/mirror/
    sending incremental file list
    deleting cache.tmp
    assets.txt
    deleting releases/old.txt
    releases/current.txt
    
    sent 268 bytes  received 92 bytes  720.00 bytes/sec
    total size is 34  speedup is 0.09
  5. Repeat the sync as a checksum dry run to verify that no file or deletion entries remain.
    $ rsync -avnc --delete /srv/source/ /srv/mirror/
    sending incremental file list
    
    sent 172 bytes  received 13 bytes  370.00 bytes/sec
    total size is 34  speedup is 0.18 (DRY RUN)

    -n keeps the check read-only, and -c compares file checksums instead of relying only on size and modification time.