rsync –dry-run before anything with –delete

--delete removes files at the destination that are not at the source, which is what makes rsync a deployment tool rather than a copy. It is also one mistyped source path away from emptying the target directory.

# always first
rsync -avz --delete --dry-run ./public/ deploy@host:/var/www/app/public/

# note the trailing slash on the source:
#   ./public/   copies the contents
#   ./public    copies the directory itself, into public/public

The trailing slash rule is the other half of the danger, because getting it wrong nests a copy inside the target and --delete then removes what was there. -n is the short form and there is no reason not to make it a habit. --exclude patterns are worth checking in the dry run too — an excluded path is not deleted, but a mistyped exclude is not excluded either.