What
Decide whether the git config under ~/.config/git/config should be managed as a single declarative chezmoi template (.tmpl), or kept as the current additive imperative scripts.
This is a follow-up to the per-location identity work (includeIf) landed in:
private_dot_config/git/personal.inc (declarative — personal identity)
run_onchange_after_10-git-identity.sh (imperative — default identity + includeIf directives)
Why (the crux)
~/.config/git/config is written by three independent sources today:
run_once_before_00-initial-setup.sh — base settings (pager, merge, push, lfs, rerere…), one-time, via git config --global
gh auth — the [credential "https://github.com"] / gist helper blocks, at runtime (not chezmoi)
run_onchange_after_10-git-identity.sh — default FVH identity + four includeIf overrides
Because gh co-owns the file at runtime, a static .tmpl (which is authoritative for the whole file) forces a decision about the gh credential helper: bake it into the template (chezmoi owns gh's territory, incl. the macOS-only /opt/homebrew/bin/gh path), or omit it and have chezmoi apply delete it → breaks auth. This is the runtime-drift trap from ~/.claude/rules/chezmoi-conventions.md.
Options
A. Keep imperative run_onchange (current state)
- Additive: only writes the keys it owns; never rewrites the whole file.
- Drift-immune by construction; leaves gh's helper + ad-hoc
git config --global untouched.
- Consistent with the existing
run_once pattern.
B. Full declarative template consolidation
- One
private_dot_config/git/config.tmpl = base settings + identity + includeIf + gh helper (path via {{ if eq .chezmoi.os "darwin" }}).
- Delete the
git config --global block from run_once_before_00.
- Delete
run_onchange_after_10-git-identity.sh.
- One-time cost: removing the run_once git block changes that script's hash → re-runs the heavy run_once (nvim Lazy sync, Mason, pre-commit install) once.
C. modify_ script (jq-style merge)
- The idiomatic chezmoi answer for runtime-mutated files — but git config is INI, not JSON, so there's no clean merge primitive. More complex than A or B. Not recommended.
Comparison
|
A: imperative run_onchange |
B: static .tmpl |
| Readability |
scattered across 2 scripts; includeIf.gitdir:….path key-mangling is ugly |
one file, natural [includeIf "…"] blocks |
chezmoi diff |
shows script text, not resulting config |
shows real config content diffs |
| gh credential helper |
untouched (additive) |
must bake in (+ darwin conditional) or it gets deleted |
Ad-hoc git config --global |
preserved |
clobbered on next apply |
| Cross-platform |
identity/includeIf already portable |
handles macOS-only gh path via conditional |
| Consolidation cost |
none |
forces one heavy run_once re-run |
| Drift-immune by construction |
yes |
no (only as stable as gh's behavior) |
Decision factors
- The gh-helper drift risk is low in practice — gh writes it once and leaves it. So B is defensible, just a bigger/more opinionated move than the problem strictly requires.
- Lean A if keeping gh's credential setup as gh's territory and avoiding any clobber risk matters more than single-file readability.
- Lean B if one readable source of truth for all git config is the priority, and chezmoi owning the gh helper line is acceptable.
Recommendation
Keep A for now (additive is the correct response to a gh-co-owned file). Revisit B as a deliberate consolidation if/when the scattered-config readability becomes a real annoyance.
Acceptance criteria
Reference
~/.claude/rules/chezmoi-conventions.md — Runtime Drift + modify_ guidance
- git
includeIf / gitdir: docs
What
Decide whether the git config under
~/.config/git/configshould be managed as a single declarative chezmoi template (.tmpl), or kept as the current additive imperative scripts.This is a follow-up to the per-location identity work (
includeIf) landed in:private_dot_config/git/personal.inc(declarative — personal identity)run_onchange_after_10-git-identity.sh(imperative — default identity +includeIfdirectives)Why (the crux)
~/.config/git/configis written by three independent sources today:run_once_before_00-initial-setup.sh— base settings (pager, merge, push, lfs, rerere…), one-time, viagit config --globalgh auth— the[credential "https://github.com"]/ gist helper blocks, at runtime (not chezmoi)run_onchange_after_10-git-identity.sh— default FVH identity + fourincludeIfoverridesBecause
ghco-owns the file at runtime, a static.tmpl(which is authoritative for the whole file) forces a decision about the gh credential helper: bake it into the template (chezmoi owns gh's territory, incl. the macOS-only/opt/homebrew/bin/ghpath), or omit it and havechezmoi applydelete it → breaks auth. This is the runtime-drift trap from~/.claude/rules/chezmoi-conventions.md.Options
A. Keep imperative
run_onchange(current state)git config --globaluntouched.run_oncepattern.B. Full declarative template consolidation
private_dot_config/git/config.tmpl= base settings + identity +includeIf+ gh helper (path via{{ if eq .chezmoi.os "darwin" }}).git config --globalblock fromrun_once_before_00.run_onchange_after_10-git-identity.sh.C. modify_ script (jq-style merge)
Comparison
includeIf.gitdir:….pathkey-mangling is ugly[includeIf "…"]blockschezmoi diffgit config --globalDecision factors
Recommendation
Keep A for now (additive is the correct response to a gh-co-owned file). Revisit B as a deliberate consolidation if/when the scattered-config readability becomes a real annoyance.
Acceptance criteria
config.tmplfaithfully reproduces current content incl. gh helper, run_once git block +run_onchangeremoved,chezmoi diffclean after apply, identity verified per-locationReference
~/.claude/rules/chezmoi-conventions.md— Runtime Drift + modify_ guidanceincludeIf/gitdir:docs