# The `dotfiles` command | | | |---|---| | `dotfiles update` | fetch and fast-forward the repo | | `dotfiles apply` | update, `chezmoi apply`, then `metapac sync` | | `dotfiles chezmoi ...` | passthrough | | `dotfiles metapac ...` | passthrough | ## Deliberate constraints **`apply` refuses to run with uncommitted changes**, and checks before touching anything — so a half-applied state cannot come from a dirty tree. **`update` fast-forwards only.** `git merge --ff-only` after an explicit fetch, never a plain `pull`, so a diverged branch is reported rather than silently merged or rebased into a state nobody asked for. **`apply` never removes packages.** `metapac sync` installs what is missing; `clean` uninstalls what is not declared, which is destructive enough to stay an explicit `dotfiles metapac clean`. See [config/metapac.md](config/metapac.md) for why that command deserves respect. ## Why the script is wrapped in a brace group `dotfiles apply` runs `chezmoi apply`, which can rewrite this very script while it is executing. Bash reads scripts incrementally by byte offset, so a file that changes size underneath it can resume parsing at garbage. The braces force a full parse before anything runs.