rsync -a (archive mode): What It Does in CI
rsync -a recursively copies a tree while preserving symlinks, permissions, timestamps, and special files.
Most CI deploys start with rsync -a because it keeps file modes and mtimes intact, which is what makes rsync skip unchanged files on the next run.
What it does
-a (archive) is a shortcut for -rlptgoD: recurse into directories, copy symlinks as symlinks, and preserve permissions, modification times, group, owner, and device/special files. It does not preserve hardlinks (use -H) or ACLs/xattrs (use -A / -X). Preserving mtimes matters in CI because rsync uses size plus mtime to decide what to skip on the next sync.
Common usage
# Sync a built site into a deploy directory
rsync -a dist/ /var/www/app/
# Archive plus verbose plus compression over SSH
rsync -avz dist/ user@host:/var/www/app/What -a expands to
| Flag | Meaning |
|---|---|
| -r | Recurse into directories |
| -l | Copy symlinks as symlinks |
| -p | Preserve permissions |
| -t | Preserve modification times |
| -g | Preserve group |
| -o | Preserve owner (super-user only) |
| -D | Preserve device and special files |
In CI
Preserving owner (-o) only works as root, so on a normal SSH deploy user rsync silently drops ownership changes. That is fine for web deploys. If you need a specific owner on the target, pair with --chown or run the remote side via --rsync-path="sudo rsync".
Common errors in CI
rsync: failed to set times on "...": Operation not permitted (1) usually means the destination filesystem or mount does not allow setting mtimes for your user. Add --no-t to skip time preservation, or -O / --omit-dir-times if only directories are failing. The transfer still completes but rsync returns a non-zero code (often 23).