fix(git_operations): stop -c diff.external= from breaking every diff - #5988
Closed
YellowSnnowmann wants to merge 1 commit into
Closed
fix(git_operations): stop -c diff.external= from breaking every diff#5988YellowSnnowmann wants to merge 1 commit into
-c diff.external= from breaking every diff#5988YellowSnnowmann wants to merge 1 commit into
Conversation
`hardened_git` injected `-c diff.external=` as one of the `NEUTRALISED_CONFIG`
overrides. An empty value does not disable an external diff driver — git
executes the empty string — so every `diff` this tool ran died with:
error: cannot run : No such file or directory
fatal: external diff died, stopping at <file>
That is not hardening; it is an outage that happens to look like one. The
`diff` operation was broken for every repository, with or without config of
its own.
Two things replace it, and together they are strictly stronger than what they
replace:
- `diff.external` is not on `ALLOWED_REPO_CONFIG`, so a repository that sets
it is already refused outright by `first_disallowed_repo_config_key`. That
is the fail-closed guarantee and it was never carried by the `-c` entry.
- `--no-ext-diff` on the `diff` command itself covers what the `-c` entry was
actually reaching for: a key written into the repository in the gap between
that inspection and the command. Verified directly against a repository
whose `diff.external` names a script that touches a marker file — without
the flag the marker appears and the driver's output is used; with it the
diff is correct and the marker never appears.
`git_log` passes `--pretty=format:` and never produces a patch, so it has no
external diff to refuse; `diff` is the only affected operation.
A test pins that `diff.external` is never re-added to `NEUTRALISED_CONFIG`,
since the value that looks correct there is the one that breaks the tool.
Closes tinyhumansai#5979
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueWarning Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice. Comment |
Collaborator
Author
Closed
4 tasks
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.
Closes #5979.
The bug
hardened_gitinjects everyNEUTRALISED_CONFIGentry as a-coverride, and one of them wasdiff.external=. An empty value does not disable an external diff driver — git tries to execute the empty string — so everydiffthis tool ran died with:That is not hardening; it is an outage wearing hardening's clothes.
GitOperationsTool'sdiffoperation is broken onmainfor every repository, with or without config of its own — this is a user-facing break, not only a test failure.Reproduced standalone, no OpenHuman involved:
The fix
diff.externalcannot be neutralised by a-cvalue — there is no value meaning "none". Two things replace it, and together they are strictly stronger than what they replace:diff.externalis not onALLOWED_REPO_CONFIG, so a repository that sets it is refused outright byfirst_disallowed_repo_config_key. That is the fail-closed guarantee, and the-centry never carried it.--no-ext-diffon the command covers what the-centry was actually reaching for: a key written into the repository in the gap between that inspection and the command itself — the race theNEUTRALISED_CONFIGdoc comment describes.Verified directly, against a repository whose
diff.externalnames a script that touches a marker file: without the flag the marker appears and the driver's output is used; with it the diff is correct and the marker never appears.GIT_EXTERNAL_DIFFwas already cleared bysuppress_ambient_git_config, so the env half was never open.git_logpasses--pretty=format:and never produces a patch, so it has no external diff to refuse;diffis the only affected operation.Why it wasn't caught
The coverage lane derives which raw-coverage modules to run from the changed paths, so
tools_network_channels_raw_coverage_e2eonly runs when the diff reaches into that area. It surfaced on #5955 — a PR that touches no git code at all.Test plan
an_ordinary_repository_still_produces_a_diff— the regression: a repository with no config of its own can produce a diffa_repository_naming_an_external_diff_driver_never_gets_it_run— the hardening property still holds; the planted driver is proven to run before it is planted, so a pass means refusal, not an inert fixturediff_external_is_not_neutralised_by_a_config_override— pins that the entry is never re-added, since the value that looks correct there is the one that breaks the tooltools_network_channels_raw_coverage_e2e::git_operations_cover_read_write_markdown_and_safety_rejections— the CI test that exposed this now passescargo clippy(product feature set) clean at-D warnings;cargo fmt --checkcleangit_operations::config_tests🤖 Generated with Claude Code