Worktree-per-task workflow: retire working-branch, fix check-dotfiles' checkout resolution - #29
Merged
Merged
Conversation
…trees Running the checks from a second worktree turned up three problems, all of which made a broken setup look fine. `just check` invoked ~/bin/check-dotfiles, which resolves its repo root from its own location, so from a worktree it scanned $HOME instead. $HOME is the yadm main worktree and has no .git directory of its own, so git ls-files matched nothing and the run reported "All 0 checks passed" -- a green result over an empty file list. The recipe now uses ./bin/check-dotfiles so it validates the checkout you are standing in. The other recipes keep using ~/bin because they act on the live system rather than a checkout. The script now refuses to run outside a git checkout, and refuses to report success when it matched no files at all, so that failure cannot recur silently. It also now probes python3 before using it. This repo ships .config/mise/config.toml, which mise picks up as a project config whenever the cwd is inside a checkout, and a freshly created worktree is untrusted by default -- so every mise-shimmed binary exits 1 rather than running. That surfaced as 73 "parse error" failures against config files that are perfectly valid. The probe turns it into one message naming `mise trust`. README documents the worktree-per-task workflow this exercised, including the mise trust step and the reason a bare `git commit` after `git rm` is a trap.
tlockney
marked this pull request as ready for review
July 27, 2026 21:36
working-branch existed to give quick, exploratory edits somewhere to live without the overhead of a branch and a checkout. The worktree convention covers that case now, so keeping it around only preserves a second, softer path where changes reach $HOME without review. ~/src/personal/dotfiles becomes the launcher: detached at origin/main, used to read the tree and start tasks from, never edited in. Detached rather than on a branch because a linked worktree cannot check out main -- $HOME already has it -- and because with no branch there is nowhere for a stray edit to accumulate. To keep starting a task as cheap as working-branch was, `just worktree <name>` creates the worktree off origin/main, puts it on its own branch, and runs mise trust so shimmed binaries work there. `just worktree-done <name>` removes it again, deletes the branch with -d so unmerged work is refused rather than discarded, and re-parks the launcher at origin/main. Both resolve the worktrees directory whether run from the launcher or from another task worktree, and worktree-done declines to re-park when it is not the launcher or when the tree is dirty. The raycast toolbox README pointed at `yadm merge working-branch`; it now points at `yadm fetch && yadm merge origin/main`. The dated plan under .config/dotfiles/plans/ still mentions working-branch and is left alone: it records what was true when it was written.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Asked to park
~/src/personal/dotfilesback onworking-branchand establish a convention where future work happens in its own worktree on its own branch. Dogfooding that convention — this PR was built in a worktree — immediately broke three things.What dogfooding found
1.
just checkreported "All 0 checks passed" from a worktree.The recipe called
~/bin/check-dotfiles, which resolves its repo root from its own location — so from a worktree it scanned$HOME, not the worktree.$HOMEis the yadm main worktree and has no.gitdirectory of its own, sogit ls-filesmatched nothing and every section trivially passed. A green run that checked nothing is the worst result this script can produce, and my own Justfile recipe walked straight into it.Fixed by using
./bin/check-dotfiles. The other recipes keep~/binbecause they act on the live system rather than a checkout.2. Nothing prevented that from recurring silently.
The script now refuses to run outside a git checkout, and refuses to report success when it matched zero files. Both verified:
3. Every new worktree is broken for mise-shimmed tools.
This repo ships
.config/mise/config.toml, so mise treats any checkout as a project config and refuses to run until that exact path is trusted. A freshly created worktree is untrusted, sopython3,node,uvx— all mise shims — exit 1 instead of running. This surfaced as 73 "parse error" failures against config files that are entirely valid.That is not a problem with this script; it affects anything you run in a new worktree. It is now documented as a required step, and the script probes for it:
The documented convention
~/src/personal/dotfilesstays parked onworking-branchas a stable, current checkout and is not where edits happen. Each task gets../dotfiles-worktrees/<task>on its own branch offorigin/main, trusted withmise trust, validated withjust check, then removed when merged.The README also records two traps hit during this session: never
git checkout mainin a linked worktree (mainbelongs to the$HOMEworktree), and never a baregit commitafter agit rm— it commits the whole index and will sweep unrelated staged changes into your commit, which is exactly what happened to thelint.ymldeletion in #28 before I redid those commits.Verification
From the worktree, after
mise trust:configsis 77 locally vs 97 in CI because the runner hasluacand this Mac does not — reported asSKIP, not a silent pass.