- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Recovered from files orphaned since before dits-and-dots' registry.yml integration existed, which had been silently shadowing this repo's own current functions since ~July (see aperture-dots session log for the full story of how that surfaced). Reviewed everything in the orphaned files against current tracked code; almost all of it was already superseded. Turns out the watch_folders inbox health-check/cleanup automation (_shk_check_watch_folders, _shk_cleanup_watch_folders, _shk_run_watch_folders) was already restored in 00_init.sh, just with 2 remaining yq calls missing -r - fixed those instead of the duplicate copy I nearly committed. Issue #4 tracks moving this off per-shell execution onto a systemd timer. shk_chezmoi_cheatsheet - genuinely new, migrated into 50_dev.sh, same style as the existing shk_git_cheatsheet/shk_acl. Also fixed two real bugs surfaced while diffing (present in the current tracked code independent of the orphan cleanup): - shk_directory_collapse_chains called an undefined collapse_single_dirs instead of recursing into itself - single-level chains collapsed fine, multi-level chains (a/b/c/d) silently didn't finish. - shk_chmod_files/shk_chmod_directories used unquoted $1/$2, breaking on paths with spaces (the function's own echo admitted as much). Not migrated (explicit decision): git_commit() (superseded in spirit by existing repo-specific dotpush-style flows), record_vhs() (superseded by shk_capture_vhs's more careful device detection, was self-marked TODO). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
| dotfiles | ||
| private-registry | ||
| .chezmoi.toml.tmpl | ||
| .chezmoiroot | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| install.sh | ||
| README.md | ||
| registry.yml | ||
dits-and-dots
Personal dotfiles managed with chezmoi. Includes modular bash configs under ~/.config/bash/bashrc.d/.
Install
bash <(curl -fsSL https://hex.wurzelraum.org/shukutils/dits-and-dots/raw/branch/main/install.sh) && source ~/.bashrc
This installs chezmoi (if missing) and applies the dotfiles. The installer itself
runs in a subshell (that's what bash <(...) does), so it can't reach back and
affect your current shell no matter what it does internally — && source ~/.bashrc
runs in your shell, right after, which is why it's chained onto this command
rather than being something install.sh does for you.
Editing configs
Never call chezmoi update/apply/re-add directly. Use:
dotpull— before you edit anything. Syncs the whole chezmoi source, not just bashrc.d.dotpush [message]— once you're done editing. Commits and pushes everything.bashedit— convenience wrapper:dotpull→ open all bashrc.d modules in vim →dotpush.
If dotpull/dotpush ever find that local and origin have diverged (e.g. a previous push
failed silently, or you edited on two machines), they don't merge blind or overwrite anything:
your local work gets pushed to a local-sync/<host>-<timestamp> branch on origin first, your
local branch is reset to match origin, then that temporary branch is deleted again — its job
was only to make the reset safe. Worst case a push fails and nothing moves; once it succeeds,
the commit SHA is printed so you can git cherry-pick it back if you ever need to, even though
it's no longer reachable from a branch name.
Run dits-help for a quick reference (chezmoi_cheatsheet still works as an alias).
Why "never call chezmoi directly" matters:
dotpull/dotpushcallchezmoi re-add/applyinternally, but chezmoi's owngit.autoCommit/autoPushconfig would otherwise fire inside that very call — a naive commit+push with no fetch-first check, racing ahead of the careful divergence handling below. This repo ships.chezmoi.toml.tmplwith both set tofalseso a freshchezmoi initnever enables them. If your machine was set up before this template existed, checkchezmoi cat-config | grep -A2 '\[git\]'— ifautoCommit/autoPushshowtrue, addautoCommit = falseandautoPush = falseunder[git]in~/.config/chezmoi/chezmoi.tomlby hand (re-runningchezmoi initwon't pick up the template on an already-initialized source repo).
Note:
~/.bashrcitself is never touched by chezmoi and stays yours to customize per-machine.install.shonly makes sure it has one include line pointing at~/.config/bash/bashrc, which is what chezmoi manages and which sources everything under~/.config/bash/bashrc.d/. For machine-local additions that shouldn't be synced at all, use~/.bash_aliasesinstead.
Additional repos (registry.yml)
Beyond this repo's own bashrc.d modules, registry.yml lists other git repos of
bash functions — private or public — that plug into the same loading mechanism
as local_source_dirs in ~/.shukonfig/shukonfig.yml: any repo's init.sh gets
sourced automatically once it's cloned locally.
dits-new— scaffold a brand-new registry repo before it exists anywhere: a local git repo with aninit.sh(contract + a demo function) and aREADME.md. Push it to your forge yourself when it's ready.dits-list— show every registry repo and whether it's installed on this machine.dits-register— add a new repo interactively: prompts for a name, the plain clone URL, and an access token (hidden input), builds the authenticated URL, encrypts it (its own passphrase, typed twice), and appends the entry toregistry.yml. Doesn't push — rundotpushyourself once you're happy with it.dits-install <name>— decrypt that repo's clone URL (prompts for its own passphrase) and clone it. Never re-clones if already present.dits-update—dotpull, then syncs every installed registry repo the same waydotpull/dotpushsync dits-and-dots itself: commits any local edits, pulls (fast-forward if behind), and pushes if ahead. On real divergence it snapshots to alocal-sync/<host>-<ts>branch, resets to origin, then deletes that branch again (prints the commit SHA for manual recovery) — same asdotpull. If the repo's token can't push at all (read-only), nothing is lost or left blocking the pull either: local work goes on a local-only branch (never pushed — it just doesn't exist upstream), the repo is reset to match origin, and that trade-off is printed plainly. Finishes by reloading the shell functions. No passphrase needed for any of this post-install: the decrypted URL (including any auth token) lives on in that clone's ownoriginremote, not in this repo.
"Installed" is never tracked in a file — it's just whether the repo's clone_dir
exists, checked fresh every time. Nothing about a private repo's host, path, or
token is ever in registry.yml itself; that's only ever inside its own
private-registry/<name>.age blob, encrypted with a passphrase specific to that
one repo. See private-registry/sample-private-repo.age for a working local example (demo
passphrase: dits-demo) and the separate sample-private-repo-template repo
(~/Repos/shk/sample-private-repo-template on this machine) for the init.sh
contract to build a real one from.