Skip to content

Support modifying stacks across worktrees - #521

Open
skarim wants to merge 3 commits into
skarim/worktrees-distributed-rebase-syncfrom
skarim/worktrees-modify
Open

skarim wants to merge 3 commits into
skarim/worktrees-distributed-rebase-syncfrom
skarim/worktrees-modify

Conversation

@skarim

@skarim skarim commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Lets users restructure a stack with gh stack modify while its branches remain checked out in different worktrees. Building on #529, the interactive editor applies each planned change in the checkout that holds the affected branch.

Functionality and user impact

  • Rename, insert, drop, fold, and reorder across worktrees. Renames and rebases run where the branch is checked out; a fold-down cherry-pick runs where the receiving branch is checked out. Branches not checked out anywhere use the starting worktree.
  • Dropping or folding a layer keeps its underlying branch and worktree. Dropped commits are excluded from the updated stack, including when drops and folds are combined. If the branch chosen after finishing is checked out elsewhere, keep the starting worktree on its preserved branch and report the other path.
  • Resolve and stage conflicts in the reported checkout, then continue or abort from any worktree. Record completed steps and branch commit IDs so continuation does not repeat work and recovery can stop when it finds unrelated changes. Keep recovery records if restoring or saving fails.

Boundary: the starting worktree and other checkouts that will be changed must be clean and available; read-only source worktrees are left alone. Git 2.36+, linear history, an interactive terminal, and no queued PRs remain requirements. Reordering cannot be mixed with drops, folds, inserts, or renames in one session. No automatic stashing or worktree creation/removal is added.

Key areas to review

  • internal/modify/plan.go: compileActions determines final branch names, which branch receives each fold, and which commits to remove before changing Git history. Check the action order and rejection of unsupported combinations.
  • internal/modify/actions.go: runActions, applyRename, applyInsert, and applyFold execute the plan. Focus on the exact commits each fold includes, preserving removed branches, and saving progress after each action.
  • internal/modify/preconditions.go: preflightBranches checks that branches are still in the expected checkouts and those checkouts are ready. On continuation, check other worktrees first; the checkout containing the conflict is expected to have unfinished Git work.
  • internal/modify/apply.go: ApplyPlan, rebaseRemaining, and ContinueApply connect branch edits to the following rebases and resume remaining steps after conflicts, even when the next conflict is in another worktree.
  • internal/modify/recovery.go: startRefMutation, checkPendingHead, unwindState, and restoreCheckout check saved commit IDs before changing branches, undo recorded changes, and restore the starting checkout without taking over another worktree.

Related issues

@skarim
skarim added this pull request to stack #522 September 22, 2026 17:03
@skarim
skarim removed this pull request from stack #522 September 29, 2026 12:50
@skarim
skarim force-pushed the skarim/worktrees-modify branch from f9a47f9 to c088459 Compare September 29, 2026 13:03
@skarim
skarim changed the base branch from skarim/worktrees-support to skarim/worktrees-distributed-rebase-sync September 29, 2026 13:03
@skarim
skarim added this pull request to stack #530 September 29, 2026 13:04
@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

Fold normalization ordering contradicts its new test, and checkout restoration can select the wrong fold receiver.

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

Open (2)
What changed in this PR

Adds distributed worktree support to gh stack modify, including owner-scoped actions, conflict recovery, and documentation.

Changes:

  • Executes stack modifications in each branch’s owning worktree.
  • Persists action progress and strengthens continuation/abort recovery.
  • Adds extensive distributed-worktree tests and documentation.
File Description
.github/​copilot-instructions.md Documents distributed-modify constraints.
AGENTS.md Updates architecture guidance.
README.md Describes cross-worktree modify behavior.
cmd/​modify.go Routes conflicts to recorded owners.
cmd/​modify_test.go Tests command and TUI behavior.
docs/​src/​content/​docs/​getting-started/​quick-start.md Updates quick-start guidance.
docs/​src/​content/​docs/​guides/​modify.md Documents distributed modification and recovery.
docs/​src/​content/​docs/​guides/​workflows.md Updates worktree workflows.
docs/​src/​content/​docs/​reference/​cli.md Updates CLI requirements and behavior.
internal/​modify/​actions.go Implements persisted structural actions.
internal/​modify/​apply.go Coordinates owner-scoped execution and continuation.
internal/​modify/​apply_test.go Adds distributed execution and recovery coverage.
internal/​modify/​plan.go Compiles action targets and execution order.
internal/​modify/​preconditions.go Adds owner validation and targeted preflight.
internal/​modify/​recovery.go Implements distributed rollback and checkout restoration.
internal/​modify/​state.go Persists execution and recovery metadata.
skills/​gh-stack/​SKILL.md Updates agent-facing behavior guidance.
skills/​gh-stack/​references/​troubleshooting.md Updates distributed recovery troubleshooting.

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

Comment on lines +366 to +368
if !aborting {
target = resolveCheckoutBranch(state.OriginalBranch, state.Plan, state.Snapshot, s)
}
Comment thread internal/modify/plan.go
Comment on lines +137 to +138
for i, n := range nodes {
if n.PendingAction == nil || (n.PendingAction.Type != modifyview.ActionFoldDown && n.PendingAction.Type != modifyview.ActionFoldUp) {

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