git: open repositories with alternates-aware storage#1268
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes missing-checkpoint behavior in shared clones/worktrees by centralizing git repository opening through a new gitrepo package that is alternates-aware (including nested .git/objects/info/alternates) and worktree-commondir-aware, and by consistently closing go-git repository handles to avoid leaking filesystem resources. It also updates metadata ref advancement logic to preserve local-only checkpoint commits by replaying them onto fetched tips when histories diverge or are disconnected.
Changes:
- Add
cmd/entire/cli/gitrepoto open repositories with alternates-aware storage (and worktreecommondirsupport). - Route repository opens across CLI paths and tests through
gitrepo, and adddefer repo.Close()/test cleanup broadly. - Update
SafelyAdvanceLocalReflogic + tests to replay local-only commits onto fetched targets; add regression tests for alternates-backed objects and disconnected/diverged histories.
Reviewed changes
Copilot reviewed 51 out of 51 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/trail/store.go | Tightens error handling when checking for trails branch existence. |
| cmd/entire/cli/trail_cmd.go | Closes repository handle after opening in trail create. |
| cmd/entire/cli/testutil/testutil.go | Uses gitrepo.OpenPath and closes repos in test helpers. |
| cmd/entire/cli/strategy/session.go | Closes repository handle after opening for session listing. |
| cmd/entire/cli/strategy/safely_advance_local_ref_test.go | Strengthens tests to validate replay behavior and file preservation. |
| cmd/entire/cli/strategy/push_common.go | Closes repos; improves merge-base error handling for disconnected histories. |
| cmd/entire/cli/strategy/push_common_test.go | Adds shared-clone alternates regression test for fetch+rebase path. |
| cmd/entire/cli/strategy/metadata_reconcile.go | Closes repository handle in metadata disconnection warning path. |
| cmd/entire/cli/strategy/manual_commit.go | Refactors checkpoint store creation to use a passed-in repo; closes repo in validation. |
| cmd/entire/cli/strategy/manual_commit_test.go | Closes repo in tests; updates to new checkpoint-store helper signature. |
| cmd/entire/cli/strategy/manual_commit_session.go | Closes repository handles in session-state listing/counting helpers. |
| cmd/entire/cli/strategy/manual_commit_rewind.go | Closes repos; uses repo-scoped checkpoint store; adjusts “no checkpoints” behavior path. |
| cmd/entire/cli/strategy/manual_commit_reset.go | Closes repository handles in reset flows. |
| cmd/entire/cli/strategy/manual_commit_logs.go | Closes repository handles in session info/metadata ref helpers. |
| cmd/entire/cli/strategy/manual_commit_hooks.go | Closes repos in hook paths and removes/adjusts several nolint annotations. |
| cmd/entire/cli/strategy/manual_commit_git.go | Closes repos and uses repo-scoped checkpoint store for save operations. |
| cmd/entire/cli/strategy/manual_commit_condensation.go | Opens/closes repos locally for committed-reader access; uses repo-scoped store. |
| cmd/entire/cli/strategy/generation_repair.go | Closes repository handle during v2 generation repair. |
| cmd/entire/cli/strategy/common.go | Introduces replay-based safe ref advancement; switches OpenRepository to gitrepo.OpenCurrent; closes repos in helpers. |
| cmd/entire/cli/strategy/common_test.go | Adds tests for ref-read errors and shallow/disconnected handling. |
| cmd/entire/cli/strategy/cleanup.go | Closes repos in cleanup listing/deletion paths. |
| cmd/entire/cli/strategy/checkpoint_remote.go | Closes repos; keeps fail-open fetch-if-missing behavior. |
| cmd/entire/cli/strategy/checkpoint_remote_test.go | Adds diverged/disconnected metadata fetch regression tests. |
| cmd/entire/cli/status.go | Switches repo opening to gitrepo.OpenPath and closes the repo. |
| cmd/entire/cli/state.go | Closes repository handles in file-change detection helpers. |
| cmd/entire/cli/setup.go | Ensures repos opened for empty-repo notes are closed. |
| cmd/entire/cli/search_cmd.go | Closes repository handle after opening for search preflight. |
| cmd/entire/cli/rewind.go | Uses gitrepo.OpenCurrent and closes repos in transcript/HEAD helpers. |
| cmd/entire/cli/review/cmd.go | Switches to gitrepo.OpenPath for scope detection and closes repo. |
| cmd/entire/cli/review_helpers.go | Switches to gitrepo.OpenPath and closes repo for head review checkpoint check. |
| cmd/entire/cli/review_context.go | Switches to gitrepo.OpenPath and closes repos for review context rendering. |
| cmd/entire/cli/resume.go | Adds explicit closes for repos opened during metadata-tree fallback attempts. |
| cmd/entire/cli/lifecycle.go | Ensures repos opened for empty-repo checks are closed. |
| cmd/entire/cli/integration_test/testenv.go | Uses gitrepo.OpenPath and closes repos throughout integration test harness helpers. |
| cmd/entire/cli/gitrepo/repository.go | New alternates/worktree-aware repository opener with AlternatesFS wiring. |
| cmd/entire/cli/gitrepo/repository_test.go | Tests reading commits/trees via multiple and nested alternates. |
| cmd/entire/cli/gitrepo/alternates_fs.go | Adds OS-rooted billy filesystem wrapper to support absolute alternates paths. |
| cmd/entire/cli/git_operations.go | Closes repos; adds unshallow extra-args logic for full metadata fetches. |
| cmd/entire/cli/explain.go | Adds lookup Close semantics and ensures repos are closed across explain flows. |
| cmd/entire/cli/explain_export.go | Fixes lookup/repo lifecycle when remote fallback replaces lookups; closes repos from metadata fetch helpers. |
| cmd/entire/cli/doctor.go | Closes repos in doctor “sessions fix” and disconnection checks. |
| cmd/entire/cli/dispatch/mode_local.go | Opens repos via gitrepo.OpenPath and closes them during candidate enumeration. |
| cmd/entire/cli/dispatch/mode_cloud.go | Uses gitrepo.OpenPath and closes repo when deriving repo slug/name. |
| cmd/entire/cli/dispatch_wizard.go | Uses gitrepo.OpenPath and closes repo during repo discovery. |
| cmd/entire/cli/clean.go | Closes repos used for preview and active-session checks. |
| cmd/entire/cli/checkpoint/v2_store.go | Improves ref existence error handling in v2 store ensure logic. |
| cmd/entire/cli/checkpoint/v2_resolve.go | Reorders v2 metadata resolution to prefer full fetch over stale local refs; ensures repos are closed on fallback. |
| cmd/entire/cli/checkpoint/v2_resolve_test.go | Updates test to assert full fetch is attempted before accepting local tree. |
| cmd/entire/cli/checkpoint/committed.go | Uses gitrepo.OpenCurrent and closes repo for session-log lookup; improves sessions-branch ensure error handling. |
| cmd/entire/cli/benchutil/benchutil.go | Registers benchmark repo close via b.Cleanup. |
| cmd/entire/cli/attach.go | Closes repository handle after opening for attach flow. |
Shared clones can store required objects only through .git/objects/info/alternates. Several checkpoint paths opened repositories with plain go-git storage, so local-only checkpoint commits reachable through alternates could look missing. That made metadata rebase and push paths silently skip checkpoint data and leave remote checkpoint branches incomplete. Add a gitrepo package that centralizes repository opening, resolves linked worktree .git/commondir layouts, and wires go-git's AlternatesFS so multiple and nested alternates are readable. Route repository openings across the CLI and shared test harnesses through that package so go-git sees the same object graph everywhere. Also close repository handles after use. Upstream go-git requires callers to close repositories to release filesystem storage resources, so the shared opener documents ownership and call sites now defer Close or register test cleanup. Entire-Checkpoint: 4790d9fad21c
Entire-Checkpoint: f1d32dfdbb0e
|
@cursor review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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 cfc5289. Configure here.

https://entire.io/gh/entireio/cli/trails/426
Shared clones can store required objects only through .git/objects/info/alternates. Several checkpoint paths opened repositories with plain go-git storage, so local-only checkpoint commits reachable through alternates could look missing. That made metadata rebase and push paths silently skip checkpoint data and leave remote checkpoint branches incomplete.
Add a gitrepo package that centralizes repository opening, resolves linked worktree .git/commondir layouts, and wires go-git's AlternatesFS so multiple and nested alternates are readable. Route repository openings across the CLI and shared test harnesses through that package so go-git sees the same object graph everywhere.
Also close repository handles after use. Upstream go-git requires callers to close repositories to release filesystem storage resources, so the shared opener documents ownership and call sites now defer Close or register test cleanup.
Depends on #1251.
Note
Medium Risk
Touches checkpoint metadata fetch/rebase/push and many command paths; wrong alternates or handle lifecycle could still drop local checkpoint data or leak resources, but behavior is covered by new alternates and shared-clone tests.
Overview
Introduces
gitrepo(OpenCurrent/OpenPath) so go-git opens repos with object alternates support (linked worktrees,commondir, OS-rootedAlternatesFS), and refuses a silentPlainOpenfallback when alternates are configured.strategy.OpenRepositoryand most CLI, dispatch, review, and test paths now use this opener instead of ad hocPlainOpen/PlainOpenWithOptions.Call sites own and close repository handles (
defer repo.Close(), test cleanups, and extra closes when metadata fetch returns a fresher repo or explain swaps lookups). Manual-commit drops the cached checkpoint store and buildsGitStore/ committed readers from an already-open repo per operation.Adds tests for multi-alternate reads and a shared-clone metadata rebase scenario where local-only commits live only via alternates.
Reviewed by Cursor Bugbot for commit cfc5289. Configure here.