fix(gitrepo): tolerate negative fetch refspecs when opening repositories#1711
Open
entire[bot] wants to merge 5 commits into
Open
fix(gitrepo): tolerate negative fetch refspecs when opening repositories#1711entire[bot] wants to merge 5 commits into
entire[bot] wants to merge 5 commits into
Conversation
go-git's refspec parser rejects git 2.29+ negative (exclusion) refspecs (fetch = ^refs/...), so every entire command failed to open a repository whose .git/config used them with "malformed refspec, separators are wrong". Wrap the git-directory filesystem so config reads omit negative fetch refspec lines. The on-disk config is never modified (native git still honors the negatives) and all other settings plus positive refspecs are preserved. Closes #778 Co-authored-by: Cursor <cursoragent@cursor.com>
Drive the real entire binary against a repo whose .git/config carries git 2.29+ negative fetch refspecs, asserting the repository opens instead of failing with "malformed refspec" and that the on-disk config is preserved. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes repository opening failures in repos that use Git 2.29+ negative (exclusion) fetch refspecs (fetch = ^refs/...) by sanitizing .git/config reads before go-git parses them, without modifying the on-disk config.
Changes:
- Add a billy filesystem wrapper that filters out negative fetch refspec lines only when go-git reads
config. - Compose the new config-sanitizing wrapper into the central
gitrepoopen path (alongside the existing alternates-rewrite wrapper). - Add unit + integration regression tests reproducing issue #778 end-to-end.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| cmd/entire/cli/gitrepo/repository.go | Composes wrapConfigSanitize into the repository-open filesystem stack. |
| cmd/entire/cli/gitrepo/config_sanitize.go | Implements the config-read sanitizer wrapper and negative-refspec line filter. |
| cmd/entire/cli/gitrepo/config_sanitize_test.go | Adds unit/regression tests ensuring negative refspecs are stripped in-memory while disk config remains unchanged. |
| cmd/entire/cli/integration_test/issue_778_negative_refspecs_e2e_test.go | Adds an integration test that drives the real binary against a repo containing negative refspecs. |
sanitizedConfig returned ("", false) whenever .git/config exceeded
maxConfigReadBytes (1 MiB), causing the caller to fall back to the
raw, unsanitized file. A negative fetch refspec placed past the cap
would then reach go-git's parser unstripped, reintroducing issue #778
for oversized configs.
Mirror the truncation-safe pattern already used by alternatesRewriteFS:
on an over-cap read, discard the trailing line cut off by the cap and
sanitize the visible prefix, returning ok=true even when no negative
refspec is found in that prefix (unseen content past the cap could
still hold one).
sanitizedConfig previously read the config through a 1MiB prefix cap and, once exceeded, silently served that truncated prefix (dropping any remotes/branches/submodules configured past the cutoff, with no indication anything was lost). Raise the cap to a generous 64MiB ceiling that no realistic config will ever hit, and return an explicit error instead of a partial view when it is exceeded, so a pathological config fails loudly rather than silently losing config.
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.
Trail: https://entire.io/gh/entireio/cli/trails/818
What: Repository opening now tolerates git 2.29+ negative (exclusion) fetch refspecs (
fetch = ^refs/...) in.git/config.Why / how it helps: go-git's refspec parser rejects the
^form, so every entire command (enable,doctor, hooks, …) failed on a repo that used negative refspecs:metadata check failed: failed to open repository: … read config: malformed refspec, separators are wrong. Negative refspecs are valid, supported git config (used to keep specific refs out of fetches), so the CLI should honor repos that use them. Fixes #778.How: A filesystem wrapper (
configSanitizeFS, mirroring the existingalternatesRewriteFS) intercepts reads of theconfigfile in the centralgitrepoopen path and drops only the negative fetch refspec lines before go-git parses them. The on-disk config is never modified — native git still honors the negatives — and positive refspecs plus every other setting are preserved. BothOpenand read-onlyOpenFileare intercepted; writes pass straight through.How to review:
config_sanitize.go(the wrapper +sanitizedConfigline filter) and the one-line composition inrepository.go. The regex only matchesfetch = ^…lines; a^anywhere else (e.g. a URL) is left untouched (unit-tested).Testing:
TestOpenPath_ToleratesNegativeRefspecs(realgit init+ negative refspecs): OpenPath now succeeds, the positive refspec survives, the negatives are gone, and the on-disk config is unchanged. Verified it fails without the fix.TestSanitizedConfigunit cases: strips negatives / keeps the rest, no-negatives unchanged,^outside a fetch line preserved, no-^fast path.go test ./cmd/entire/cli/gitrepo/— 34 pass;golangci-lint— 0 issues;gofmtclean;go build ./cmd/entire/...green. Confirmed on the committed tree.Closes #778