Skip to content

fix(gitrepo): tolerate negative fetch refspecs when opening repositories#1711

Open
entire[bot] wants to merge 5 commits into
mainfrom
fix/778-negative-refspecs
Open

fix(gitrepo): tolerate negative fetch refspecs when opening repositories#1711
entire[bot] wants to merge 5 commits into
mainfrom
fix/778-negative-refspecs

Conversation

@entire

@entire entire Bot commented Jul 10, 2026

Copy link
Copy Markdown

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 existing alternatesRewriteFS) intercepts reads of the config file in the central gitrepo open 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. Both Open and read-only OpenFile are intercepted; writes pass straight through.

How to review: config_sanitize.go (the wrapper + sanitizedConfig line filter) and the one-line composition in repository.go. The regex only matches fetch = ^… lines; a ^ anywhere else (e.g. a URL) is left untouched (unit-tested).

Testing:

  • TestOpenPath_ToleratesNegativeRefspecs (real git 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.
  • TestSanitizedConfig unit 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; gofmt clean; go build ./cmd/entire/... green. Confirmed on the committed tree.

Closes #778

suhaanthayyil and others added 2 commits July 10, 2026 17:12
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>
@suhaanthayyil
suhaanthayyil marked this pull request as ready for review July 11, 2026 02:40
@suhaanthayyil
suhaanthayyil requested a review from a team as a code owner July 11, 2026 02:40
Copilot AI review requested due to automatic review settings July 11, 2026 02:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 gitrepo open 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.

Comment thread cmd/entire/cli/gitrepo/config_sanitize.go
Comment thread cmd/entire/cli/gitrepo/config_sanitize.go Outdated
Comment thread cmd/entire/cli/gitrepo/config_sanitize_test.go
Comment thread cmd/entire/cli/gitrepo/config_sanitize_test.go
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

entire CLI commands break in the presence of negative refspecs in git

2 participants