Repository navigation
feat(scripts): create worktrees with new-worktree.sh and keep the shared hook bound to the primary checkout - #218
Merged
Conversation
…orktree Git hooks live in the repository's common directory and every worktree shares them, and `pre-commit install` writes the interpreter that runs it into the hook. setup-hooks.sh ran it wherever it was invoked, so running it in a worktree bound every checkout's commits to that worktree's virtual environment, and once the worktree was removed every commit failed with "`pre-commit` not found". It now installs the hook only in the primary checkout. A worktree checks that the shared hook is bound to the primary checkout's environment and says how to rebind it if not, and leaves it alone either way. It also syncs on every run. The stamp file it gated on had been committed, so a fresh worktree checked the stamp out and whether it got an environment at all came down to the order in which checkout wrote files. The stamp is now untracked and ignored.
Creating a worktree correctly takes several steps that are easy to skip, and skipping them fails quietly. scripts/new-worktree.sh <name> [<branch>] does them in order: it fetches origin, fast-forwards local main where that is safe and refuses when main holds commits origin/main lacks, creates ../span-panel-api-<name> on a branch that tracks no remote so a bare push can never land on main, links .env from the primary checkout, and runs setup-hooks.sh inside it. The worktree gets a virtual environment of its own rather than a link to the primary checkout's. This repository installs its own distributions in editable mode, each recording one checkout's source path, so a shared environment imports whichever checkout synced last and tests pass against the wrong code without an error. Main is moved with update-ref rather than `branch --force`, which would also rewrite its upstream, and a checked-out main is fast-forwarded only when it has no uncommitted tracked changes. The setup script beside this one runs rather than the new worktree's copy, because a branch from origin/main can predate the worktree-aware setup.
…orktree A worktree commits through the one hook in the common directory. When that hook was missing, new-worktree.sh only warned after the fact and the worktree's commits skipped every check without a word; when it was bound to an environment that no longer exists, they failed. setup-hooks.sh gains --check-hook, which exits non-zero when the shared hook is missing or not bound to the primary checkout. new-worktree.sh runs it before creating the worktree, installs the hook from the primary checkout when it fails, and refuses to create the worktree if the hook is still not bound afterwards.
AGENTS.md gains a Worktrees section: create worktrees with scripts/new-worktree.sh rather than `git worktree add` or a built-in worktree tool, never share a virtual environment between checkouts, and install the pre-commit hook from the primary checkout. CLAUDE.md already imports AGENTS.md, so the section reaches every agent without further change.
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.
Worktrees of this repository have been created with
scripts/new-worktree.sh, from a branch that never reachedmainor a pre-release branch. This brings the script in, with thesetup-hooks.shfix it depends on and the instructions for both.The fix matters on its own. Git hooks live in the repository's common directory and every worktree shares them, and
pre-commit installwrites the interpreter that runs it into the hook.setup-hooks.shran it wherever it was invoked, so running it in a worktree bound every checkout's commits to that worktree's virtual environment, and once the worktree was removed every commit failed with "pre-commitnot found".Change
setup-hooks.sh:--check-hookonly checks, and exits non-zero when the hook is missing, bound to another environment, or bound to an interpreter that no longer exists..deps-installedstamp it gated on had been committed, so whether a fresh worktree got an environment at all depended on the order in which checkout wrote files. The stamp is removed from the repository and ignored.scripts/new-worktree.sh <name> [<branch>]:origin, fast-forwards localmainwhere that is safe, and refuses whenmainholds commitsorigin/mainlacks.../span-panel-api-<name>on a branch that tracks no remote, so a baregit pushcan never land onmain, and links.env.setup-hooks.shbeside the script rather than the worktree's own copy, becauseorigin/maincan predate the worktree-aware one and running that would rebind the shared hook.DEVELOPMENT.md: the Git Hooks section describes both modes and--check-hook, and a new Worktrees section describes the script.AGENTS.md: a Worktrees section.CLAUDE.mdalready importsAGENTS.md.The integration's script comes in with SpanPanel/span#333.
Checks
--check-hook, exercised in a throwaway repository:new-worktree.shrefusals: a name with a space and a call with no arguments exit 2. An existing target directory and an existing branch exit 1, before anything is fetched or created.--check-hookfrom the worktree agrees.shellcheckis clean on both scripts. All hooks pass over the branch: 1857 passed, 7 skipped, 9 xfailed.Not covered
origin/main. Work for a pre-release branch, this one included, is reset onto it by hand after the script runs.