C.W.K.
Stream
Lesson 10 of 12 · published

Dotfiles Sync

~15 min · dotfiles, rsync, git

Level 0Pinger
0 XP0/101 lessons0/12 achievements
0/150 XP to next level150 XP to go0% complete

Consistent config across the fleet

Your .zshrc, .gitconfig, ~/.ssh/config, editor settings — these need to be identical across every machine. The standard approach: a dotfiles git repo, plus a small bootstrap script that uses rsync to deploy.

Why rsync (not symlinks)

Some dotfile managers symlink files from the repo into ~/. That works but pulls the repo path into the dependency graph — break the repo location and shells start failing. rsync deploys real files; the repo is your version control, the deployed copy is what runs. Cleaner separation.

Never commit secrets

Public keys live in dotfiles. Private keys, env files with API keys, tokens — never. Use .gitignore to exclude id_* (without .pub), .env*, anything that shouldn't leave the machine.

Code

Repo layout·plaintext
~/dotfiles/
├── .zshrc
├── .gitconfig
├── .ssh/
│   └── config           # ← shared SSH config
├── .config/
│   ├── nvim/
│   └── starship.toml
├── Brewfile             # `brew bundle` source of truth
├── bootstrap.sh         # the deploy script
└── .gitignore           # exclude private keys, .env, etc.
bootstrap.sh — deploy on a machine·bash
#!/bin/bash
set -euo pipefail

DOTFILES="$HOME/dotfiles"
REPO="git@github.com:you_username/dotfiles.git"

# Clone or update
if [[ -d "$DOTFILES" ]]; then
    git -C "$DOTFILES" pull --rebase
else
    git clone "$REPO" "$DOTFILES"
fi

# Sync into ~ — exclude the meta files
rsync -avh --no-perms "$DOTFILES/" "$HOME/" \
    --exclude '.git' \
    --exclude 'bootstrap.sh' \
    --exclude 'Brewfile' \
    --exclude 'README.md'

# Install Brew packages
brew bundle --file="$DOTFILES/Brewfile" || true

echo 'Done. Run: source ~/.zshrc'

External links

Exercise

If you don't have one yet, create a ~/dotfiles/ git repo with at minimum your .zshrc and .ssh/config. Write a 10-line bootstrap.sh that rsyncs from the repo into ~/. Try it on a second machine — push to GitHub from one, clone and bootstrap on another, watch your shell come up identically.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.