Skip to content

Record why .git/config's uchg tripwire is intentionally absent, so it is not re-added reflexively #304

Description

@twistedmelonman

Summary

~/Developer/dotfiles/.git/config no longer carries the uchg (immutable) flag. Its removal was deliberate and evidence-backed, but nothing in this repo records that. A future session that finds the flag absent has no way to tell "removed on purpose after the underlying bug was fixed" from "never set, or lost somewhere", and the obvious reaction is to put it back.

Filing this so the reasoning outlives the workspace it currently lives in. The evidence sits in a gitignored SDD directory that gets cleaned up.

Why the flag existed

It was a tripwire for #239: tests were contaminating the real checkout's .git/config, blanking core.hooksPath and silently disabling commit-time review. Making the file immutable meant a contaminating write failed loudly instead of corrupting state.

Why it came off

bash/tests/lib/git-env-isolation.sh now clears the git repository-selection variables before any test's first git call, which removes the mechanism the contamination depended on. The tripwire was guarding a hole that had been filled.

What the evidence actually is — including the part that was initially wrong

This matters more than the conclusion, because the first attempt to prove it was a false OK.

First attempt (rejected). The suite was run from a linked worktree via bash <worktree>/bash/tests/run-tests.sh, and no contamination occurred. That proved nothing. Git exports GIT_DIR into a hook's environment only when git itself dispatches the hook; a direct bash script invocation never receives it. So the test was shape-identical to running from the main checkout, and would have passed just as cleanly with the guard deleted entirely.

This was confirmed by measurement, not argument, in an isolated fixture:

  • Case A — direct bash script from inside a linked worktree → GIT_DIR unset
  • Case B — same script invoked by git as a pre-commit hook from that worktree → GIT_DIR=.../worktrees/linked

Second attempt (accepted). The corrected run injects GIT_DIR from the worktree's own resolved admin gitdir (read out of the worktree's .git file), asserts it is non-empty inside the same process immediately before execing the runner, and adds a negative-control probe.

The negative control is the part that makes this proof rather than absence-of-evidence: an unguarded write under that same injected GIT_DIR did land control-probe@example.invalid in the main checkout's config, and was then restored byte-identically. The trap is live, so the guard's pass is not vacuous.

The injection point matches production: .project-hooks/pre-push does exec "${runner_bash}" ".../run-tests.sh", and bash/tests/run-tests.sh calls isolate_git_env. An injected GIT_DIR inherited through that exec is mechanically what git exports when dispatching the real hook from a linked worktree.

Result: 24/24 with GIT_DIR confirmed present, core.hooksPath held at ~/.config/git/hooks throughout, and .git/config byte-identical to a pre-run backup (diff exit 0).

What to do

Something durable in the repo that says the flag is intentionally absent, so it does not get re-added reflexively. Options, roughly in order of preference:

  • A note in the testing docs, or a comment in bash/tests/lib/git-env-isolation.sh next to the dotfiles .git/config was contaminated with test-fixture values; cause unknown #239 explanation already there — that header is where someone investigating this would look first.
  • A test asserting core.hooksPath is non-empty after the suite runs, which pins the property the flag was protecting rather than the flag itself. This is the stronger option: it fails if the guarantee regresses, whereas a comment only informs.

Re-adding uchg is not obviously wrong as defense in depth, but it should be a decision someone makes knowingly, not a reflex triggered by finding it missing.

Verification, if revisiting

ls -lO .git/config                          # flags column should read `-`
git config --get core.hooksPath             # must be non-empty; empty is the #239 failure

An empty core.hooksPath is the exact silent-review-failure mode all of this exists to prevent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions