Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes go-git repository opening for shared/reference clones that use relative objects/info/alternates paths, so checkpoint sync can resolve commits stored in alternate object directories.
Changes:
- Adds an alternates rewriter that resolves relative alternates against the owning
objectsdirectory. - Applies the rewriter to dot-git/common-git filesystems and nested alternate chains.
- Adds unit, repository-level, strategy, and e2e coverage for relative alternates and Git config isolation.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
cmd/entire/cli/gitrepo/alternates_rewrite.go |
Adds the filesystem wrapper and rewrite helpers for relative alternates. |
cmd/entire/cli/gitrepo/alternates_fs.go |
Rewrites nested alternate files when go-git follows alternate chains. |
cmd/entire/cli/gitrepo/repository.go |
Wraps dot-git and common-git filesystems during repository open. |
cmd/entire/cli/gitrepo/alternates_rewrite_test.go |
Adds unit coverage for alternates rewriting and read limits. |
cmd/entire/cli/gitrepo/repository_test.go |
Adds OpenPath coverage for single, multiple, nested, and linked-worktree relative alternates. |
cmd/entire/cli/testutil/testutil.go |
Expands Git config isolation helpers for tests. |
cmd/entire/cli/strategy/push_common_test.go |
Applies in-process Git config isolation to fetch/rebase tests. |
e2e/tests/alternates_test.go |
Adds an e2e reproduction for checkpoint sync through a relative alternate. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8f14f10. Configure here.
go-git's dotgit.Alternates() strips leading "../" and anchors entries at the filesystem root, so relative objects/info/alternates entries — the shape produced by `git clone --shared`/`--reference` — point at non-existent paths. The pre-push checkpoint sync then fails to resolve alternate-resident commits even though git itself reads them. Wrap both the dotgit and common-git filesystems with an alternates rewriter that resolves relative entries against <root>/objects on read. The rewriter preserves file structure (comments, blanks, absolute entries pass through untouched), caps reads at 4096 bytes, and applies to nested alternate chains via the os-rooted AlternatesFS. Linked worktrees are covered because the wrap applies to the common dir where the alternates file actually lives. Adds unit tests for the rewriter, integration tests for OpenPath across multiple/nested/linked-worktree relative-alternate layouts, and an e2e test reproducing the shared-clone checkpoint sync failure. Tests that shell out to git get GIT_CONFIG_* isolation so they don't pick up host config. Assisted-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Paulo Gomes <paulo@entire.io> Entire-Checkpoint: 6de31b509acf
- Don't fall back to the uncapped original alternates file when our capped read found no relative entry to rewrite. The past-cap content could itself be a relative entry, which go-git would then mangle. readAlternatesContent now reports truncation and rewriteRelative- Alternates returns ok=true on truncation so the caller always serves the capped view. - Filter every inherited GIT_CONFIG_* variable in GitIsolatedEnv and IsolateGitConfigEnv (not just the explicit subset). This includes GIT_CONFIG_PARAMETERS, which can inject `git -c` overrides into child git invocations and would otherwise survive isolation. - Use upsertEnv when building cmd.Env in the alternates e2e test so a parent ENTIRE_TEST_TTY=1 (e.g. from a CI wrapper) cannot shadow the appended ENTIRE_TEST_TTY=0 and put the child into interactive mode. Assisted-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Paulo Gomes <paulo@entire.io> Entire-Checkpoint: 23224dbe8460
Add cases for a file containing only blank lines (should return not ok) and blank lines between two relative alternates (should be preserved). Assisted-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Paulo Gomes <paulo@entire.io> Entire-Checkpoint: 9b750209b4f0
Soph
approved these changes
May 28, 2026
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.

https://entire.io/gh/entireio/cli/trails/445
go-git's dotgit.Alternates() strips leading "../" and anchors entries at the filesystem root, so relative objects/info/alternates entries — the shape produced by
git clone --shared/--reference— point at non-existent paths. The pre-push checkpoint sync then fails to resolve alternate-resident commits even though git itself reads them.Wrap both the dotgit and common-git filesystems with an alternates rewriter that resolves relative entries against /objects on read. The rewriter preserves file structure (comments, blanks, absolute entries pass through untouched), caps reads at 4096 bytes, and applies to nested alternate chains via the os-rooted AlternatesFS. Linked worktrees are covered because the wrap applies to the common dir where the alternates file actually lives.
Adds unit tests for the rewriter, integration tests for OpenPath across multiple/nested/linked-worktree relative-alternate layouts, and an e2e test reproducing the shared-clone checkpoint sync failure. Tests that shell out to git get GIT_CONFIG_* isolation so they don't pick up host config.
Support for Windows confirmed via E2E tests:
Note
Medium Risk
Changes how repositories with alternates are opened for all go-git paths (checkpoint sync, tests using OpenPath); behavior is well-tested but incorrect rewriting could break object resolution for shared or worktree layouts.
Overview
go-git can’t resolve relative
objects/info/alternatesentries (shared/--referenceclones). This PR rewrites those paths on read so checkpoint sync andOpenPathcan load objects from alternate stores.On open, dot-git and common-git billy filesystems are wrapped so
objects/info/alternatesserves in-memory content with relative lines resolved against<git-dir>/objects, matching Git. Comments, blanks, and absolute paths are unchanged; reads are capped at 4KB. The OS-rooted alternates FS applies the same rewrite for nested…/objects/info/alternatesfiles in alternate chains.Tests: unit coverage for the rewriter;
OpenPathintegration for single/multiple/nested relative alternates and linked worktrees; e2e pre-push checkpoint sync with a forced relative alternate.IsolateGitConfigEnvand broaderGIT_CONFIG_*filtering stabilize tests that call git viaos.Environ().Reviewed by Cursor Bugbot for commit 8f14f10. Configure here.