rsync exclude hidden files Mac: Safe Dotfile Backup Guide

rsync exclude hidden files Mac guide: skip hidden caches and metadata while keeping restore-critical project dotfiles.

Mac developer cleaning a backup workflow full of hidden dotfiles and generated folders

rsync exclude hidden files Mac is a useful search because hidden files are where many developer backups go wrong. Dotfiles can be essential project configuration, disposable cache, private secret, Git history, macOS metadata, or tool state. A safe backup does not blindly copy every hidden path, and it also does not blindly delete every path that starts with a dot.

rsync exclude hidden files Mac: the safe starting point

The common shortcut is this:

rsync -avhn --exclude='.*' ~/Developer/my-app/ /Volumes/DevBackup/my-app/

That command is attractive because it appears to skip hidden files and hidden folders in one rule. It is also too blunt for most code projects. It excludes .gitignore, .npmrc, .ruby-version, .python-version, .tool-versions, .editorconfig, .env.example, and any other dotfile that may define how the project should build on a new machine.

Use a dry run first. The n in -avhn means no changes are made. It gives you a chance to catch missing config before the real copy:

rsync -avhn --itemize-changes \
  --exclude='.DS_Store' \
  --exclude='.Spotlight-V100/' \
  --exclude='.Trashes/' \
  --exclude='.fseventsd/' \
  ~/Developer/my-app/ /Volumes/DevBackup/my-app/

That smaller starter set skips macOS volume metadata without removing project configuration. From there, add explicit developer-tool folders that are safe to regenerate: node_modules/, .venv/, .pytest_cache/, .next/cache/, .turbo/, coverage/, dist/, and build/.

Why hidden files are risky in developer backups

macOS hides files whose names start with a dot because the convention comes from Unix. Developer tooling leans heavily on that convention. A project root might include visible folders such as src and tests, but the real build recipe often lives in hidden files.

  • Keep most project config. Files such as .editorconfig, .nvmrc, .node-version, .ruby-version, .python-version, .prettierrc, and .eslintrc are small and useful after restore.
  • Review secrets. .env, private keys, local certificates, and database dumps may be sensitive. They deserve a deliberate policy, not a wildcard accident.
  • Decide intentionally about Git history. .git/ is hidden and can be large. Excluding it is right for a clean working-tree backup when GitHub, GitLab, or another remote protects history. Including it is right when the backup must preserve local branches, tags, hooks, reflogs, or unpushed commits.
  • Skip generated hidden caches. .next/cache/, .turbo/, .pytest_cache/, .mypy_cache/, .ruff_cache/, .gradle/, and similar folders are typically rebuilt by tools.
Treat hidden paths by purpose, not by dot prefix Project root src/ package-lock.json .editorconfig .env .next/cache/ .DS_Store Policy keep config skip caches skip metadata review secrets choose .git Clean backup src/ tests/ .editorconfig .nvmrc noise filtered A precise rule set keeps restore-critical dotfiles while excluding generated churn and platform metadata.
A dot-prefix is a visibility convention. Your backup rules should classify hidden files by restore value, sensitivity, and rebuild cost.

Rsync patterns for hidden files on Mac

rsync exclude rules are path patterns, not regular expressions. A few examples show why broad hidden-file rules can surprise you:

Safer defaults

  • --exclude='.DS_Store' skips Finder metadata files wherever they appear.
  • --exclude='.Spotlight-V100/' skips a macOS volume index directory.
  • --exclude='.next/cache/' skips a specific generated cache but can keep .next structure if you need it.
  • --exclude='.pytest_cache/' skips Python test cache without removing project config.

Review first

  • --exclude='.*' skips nearly every dotfile and dotfolder at matching path levels, including useful config.
  • --exclude='.git/' changes the backup from a clone-like copy into a working-tree copy.
  • --exclude='.env' protects secrets, but may omit a local setup file you expected to restore.
  • --exclude='*/.*' can hide nested dotfiles you did not know were part of the build.

For one project, explicit command-line rules are fine. For recurring backups, put the policy in an exclude file so it can be reviewed like code:

# ~/.rsync-mac-dev-excludes
# macOS metadata
.DS_Store
.Spotlight-V100/
.Trashes/
.fseventsd/

# generated developer caches
node_modules/
.next/cache/
.nuxt/
.svelte-kit/
.turbo/
.vite/
.pytest_cache/
.mypy_cache/
.ruff_cache/
__pycache__/
.gradle/
coverage/
dist/
build/

# optional: clean working-tree backup only
# .git/

# optional: secrets policy, review before enabling
# .env
# *.pem
# *.key

Then use the file with a dry run:

rsync -avnih --delete \
  --exclude-from="$HOME/.rsync-mac-dev-excludes" \
  ~/Developer/my-app/ /Volumes/DevBackup/my-app/

Read the itemized output before removing n. You want to see source, tests, docs, manifests, lockfiles, and restore instructions. You should not see dependency trees, build output, cache folders, or macOS metadata. If .editorconfig or .nvmrc vanished from the preview, your pattern is too broad.

Abstract rsync filter separating hidden caches and useful dotfiles in a Mac developer backup
Hidden files are mixed cargo: some explain the project, some leak secrets, and some are only machine-local noise.

Step-by-step fix for clean hidden-file backups

1. List the hidden files before deciding

Start by looking at what you actually have. From the project root, use:

find . -maxdepth 2 -name '.*' -print | sort

Do not run a destructive mirror from that list. Use it to classify paths into four groups: keep, skip, review, and choose per backup type. Keep small config files. Skip machine-generated caches. Review anything secret. Decide whether this backup needs .git/.

2. Keep restore-critical dotfiles

Most project-level dotfiles are tiny. If they help another developer or future-you rebuild the project, keep them. Common examples include .gitignore, .editorconfig, .nvmrc, .node-version, .ruby-version, .python-version, .tool-versions, lint configs, formatter configs, and checked-in templates such as .env.example.

3. Exclude caches and platform junk explicitly

Caches are where sync tools get dragged into unnecessary work. A Next.js app can rebuild .next/cache/. Python can rebuild .pytest_cache/. Gradle can rebuild .gradle/. macOS can recreate .DS_Store. These are good exclude targets because they are reproducible and noisy.

4. Treat secrets separately

Some developers exclude .env from every backup. Others keep encrypted secret archives in a separate password manager or secrets vault. Both are better than letting --exclude='.*' make the decision by accident. If a backup destination is an external SSD in a drawer, your policy may differ from a cloud folder shared across devices.

5. Run a restore test

A clean backup is not just smaller. It should rebuild. Copy the backup to a scratch folder and run the project’s normal setup command: npm ci, pnpm install --frozen-lockfile, pip install -r requirements.txt, bundle install, or the project-specific equivalent. If setup fails because a dotfile is missing, promote that file from skip to keep.

When not to exclude hidden files

Do not exclude hidden files just to make a backup look cleaner. Several cases need them:

  • Offline clone backup: keep .git/ if the destination must preserve local history and branches without network access.
  • Toolchain pinning: keep version files such as .nvmrc, .ruby-version, .python-version, and .tool-versions.
  • Editor and formatting policy: keep .editorconfig, formatter config, lint config, and project-level TypeScript or test config.
  • Documented sample env files: keep .env.example or .env.template if they teach the restore process which variables are required.

The good backup is boring, but it is not minimal for its own sake. It preserves the files that explain the project and drops the files that are expensive to copy or unsafe to spread.

Organized Mac developer backup where useful dotfiles are kept and hidden caches are skipped
The clean workflow keeps the recipe and skips the churn: source, lockfiles, and useful dotfiles go to the backup; caches stay local.

When Lsyncer is easier than maintaining hidden-file rules

rsync is still the right answer for many developers. It is transparent, scriptable, and available on macOS. It becomes less pleasant when you need schedules, several folder pairs, visible run history, alerts, mounted-drive checks, and per-project exclusions that someone has to maintain over time.

Lsyncer takes the same filtered-backup idea and turns it into a native macOS workflow. You choose the source and destination, keep generated folders such as node_modules, .git, virtual environments, build output, and caches out of the sync, and run it on demand or on a schedule. It is a one-time $19.99 App Store purchase, not a subscription.

The rule is simple: use rsync when you want to own the command. Use Lsyncer when you want repeatable local project sync with a GUI, status, and fewer fragile shell details. In both cases, the technical policy is the same: back up source-of-truth files, skip generated churn, and review hidden files by purpose.

Best practices for hidden files in Mac project backups

  • Avoid blanket dotfile excludes. They are fast to type and easy to regret.
  • Keep an exclude file under version control. A small documented policy beats a mystery command in shell history.
  • Use dry runs after every pattern change. Hidden-file rules have a wide blast radius.
  • Separate source backup from secrets backup. Use the right storage and encryption for credentials instead of treating them as ordinary project files.
  • Keep active projects outside cloud-sync roots. Work in ~/Developer or ~/Code, then copy a filtered backup where you want it.

FAQ

How do I make rsync exclude hidden files on Mac?

Use quoted exclude patterns, for example --exclude='.DS_Store' or --exclude='.pytest_cache/'. Avoid starting with --exclude='.*' unless you truly want to skip project dotfiles such as .gitignore, .editorconfig, and version files.

Does --exclude='.*' exclude .gitignore?

Yes. A broad dotfile pattern can exclude useful project files such as .gitignore, .editorconfig, .nvmrc, and other hidden configuration. For developer backups, explicit excludes are usually safer.

Should I exclude .git from rsync backups?

Exclude .git/ for a clean working-tree backup when your remote repository protects history. Keep .git/ if the backup must preserve local branches, tags, hooks, reflogs, or unpushed commits. Decide per backup type.

Should I back up .env files?

Only if you have a deliberate secrets policy. Many teams keep real secrets in a password manager or encrypted vault and back up only .env.example. Do not let a broad hidden-file rule decide this silently.

What hidden files should Mac developers usually exclude?

Common safe exclusions include .DS_Store, .Spotlight-V100/, .Trashes/, .fseventsd/, and generated caches such as .next/cache/, .turbo/, .pytest_cache/, .mypy_cache/, and .gradle/.