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:
- 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.
- 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.
- 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.
- 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
- 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.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.