`entire disable` does not reach linked worktrees: settings.local.json is per worktree, so a new `git worktree add` comes back enabled
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 475
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 178
Description
Problem or use case
We roll Entire out per repository with a committed .entire/settings.json ("enabled": true) and let individual developers opt out with entire disable. That writes "enabled": false to .entire/settings.local.json, which is gitignored — so it exists only in the worktree it was written in.
Anyone who works with linked worktrees (git worktree add, or agents such as Claude Code that create worktrees on their own) gets re-enabled every time a worktree is created: the new checkout carries only the committed settings.json, settings.Load finds no local override, and every agent hook and git hook starts recording again. The developer has to notice and run entire disable in each worktree.
Reproduced on 0.10.2 and current main:
tmp=$(mktemp -d)
git init -q -b main "$tmp/main" && cd "$tmp/main"
mkdir .entire && printf '{"enabled": true}\n' > .entire/settings.json
printf 'settings.local.json\n' > .entire/.gitignore
git add -A && git commit -qm init
entire disable # -> Entire is now disabled (.entire/settings.local.json).
git worktree add -q "$tmp/wt" -b feature
cd "$tmp/wt" && entire status --json
# {"enabled":true, ...} <- expected "enabled":false
What we checked before filing:
- Clone preferences (
.git/entire/preferences.json) already live in the git common dir so that "multiple worktrees of the same clone see the same preferences", but they carry only review/trails keys, notenabled. - The docs mention a global
~/.config/entire/settings.json;settings.Loadhas no such layer, and an"enabled": falsethere (also viaENTIRE_CONFIG_DIR) has no effect. - There is no environment variable that disables Entire.
- A
settings.local.jsonsymlinked to a file outside.entireis refused (path escapes from parent), so a per-developer shared file is not a workaround either. - No existing issue covers this; #2020 is the closest (Codex hooks installed per worktree) and #645 (stealth mode) is adjacent but a different ask.
Desired behavior
$ entire disable
Entire is now disabled (.entire/settings.local.json).
$ git worktree add ../wt -b feature && cd ../wt
$ entire status
○ Disabled · branch feature
A personal opt-out made in one worktree applies to every worktree of that clone, without touching the committed settings.json and without a per-worktree step.
Proposed solution
Mirror the local-scope enabled flag into clone preferences, which is the layer designed to span worktrees:
ClonePreferencesgainsenabled *bool;applyClonePreferencesapplies it, so the merge order becomessettings.json→ clone preferences →settings.local.json(the local file still wins, as documented).entire disable/entire enable(local scope) write the flag to bothsettings.local.json(unchanged, keepsIsSetUpAnyand older binaries working) and.git/entire/preferences.json.entire enable --projectre-syncs the mirror only when it was set — the same rule the project → local sync already follows — so a clone that never made a personal choice keeps the committed file as its only source of truth.- The "already enabled" short-circuit in
runEnableOnConfiguredRepotreats a clone-widefalseas an explicit local disable, soentire enablecan recover a worktree whose own local file saystrue. entire status --detailedshows aClone · enabled|disabledline between Project and Local.
Known edge: a worktree that carries its own settings.local.json with "enabled": false keeps that answer until entire enable runs there, because the local file is the most specific layer. That matches today's layering and only affects worktrees that were disabled individually before this change.
I have this implemented with unit tests (including a linked-worktree test) and can open a PR once the direction is agreed.
Alternatives or workarounds
We currently ship a post-checkout git hook in the repository (core.hooksPath=.githooks) that copies the main worktree's .entire/settings.local.json into a freshly created worktree (git worktree add runs post-checkout with a zero previous HEAD from inside the new worktree). It works, but it is repo-specific plumbing every team would have to rediscover, and it only helps repositories that already manage hooks this way.
Other options considered: a user-level enabled (would need a new global settings layer and would still lose to a committed "enabled": true under "more specific wins"), an ENTIRE_DISABLED environment variable (per shell, not per clone), and removing entire from PATH (the SessionStart hook then prints an install warning on every session).
CLI version: 0.10.2 (macOS, arm64); reproduced against main at 61dac01. Go 1.26.6.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with settings.Load, ClonePreferences, and applyClonePreferences to trace the settings merge order and shared worktree preferences. Then inspect entire enable/disable, enable --project, status --detailed, and runEnableOnConfiguredRepo, and run the existing unit tests including the linked-worktree case. Done means a local disable applies to new worktrees while local settings still take precedence.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, go
- Domain
- cli, developer-experience
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100