Skip to content

feat: add worktree management with per-worktree trunks#1250

Open
ed-irl wants to merge 4 commits into
ed-irl/scriptrunfrom
ed-irl/restack-auto-resolve
Open

feat: add worktree management with per-worktree trunks#1250
ed-irl wants to merge 4 commits into
ed-irl/scriptrunfrom
ed-irl/restack-auto-resolve

Conversation

@ed-irl

@ed-irl ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Adds gs worktree create and gs worktree list, plus the per-worktree trunk machinery they rely on, and worktree-aware filtering for log and repo restack.

Per-worktree trunks:

  • A worktree may register a local trunk branch that tracks the same
    remote ref as the canonical trunk, so sync and restack in different
    worktrees never contend on a single shared trunk checkout.
  • state.Store persists the registry under a new optional
    worktree-trunks key (missing key = no worktree trunks, so old
    repos and binaries are unaffected). New Store methods: IsTrunk,
    TrunkFor, WorktreeTrunks, Register/UnregisterWorktreeTrunk.
  • Trunk checks throughout state and the branch graph go through
    IsTrunk / isTrunk, so every registered worktree trunk is a graph
    root: traversals (Bottom, Downstack) stop at it and it can be a
    base but not itself tracked.

Commands:

  • gs worktree create <path> creates a Git worktree and, by default,
    a per-worktree trunk named after the directory (or --trunk),
    tracking the canonical trunk's remote ref. -b stacks a tracked
    branch on it; --no-trunk keeps the legacy detached-HEAD behavior.
  • gs worktree list shows each worktree, its checked-out branch, and
    its stack.
  • git.Repository gains WorktreeAdd.

Worktree-aware filtering:

  • BranchGraph.StacksInWorktree yields the full stacks that have any
    branch checked out in a given worktree.
  • log short -w/--worktree filters the listing to the current
    worktree's stacks; repo restack -w/--worktree restacks only those
    stacks. List and sync render and pull against the worktree's own
    trunk via TrunkFor.

Tests:

  • Unit tests for the worktree-trunk registry (persistence, reopen,
    graph-root semantics, canonical-trunk rejection) and for
    worktree-trunk traversal in the branch graph.
  • Script tests: worktree create/list, log/repo-restack -w filtering,
    and branch create/restack when trunk is checked out elsewhere.

@ed-irl

ed-irl commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

@ed-irl ed-irl force-pushed the ed-irl/scriptrun branch from 3e9d081 to 1373b7f Compare June 13, 2026 13:39
@ed-irl ed-irl force-pushed the ed-irl/restack-auto-resolve branch from cb2d78c to a4ba721 Compare June 13, 2026 13:39
@ed-irl ed-irl force-pushed the ed-irl/scriptrun branch from 1373b7f to 4cbacbc Compare June 15, 2026 09:52
@ed-irl ed-irl force-pushed the ed-irl/restack-auto-resolve branch from a4ba721 to f05db8b Compare June 15, 2026 09:53
@ed-irl ed-irl force-pushed the ed-irl/scriptrun branch from 4cbacbc to f700687 Compare June 19, 2026 01:01
@ed-irl ed-irl changed the title restack: AI-driven auto-resolve for rebase conflicts feat: add worktree management with per-worktree trunks Jun 19, 2026
@ed-irl ed-irl force-pushed the ed-irl/restack-auto-resolve branch from 9344b53 to 9dc799e Compare June 19, 2026 01:05
ed-irl and others added 3 commits June 23, 2026 11:43
Adds an auto-resolve path for restack-flavored rebase conflicts.
When configured and enabled, git-spice invokes a user-supplied
script on every rebase conflict and, if the script reports the
conflict resolved, stages the files and continues the rebase
without intervention.

Shared with the rest of git-spice's script-driven features via the
protocol surface on ed-irl/scriptrun:

  - Uses scriptrun.ResolveResponse for the JSON output schema and
    scriptrun.QAPair for resolution-file entries -- no duplicated
    types.
  - Passes the shared GS_OPERATION / GS_BRANCH / GS_BASE env via
    scriptrun.EnvFor. Operation is derived from Request.ContinueCommand
    so each restack flavour reports its own value (branch-restack,
    upstack-restack, downstack-restack, stack-restack, repo-restack).
  - Iteration cap reads spice.scriptResolve.maxIterations
    (default 10) via Handler.MaxResolveIterations, replacing the
    previously private constant. main.go wires it through.
  - Resolution file lives at .spice/resolutions/restack.json under
    spicedir; the old .spice_resolution.json root-level path is
    gone.
  - Per-protocol details (env contract, JSON schema, persistence,
    iteration cap, fall-through) are documented once in
    doc/src/guide/scripts.md; doc/src/guide/restack-auto-resolve.md
    is now a thin page that defers there and only documents
    restack-specific UX (Claude Code recipe, the
    GS_OPERATION values restack uses, the resolution-file key
    layout).

CLI:

  - All restack flavours (gs branch/upstack/downstack/stack/repo
    restack) accept --auto-resolve / --no-auto-resolve, with the
    default coming from spice.restack.autoResolve.
  - The resolver is configured via spice.restack.resolver (script
    body).

Tests:

  - Existing success / disabled scripts updated to assert the new
    .spice/resolutions/restack.json path.
  - Six new script tests cover the protocol surfaces and bring
    restack to parity with the integration-auto-resolve coverage:
    assumptions, invalid_output, unresolved_no_questions,
    iteration_cap (configurable via spice.scriptResolve.maxIterations),
    persists_across_restacks, and env (GS_OPERATION / GS_BRANCH /
    GS_BASE contract).
When --auto-resolve was requested but spice.restack.resolver was not
set, the conflict silently fell through to manual resolution with no
indication the flag was ignored. Emit a warning pointing at the config
key instead.
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.

1 participant