Skip to content

Share stack tracking across Git worktrees - #528

Open
skarim wants to merge 2 commits into
skarim/worktrees-atomic-storagefrom
skarim/worktrees-shared-tracking
Open

skarim wants to merge 2 commits into
skarim/worktrees-atomic-storagefrom
skarim/worktrees-shared-tracking

Conversation

@skarim

@skarim skarim commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Makes stack tracking belong to the repository, not the directory where init ran. Worktrees can hold independent stacks or different branches of the same stack without losing tracking information when a checkout is removed.

Functionality and user impact

  • All commands read and save <common-dir>/gh-stack. Older tracking files are combined automatically when their definitions agree or describe separate stacks. Backups are preserved; conflicting definitions stop with guidance instead of choosing one.
  • init and add can adopt a branch checked out elsewhere without switching either checkout. Commit/stage shortcuts cannot target another worktree. Navigation reports that branch's location; --print-path prints it, or checks out an available branch locally before printing the current path.
  • Allow only one gh-stack command to change the clone at a time, while keeping read-only views available. Recovery records identify the stack and starting worktree; submitting one stack cannot clear another stack's pending modify record.

Boundary: rebase/sync still refuse stacks with member branches—or a trunk they would update—checked out elsewhere. Migration may happen before that refusal, and rebase recovery must run where it started. #529 enables cross-worktree rebase/sync; #521 adds distributed modify. Requires Git 2.36+, with no automatic stashing or worktree creation/removal.

Key areas to review

  • cmd/worktree_utils.go: stackStateDir, beginStackMutation, and mutationStateDir choose the shared catalog and lock the command before changes begin. Older interrupted operations must keep using the catalog they started with.
  • cmd/worktree_utils.go: foreignWorktreePath / checkoutWorktreeBranch locate branches without taking over another checkout. Follow their callers in cmd/init.go and cmd/add.go to see when adoption changes only tracking information.
  • cmd/utils.go: preflightSyncReconciliation and requireLocalBranches check remotely added branches before creating branches or changing stack membership. Choosing a stack must not switch checkouts before these checks.
  • cmd/rebase.go: requireRebaseOrigin, rebaseStackFromState, and loadRebaseState ensure recovery uses the correct stack and checkout. origin-only marks operations that need this version's recovery behavior.
  • internal/modify/state.go, recovery.go, and cmd/submit.go: MatchesStack, unwindState, and handlePendingModify match the actual stack, not its position in a list, and keep recovery records when restoring or submitting fails.

Related issues

Part 3 of the 4-PR split of #520

@skarim
skarim added this pull request to stack #530 September 28, 2026 17:20
@skarim
skarim force-pushed the skarim/worktrees-shared-tracking branch from c413105 to 4c1661f Compare September 28, 2026 21:37
@skarim
skarim marked this pull request as ready for review September 29, 2026 16:28
Copilot AI balanced review requested due to automatic review settings September 29, 2026 16:28

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.

Copilot review overview

🟡 Changes recommended

Pending one-layer submissions can remain permanently blocked, and modify continuation can falsely accept a missing rebase.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Moves stack tracking to repository-wide shared state so linked worktrees can safely share catalogs, navigation, locking, and recovery.

Changes:

  • Adds conservative legacy-catalog migration and clone-wide mutation locking.
  • Adds worktree-aware adoption, navigation, and --print-path.
  • Adds ownership preflight and shared recovery for rebase, sync, and modify.
File Description
.github/​copilot-instructions.md Documents shared-state architecture.
AGENTS.md Updates contributor guidance.
README.md Documents worktree support.
cmd/​add.go Supports foreign-owned branch adoption.
cmd/​add_test.go Tests worktree-aware add behavior.
cmd/​checkout.go Adds path-mode checkout.
cmd/​checkout_test.go Tests checkout ownership and paths.
cmd/​init.go Supports adopting branches across worktrees.
cmd/​init_test.go Tests cross-worktree initialization.
cmd/​link.go Coordinates link mutations.
cmd/​link_test.go Tests link locking.
cmd/​merge.go Uses shared mutation state.
cmd/​merge_test.go Tests merge coordination.
cmd/​modify.go Adds ownership and recovery preflight.
cmd/​modify_test.go Tests distributed-stack rejection.
cmd/​navigate.go Adds worktree-aware path navigation.
cmd/​navigate_test.go Tests navigation paths and ownership.
cmd/​push.go Coordinates push mutations.
cmd/​rebase.go Adds origin-bound shared recovery.
cmd/​rebase_test.go Tests rebase ownership and recovery.
cmd/​submit.go Matches pending recovery to stacks.
cmd/​submit_test.go Tests modify/submit recovery integration.
cmd/​switch.go Adds path-aware switching.
cmd/​switch_test.go Tests worktree-aware switching.
cmd/​sync.go Adds reconciliation ownership preflight.
cmd/​sync_test.go Tests sync worktree boundaries.
cmd/​trunk.go Adds trunk path navigation.
cmd/​unstack.go Uses shared catalogs and locking.
cmd/​unstack_test.go Tests shared-state unstack behavior.
cmd/​utils.go Centralizes shared stack resolution.
cmd/​utils_test.go Tests migration and locking helpers.
cmd/​view.go Reads shared catalogs safely.
cmd/​view_test.go Tests shared-state views.
cmd/​worktree_utils.go Implements state routing and ownership lookup.
docs/​src/​content/​docs/​getting-started/​quick-start.md Updates prerequisites.
docs/​src/​content/​docs/​guides/​modify.md Documents modify limitations.
docs/​src/​content/​docs/​guides/​workflows.md Documents worktree workflows.
docs/​src/​content/​docs/​reference/​cli.md Updates CLI behavior.
internal/​config/​config.go Adds explicit non-interactive mode.
internal/​git/​mock_ops.go Extends Git test doubles.
internal/​modify/​apply.go Adds context-tracked continuation.
internal/​modify/​apply_test.go Tests modify recovery behavior.
internal/​modify/​preconditions.go Rejects unsupported distributed modifies.
internal/​modify/​recovery.go Adds conservative shared recovery.
internal/​modify/​state.go Records and matches stack identity.
internal/​stack/​lock.go Adds clone-wide operation locking.
internal/​stack/​migration.go Consolidates legacy catalogs safely.
internal/​stack/​stack.go Supports shared catalog persistence.
internal/​worktree/​context.go Tracks worktree-owned mutations.
internal/​worktree/​context_test.go Tests mutation tracking and restoration.
skills/​gh-stack/​SKILL.md Updates agent worktree guidance.
skills/​gh-stack/​references/​commands.md Documents command behavior.
skills/​gh-stack/​references/​troubleshooting.md Documents migration and recovery.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/modify/apply.go Outdated
Comment on lines +897 to +903
if ops.IsRebaseInProgress() {
if err := ops.RebaseContinue(git.RebaseOpts{}); err != nil {
return fmt.Errorf("rebase continue failed in %s — resolve remaining conflicts and try again: %w", ctx.Origin.Path, err)
}
}
if err := ctx.Record(state.ConflictBranch); err != nil {
return err
Comment thread cmd/submit.go
Comment on lines +264 to +265
if stackSynced {
if err := clearPendingModifyState(cfg, s, gitDir); err != nil {
@skarim
skarim force-pushed the skarim/worktrees-shared-tracking branch from 4c1661f to 7286fc2 Compare September 29, 2026 22:47
@skarim
skarim force-pushed the skarim/worktrees-shared-tracking branch from 7286fc2 to b83f71a Compare September 29, 2026 23:14

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants