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:
.overwritesuffix — copied instead of symlinked, for files that don't work as symlinks (e.g..config/git/gitk.overwrite).deletesuffix — removes the corresponding file from~/(e.g..vimrc.deleteremoves~/.vimrc).dotpilotignore— fnmatch patterns for files to skip (one per line,#comments)..gitignorepatterns 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
Metadata
Release files for dotpilot 0.15.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dotpilot-0.15.0.tar.gz | 15.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dotpilot-0.15.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.3 kB
Release files / dotpilot-0.15.0.tar.gz
| Download URL | dotpilot-0.15.0.tar.gz |
|---|---|
| Size | 15.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
22a559d0c02cc95dab59a85c484c3efe6ab6f2ee8a544bb055fa71eb2a0ba6bc
|
|
BLAKE2b-256 checksum How to use checksums |
a0bed3edea5b1cc6827e68ceb6ec774fab13665408c83f7c460a4d174c3d17d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / dotpilot-0.15.0-py3-none-any.whl
| Download URL | dotpilot-0.15.0-py3-none-any.whl |
|---|---|
| Size | 23.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2a5728eed0f418b2b529a98855ae034660f6433bd35ec22b9729b90ba18faeb4
|
|
BLAKE2b-256 checksum How to use checksums |
eea23dfa279fa8862ea19d2f487aefea0086bd01666888ff62f66e97f192234a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|