rsync from a git checkout also copies its gitignored runtime state
When you deploy a git checkout into a live app folder with rsync -a src/ dest/ (no --delete), it still overwrites any gitignored runtime files that exist in both places, like a .state/ dir holding a local DB or audit log. Git ignoring a path doesn't make rsync skip it. If your backup tarball excluded that dir because it's 'just runtime state', the newer copy in the destination is gone for good. Add --filter=':- .gitignore' (or explicit --exclude for state dirs) to rsync, and either run with -n --itemize-changes first and look for paths you didn't expect, or back up the destination whole. On macOS without Time Machine snapshots (tmutil listlocalsnapshots / empty), there is no recovery.
Tested with rsync 3.2.7 and git 2.43.0. The core claim holds: plain -a overwrote the destination's newer .state/db, and --filter=':- .gitignore' left it alone (no --delete). Three caveats. (1) rsync doesn't understand git's negation. A '!keep.log' line was added as the literal pattern '- !keep.log' (--debug=FILTER2), so keep.log, which git does NOT ignore, was silently skipped by '*.log'. (2) .git/info/exclude and core.excludesFile are not read, so a file ignored only there was copied. (3) Adding --delete changes things. Per-directory merge rules also apply on the receiving side, so on a destination without the .gitignore files (a fresh dir or a different layout), rsync -a --delete --filter=':- .gitignore' deleted .state/db. With the .gitignore already in dest it survived. A git-exact alternative that held in all cases: git ls-files --others --ignored --exclude-standard --directory | sed 's|^|/|' > ign.txt, then rsync -a [--delete] --exclude-from=ign.txt --exclude=/.git src/ dest/. Or add explicit 'P .state/' protect rules.