Manage dotfiles: register configs, bootstrap symlinks, and keep everything in sync.
Project description
dotgarden
Manage dotfiles by moving them into a git-tracked repo and pointing $HOME at
the repo-managed copies. dotfile register relocates a live config into the
repo and leaves a symlink behind; dotfile bootstrap replays those symlinks
(plus OS/profile variants) on any machine. Ships the dotfile CLI.
Install
uv tool install dotgarden
# or
pipx install dotgarden
# or
pip install dotgarden
Quick start
Clone the dotgarden-template
repo — a working dotfiles layout that exercises every dotfile feature.
git clone https://github.com/andrewlook/dotgarden-template.git ~/dotfiles
cd ~/dotfiles
dotfile bootstrap --os macos # or --os linux
What's in the template
dotfiles/
├── .gitconfig root dotfile → ~/.gitconfig
├── .macos.gitconfig OS variant, sourced via ~/.gitconfig.local
├── .linux.gitconfig
├── .zprofile
├── .macos.zprofile
├── .tmux.conf
├── .config/ auto-symlinked 1:1 into ~/.config/
│ ├── fish/
│ │ ├── config.fish
│ │ └── config.macos.fish nested variant (BASE.MOD.EXT)
│ └── ghostty/
│ └── config
├── _cursor/ registered: target lives outside ~/.config/
│ ├── settings.json
│ └── keybindings.json
├── __registry__.yaml
└── bootstrap.sh curl-pipe-sh installer for new machines
Everything at the repo root (.gitconfig, .zprofile, …) and every
top-level child of .config/ is placed by convention. The registry handles
the rest — here, just Cursor, whose real target path is nowhere near
~/.config/:
# __registry__.yaml
os: [macos, linux]
profiles: [work, home]
cursor:
macos:
- _cursor/settings.json: ~/Library/Application Support/Cursor/User/settings.json
- _cursor/keybindings.json: ~/Library/Application Support/Cursor/User/keybindings.json
What bootstrap produces
$ dotfile bootstrap --os macos
common
✓ ~/.gitconfig -> ~/dotfiles/.gitconfig
✓ ~/.macos.gitconfig -> ~/dotfiles/.macos.gitconfig
✓ ~/.zprofile -> ~/dotfiles/.zprofile
✓ ~/.config/fish -> ~/dotfiles/.config/fish
✓ ~/.config/ghostty -> ~/dotfiles/.config/ghostty
registered
✓ ~/Library/Application\ Support/Cursor/User/settings.json
-> ~/dotfiles/_cursor/settings.json
local
✓ ~/.gitconfig.local
✓ ~/.config/fish/config.fish.local
✓ Bootstrap complete (8 created)
$HOME is now a set of symlinks pointing back at the repo, plus a few
generated .local files that source the right OS/profile variants:
$ ls -l ~/.gitconfig ~/.config/ghostty
~/.gitconfig -> ~/dotfiles/.gitconfig
~/.config/ghostty -> ~/dotfiles/.config/ghostty
$ cat ~/.gitconfig.local
# Auto-generated by dotfile bootstrap. Do not edit.
[include]
path = ~/.macos.gitconfig
Edits in either location track together — they're the same inode. See GUIDE.md for the hands-on walkthrough.
Commands
| Command | Description |
|---|---|
dotfile bootstrap |
Link files in $HOME to the repo-managed versions and generate .local include files |
dotfile status |
Check health of all managed symlinks |
dotfile register |
Move a config into the repo and symlink it back |
dotfile unregister |
Remove a config from management |
dotfile specialize |
Scaffold OS/profile variant files and wire their .local include |
dotfile list |
List all managed files |
dotfile doctor |
Find and remove stale symlinks |
dotfile env |
Show current OS, profile, and overlay |
dotfile ids |
Print entry IDs (for scripting) |
dotfile bootstrap
dotfile bootstrap --os <macos|linux> [--profile <name>] [--overlay <dir>] [--dry-run]
Runs every symlink and .local generator from a clean slate. Safe to re-run.
--os— required on first run; remembered in~/.dotfiles_envafter.--profile— activates a profile's variant files and registry entries.--overlay— layers a second repo on top (see GUIDE.md § Overlay).--dry-run— print the plan without touching the filesystem.--skip-registry— only handle root +.config/*conventions, skip registered entries.--skip-unsupported— silently skip.localgeneration for tool types with no known include syntax.
Existing non-symlink files at a link location are preserved as <path>.bak
before being replaced.
dotfile register
dotfile register <path> [--category <name>] [--os <os>] [--profile <name>] [--name <file>] [--overlay <dir>] [--force] [--dry-run] [-y]
Moves <path> into the repo (under _<category>/ or the repo root) and
creates a symlink back. Errors if the destination already exists unless you
pass --force.
--category— target subdirectory in the repo (auto-detected from the source path if omitted).--os/--profile— scope the entry so bootstrap only links it on matching machines.--name— rename the file inside the repo.--overlay— write into an overlay repo instead of the main one.--force— overwrite an existing registration or repo file.-y— skip the confirmation prompt.
dotfile specialize
dotfile specialize <os|profile> <dotfile> [--dry-run]
Scaffolds variant files for an existing base dotfile and appends the .local
include line so bootstrap can generate the override file.
Works on root paths (.gitconfig) and nested paths under .config/<tool>/
(e.g. .config/fish/config.fish). Variant names come from the os: and
profiles: lists in __registry__.yaml. Idempotent — safe to re-run.
Documentation
- GUIDE.md — hands-on walkthrough: starting a repo, registering your first files, specializing for OS/profile, setting up an overlay
- Starter template — clone this to begin a new dotfiles repo
- Source and issue tracker: https://github.com/andrewlook/dotgarden
Development
See CONTRIBUTING.md for setup, testing (mise run test,
./test-docker), and the publish flow. The package layout, entry point
(dotgarden.cli:main), and test harness all live in this repo — edits
happen here directly.
The examples/starter/ directory is mirrored to
andrewlook/dotgarden-template
as the clone-ready starting point documented in Quick start above.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dotgarden-0.3.0.tar.gz.
File metadata
- Download URL: dotgarden-0.3.0.tar.gz
- Upload date:
- Size: 84.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3432c296e34e9e266d9cbc9d7b964e0da171752616285af6c6290f8524aca77d
|
|
| MD5 |
c5b605be77cc7968898181b972d304cf
|
|
| BLAKE2b-256 |
d312c012473c7690fa0bdc091e4458bcc31bd38073d4150e9ceb5cd603373078
|
Provenance
The following attestation bundles were made for dotgarden-0.3.0.tar.gz:
Publisher:
publish.yml on andrewlook/dotgarden
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotgarden-0.3.0.tar.gz -
Subject digest:
3432c296e34e9e266d9cbc9d7b964e0da171752616285af6c6290f8524aca77d - Sigstore transparency entry: 1366815480
- Sigstore integration time:
-
Permalink:
andrewlook/dotgarden@8bed1d60ef2d65ae6e1922a5e3f6adc1419b75e6 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/andrewlook
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8bed1d60ef2d65ae6e1922a5e3f6adc1419b75e6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dotgarden-0.3.0-py3-none-any.whl.
File metadata
- Download URL: dotgarden-0.3.0-py3-none-any.whl
- Upload date:
- Size: 52.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77d8e3d4de5926350d1dac2a1b499b7993a49b59ed656c34747e46d0bec4440b
|
|
| MD5 |
4b7c8a0f7c968cf9acf575837856a69e
|
|
| BLAKE2b-256 |
35b335b36bb91d7b6db01e1161a59bfc23971edb8c89f9b2879778f309a67aed
|
Provenance
The following attestation bundles were made for dotgarden-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on andrewlook/dotgarden
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotgarden-0.3.0-py3-none-any.whl -
Subject digest:
77d8e3d4de5926350d1dac2a1b499b7993a49b59ed656c34747e46d0bec4440b - Sigstore transparency entry: 1366815486
- Sigstore integration time:
-
Permalink:
andrewlook/dotgarden@8bed1d60ef2d65ae6e1922a5e3f6adc1419b75e6 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/andrewlook
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8bed1d60ef2d65ae6e1922a5e3f6adc1419b75e6 -
Trigger Event:
push
-
Statement type: