Skip to content

Stop stowing Claude Code's settings.json - #7

Merged
jpmontez merged 1 commit into
mainfrom
untrack-claude-settings
Sep 9, 2026
Merged

jpmontez merged 1 commit into
mainfrom
untrack-claude-settings

Conversation

@jpmontez

@jpmontez jpmontez commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Reverts the machinery from #6. Keeps its **/.claude/.cc-writes/ ignore.

Why

#6 made git status clean, but the price was out of proportion to what tracking that file actually buys.

Cost: 124 lines across 8 files — a Python clean filter, a .gitattributes entry, per-clone git config and per-clone index state that bootstrap.sh had to install and doctor.sh had to verify, two CLAUDE.md caveats — plus a skip-worktree flag that aborts any checkout touching the file. It broke the merge of #6 itself, the day it landed:

error: Your local changes to the following files would be overwritten by checkout:
	claude/.claude/settings.json

Benefit: five keys, changed four times in five months. Four of them Claude Code writes itself — enabledPlugins and extraKnownMarketplaces on plugin install, statusLine from /statusline, hooks from the settings skill. Only permissions.deny was hand-written, and it's eleven lines.

The structural point: settings.json is app-owned state that happens to contain some config, not config that happens to live in an app's directory. Stow is for files we own.

What changes

  • claude/.claude/settings.json leaves the stow package; ~/.claude/settings.json is now a plain file Claude Code owns outright.
  • The package path is ignored in the repo's own .gitignore, so an errant stow --adopt can't pull it back in. (Deliberately not in the stowed global ignore — that would hide project-level .claude/settings.json in every repo, which is meant to be committed.)
  • claude-settings-clean.py, .gitattributes, and the bootstrap.sh/doctor.sh/lib.sh/CLAUDE.md wiring are gone.
  • claude/.claude/statusline.sh stays stowed — Claude Code only reads it.

Verification

Live settings preserved through the unstow (all 9 keys, model: opus). ./doctor.sh green, claude stow package included. shellcheck bootstrap.sh doctor.sh lib.sh macos/*.sh clean. No claude-settings git config or skip-worktree bit left on the clone.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AEPYeZgMsmFPVBbRvkFtM2

Tracking that file cost 124 lines across 8 files — a clean filter, a
.gitattributes entry, per-clone git config and index state that bootstrap.sh
had to install and doctor.sh had to verify — plus a skip-worktree flag that
aborts any checkout touching the file. It broke a merge the day it landed.

What that bought: five keys that changed four times in five months, four of
which Claude Code writes itself (enabledPlugins and extraKnownMarketplaces on
plugin install, statusLine from /statusline, hooks from the settings skill).
Only permissions.deny was hand-written, and it's eleven lines.

The file is app-owned state that happens to contain some config, not config
that happens to live in an app's directory — stow is for files we own. Leave
it to Claude Code as a plain ~/.claude/settings.json and ignore the package
path so an errant `stow --adopt` can't pull it back in.

statusline.sh stays stowed: Claude Code only reads it.

Reverts the machinery from a268ac8, keeping its **/.claude/.cc-writes/ ignore.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AEPYeZgMsmFPVBbRvkFtM2
@jpmontez
jpmontez merged commit 6484962 into main Sep 9, 2026
2 checks passed
@jpmontez
jpmontez deleted the untrack-claude-settings branch September 9, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant