Skip to main content

Symlink-based dotfiles manager with auto-sync

Project description

dotpilot

Symlink-based dotfiles manager. Your repo mirrors your home directory — no dot_ prefixes, no templates, no source state. Edit a file, it's already applied.

uvx dotpilot

Requires uv. Install it with:

curl -LsSf https://astral.sh/uv/install.sh | sh

Why dotpilot?

Most dotfile managers copy files and require you to re-run a command after every edit. dotpilot symlinks — your dotfiles repo IS your home directory. Change a file in ~/dotfiles/.zshrc, and ~/.zshrc updates instantly because it's a symlink.

dotpilot chezmoi GNU Stow bare git
Edits apply instantly Yes (symlinks) No (must re-apply) Yes (symlinks) Yes
Repo structure Mirrors ~/ dot_, private_, executable_ prefixes Mirrors ~/ Mirrors ~/
New machine setup uvx dotpilot clone chezmoi init Manual clone + stow Manual clone
Dry-run by default Yes No No N/A
Tracks what you're NOT managing uvx dotpilot untracked No No No
Auto-sync from remote Built-in cron External External External
Auto-backup before apply Yes No No No
Templating Never — write agnostic scripts Yes (Go templates) No No
Secret management Never — use .localrc or 1Password/Bitwarden/pass Yes No No
Run scripts Not yet Yes (run_once_, run_onchange_) No No
File encryption Never — use age/GPG outside the repo Yes (age, GPG) No No
Cross-platform (Windows) Not yet Yes No No
Selective/partial install Not yet No Yes (per-package subdirs) Manual
Shell completions zsh bash, zsh, fish, PowerShell No N/A
Adopt existing files track command chezmoi add --adopt Manual
Dependencies Python (uv) None (Go binary) Perl Git

dotpilot trades templating and secrets for simplicity. If you need machine-specific config, use .localrc patterns or .overwrite files. If you need secrets, use a separate tool. Most people don't need either.

How it works

Your dotfiles live in a git repo (default ~/dotfiles). dotpilot creates symlinks from ~/ into that repo.

~/dotfiles/.zshrc  ←symlink←  ~/.zshrc
~/dotfiles/.config/nvim  ←symlink←  ~/.config/nvim

Special file conventions:

  • .overwrite suffix — copied instead of symlinked, for files that don't work as symlinks (e.g. .config/git/gitk.overwrite)
  • .delete suffix — removes the corresponding file from ~/ (e.g. .vimrc.delete removes ~/.vimrc)
  • .dotpilotignore — fnmatch patterns for files to skip (one per line, # comments). .gitignore patterns are also respected.

Quick start

Starting fresh

Set up a new dotfiles repo and start tracking your config:

git init ~/dotfiles && cd ~/dotfiles && git remote add origin git@github.com:you/dotfiles.git

uvx dotpilot track ~/.zshrc          # moves file into repo, symlinks back
uvx dotpilot track ~/.config/nvim    # works with directories too
uvx dotpilot untracked               # see what else you might want to track

Cloning an existing repo

Already have dotfiles on another machine? Pull them down:

uvx dotpilot clone git@github.com:you/dotfiles.git
uvx dotpilot apply               # dry-run: shows what would change
uvx dotpilot apply --apply       # back up + symlink everything

Day-to-day

It's just a git repo. Edit files, commit, push:

cd ~/dotfiles
git add -A && git commit -m "update zshrc"
git push

Pull changes on another machine:

uvx dotpilot sync --apply      # fetch + merge + re-apply symlinks

Or set up auto-sync so you never have to think about it:

uvx dotpilot cron --apply      # syncs every minute via cron

Auto-sync

The cron command installs a job that runs every minute (configurable with --schedule):

uvx dotpilot cron               # dry-run: shows what cron entry would be added
uvx dotpilot cron --apply        # install the cron job
uvx dotpilot cron --apply --remove  # remove it

The cron job runs uvx dotpilot@latest sync --apply --auto-apply, which fetches from origin, fast-forward merges, and re-applies symlinks if anything changed.

If the working directory is dirty or the merge isn't a fast-forward, sync bails out — it won't clobber your local changes.

Commands

All commands default to ~/dotfiles. Override with --dotfiles DIR. Use -h on any command for help.

Command Description
uvx dotpilot git <args> Run git commands in the dotfiles repo
uvx dotpilot clone <repo> Clone a dotfiles repo and dry-run apply
uvx dotpilot apply Symlink dotfiles into ~/ (dry-run by default, auto-backs up on --apply)
uvx dotpilot sync Fetch and fast-forward merge from origin
uvx dotpilot track <path> Start tracking a file — moves it to repo, symlinks back
uvx dotpilot untrack <path> Stop tracking — removes symlink, moves file back
uvx dotpilot untracked List dotfiles in ~/ and ~/.config you're not managing
uvx dotpilot status Git sync status — fetches remote, shows dirty/ahead/behind
uvx dotpilot backup Back up all managed dotfiles from ~/ into a timestamped directory
uvx dotpilot restore <dir> Restore dotfiles from a backup directory
uvx dotpilot doctor Check git, repo, SSH keys, upstream config
uvx dotpilot completion Install zsh completions
uvx dotpilot uninstall Remove symlinks, restore files, delete the dotfiles repo
uvx dotpilot cron Set up auto-sync every 30 minutes

Every mutating command is dry-run by default. Pass --apply to execute. Add -v to apply for verbose output.

Backup and restore

apply --apply automatically creates a backup before making changes. Backups are stored in ~/.local/state/dotpilot/backups/.

uvx dotpilot backup                      # manual backup
uvx dotpilot backup -o /tmp              # backup to custom location
uvx dotpilot restore ~/.local/state/dotpilot/backups/dotfiles-backup-* # dry-run
uvx dotpilot restore ~/.local/state/dotpilot/backups/dotfiles-backup-* --apply

Restore is symlink-aware — if symlinks are still in place, it writes through them into the repo. If symlinks are gone (e.g. after uninstall), it copies directly to ~/.

Uninstall

uvx dotpilot uninstall           # dry-run: shows symlinks, cron, unpushed warnings
uvx dotpilot uninstall --apply   # restore files, remove cron, delete repo

Warns about uncommitted changes and unpushed commits before deleting anything. Removes the cron job if one is installed.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotpilot-0.15.0.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotpilot-0.15.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file dotpilot-0.15.0.tar.gz.

File metadata

  • Download URL: dotpilot-0.15.0.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dotpilot-0.15.0.tar.gz
Algorithm Hash digest
SHA256 22a559d0c02cc95dab59a85c484c3efe6ab6f2ee8a544bb055fa71eb2a0ba6bc
MD5 b8addb7b002362784529e2a4c53b50b7
BLAKE2b-256 a0bed3edea5b1cc6827e68ceb6ec774fab13665408c83f7c460a4d174c3d17d9

See more details on using hashes here.

File details

Details for the file dotpilot-0.15.0-py3-none-any.whl.

File metadata

  • Download URL: dotpilot-0.15.0-py3-none-any.whl
  • Upload date:
  • Size: 23.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dotpilot-0.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2a5728eed0f418b2b529a98855ae034660f6433bd35ec22b9729b90ba18faeb4
MD5 cf00f480b6b1a0f1b8a67a6f04890ec2
BLAKE2b-256 eea23dfa279fa8862ea19d2f487aefea0086bd01666888ff62f66e97f192234a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page