mirror of
https://github.com/github/gh-stack.git
synced 2026-09-14 20:26:28 +08:00
main
15 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a82dc3ef1d |
Migrate to new Stacks REST API (#177)
* Add stack Number field to local model and schema
The new Stacks REST API exposes a human-facing stack number (shown in the
github.com UI) alongside the internal stack id. Add a Number field to the
stack.Stack model and document it in schema.json so it can be persisted in
the .git/gh-stack file. Purely additive; behavior is unchanged until callers
populate it.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* Cut over stack operations to the public Stacks REST API
Replace the private cli_internal stack endpoints with the new public
Stacks REST API (/repos/{owner}/{repo}/stacks):
- ListStacks / FindStackForPR (?pull_request= filter) / GetStack for reads
- CreateStack, which now returns the created stack including its number
- AddToStack for delta-only appends (there is no full-replace endpoint)
- Unstack for server-driven removal (204 dissolved / 200 partial / 422)
Migrate all callers (checkout, submit, link, sync, unstack, utils) and
drop the client-side unstack eligibility pre-check — the server now
decides which PRs can be unstacked. checkout discovers stacks via the
pull_request filter; submit/link express updates as append-only deltas;
unstack adopts partial-unstack semantics, keeping local tracking when
PRs remain stacked on GitHub.
RemoteStack now carries the stack number, and stack updates resolve a
stack's number from its internal id for stack files that predate the
Number field.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* Remove the personal access token (PAT) limitation
The new Stacks REST API is public, so any user authenticated with the
GitHub CLI (including via a PAT with repo scope) can perform stack
operations once the feature is enabled for their repository. Remove the
PAT detection and the private-preview gating:
- Delete Config.WarnIfPAT / IsPersonalAccessToken and the TokenForHostFn
test hook (internal/config/auth.go is no longer needed).
- Drop the submit pre-flight that aborted on a PAT.
- Rename warnStacksUnavailableOrPAT to warnStacksUnavailable and simplify
it to the "stacked PRs not enabled" message.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* address review comments
|
||
|
|
5975945dfd |
Ignore symlinked pull request templates (#164)
Template discovery in internal/pr read candidate template paths with os.ReadFile, which follows symlinks. A pull request template that is a symlink (for example .github/pull_request_template.md pointing to a file outside the repository) would therefore be read through to its target, and that target's contents would be used as the PR body by `gh stack submit` and `gh stack link`. Reuse cli/cli's githubtemplate package (already a dependency) for template discovery instead of the hand-rolled path list. It is the same code `gh pr create` uses, and it ignores symlinked templates, so only regular template files inside the repository are read. FindTemplate keeps the same signature, so the submit and link callers are unchanged. Two behavior changes come with the switch: - YAML front-matter is stripped from the template, matching `gh pr create`. - Template filename matching is slightly broader; hyphenated and non-.md variants are now recognized. Add tests for FindTemplate and for the `gh stack submit --auto` and `gh stack link` PR-creation flows to confirm symlinked templates are not followed. |
||
|
|
754d190490 |
Fork unmerged branches into new stack (#154)
* Fork unmerged branches into a new stack when the base stack is fully merged
Once every PR that is officially part of a stack on GitHub has been merged
-- especially after the merged branches are deleted upstream -- you can no
longer add to that stack. A new PR on top would target the trunk directly
instead of chaining onto the merged PRs, so the remote stack's "each PR's
base ref is the previous PR's head ref" invariant no longer holds. On the
next `gh stack submit`, the stack update was rejected and surfaced as a
confusing, dead-end warning:
Failed to update stack on GitHub: Pull requests must form a stack,
where each PR's base ref is the previous PR's head ref
`submit` had no handling for this: `syncStack` always sent the full PR list
(including the merged-and-deleted ones), so the API rejected the broken
chain even though the new PRs had already been created with correct bases.
Fork the survivors into a fresh stack instead of failing. After syncing PR
state and before pushing, `runSubmit` now calls `maybeForkFromMergedBase`:
- It triggers only when every PR officially part of the tracked remote
stack (`s.ID`) has merged. Membership is read from the stacks API, so
open PRs that are not part of the remote stack do not count, and -- this
is the key guard -- a normal partial, bottom-up merge (where the remote
stack still lists an open PR) is left completely untouched. A cheap
pre-check (the local stack must have at least one merged branch) avoids
an extra ListStacks call on the common path.
- The local branches are partitioned: those still in the merged remote
stack stay behind; everything else (new branches, plus open PRs that were
never part of that remote stack) is lifted into a brand-new stack rooted
at the original trunk, with an empty remote ID. The bottom survivor is
re-based onto the trunk.
- `runSubmit` continues with the new stack, so the push loop, PR creation,
and `syncStack` all operate on it; the empty ID routes `syncStack` through
the adopt/create path and a fresh stack is created on GitHub.
- The original, fully merged stack is left untouched on GitHub. Locally it
is kept as a record only if at least one of its branches still exists in
the working copy; otherwise it is dropped. No data is lost -- those PRs
are already merged on GitHub.
To restructure the stack file safely, add `StackFile.IndexOfStack`, which
locates a stack by pointer identity so the fork can capture what it needs
before `AddStack`/`RemoveStack` reallocate the underlying slice.
Also soften the partial-merge case that does not fork: when an `UpdateStack`
call fails with the "must form a stack" 422 and the stack still contains
merged branches, report it as an informational note (the unmerged PRs were
pushed and re-based onto the trunk) rather than a scary failure warning.
Scope is limited to `submit`. `add` and `checkout` keep their existing
"refuse and suggest `gh stack init`" behavior on fully merged stacks.
Tests:
- cmd/submit_test.go: TestSubmit_ForksWhenRemoteStackFullyMerged covers both
disposition variants (the old stack is removed when its merged branches
are gone locally, kept when they still exist) and asserts that only the
new branches are pushed, the fork message is printed, a fresh stack is
created, and the local stack file is split into two stacks.
TestSubmit_NoForkWhenRemoteStackHasOpenPR verifies the everyday bottom-up
merge is not forked and that the broken-chain 422 is reported calmly.
TestUpdateStack_BrokenChainAfterMerge checks the calm-vs-warn branch.
- internal/stack/stack_test.go: TestIndexOfStack covers identity lookup and
the not-found case.
Docs: README, the CLI reference, the stacked-PRs guide, the FAQ, and the
agent SKILL.md note that submitting onto a fully merged stack starts a new
stack rooted at the trunk.
* Handle fully merged stacks gracefully in the view and modify TUIs
Merged branches (and their PRs) are not selectable, so once an entire stack
has landed there is nothing to act on -- yet the TUIs did not reflect that:
- `gh stack view` still drew a highlighted cursor on the top branch even
though it could not be selected. Navigation, checkout, and the per-branch
toggles all silently did nothing, with no indication of why.
- `gh stack modify` opened its full editor on a stack with nothing left to
restructure, instead of short-circuiting like `gh stack submit` does when
there is nothing to submit.
Reflect the "nothing actionable" state in both TUIs.
View (internal/tui/stackview/model.go):
- Hide the cursor when every branch is merged. `New` now starts the cursor
at -1 and only lands it on the current or first non-merged branch; when
none exists the cursor stays hidden, so no row is rendered as focused. The
existing `m.cursor >= 0` guards and merged-skipping `moveCursor` already
make every cursor action a no-op in that state, and mouse-wheel scrolling
still works for tall merged stacks.
- Dim the shortcuts that depend on the cursor. `buildHeaderConfig` marks
navigate, commits, files, open PR, and checkout as `Disabled` (rendered
gray via the existing ShortcutEntry.Disabled styling) when all branches
are merged, leaving only `q quit` active.
Modify (cmd/modify.go):
- Short-circuit before opening the TUI. After preconditions pass and PR
state is synced, `runModify` now returns early when the stack is fully
merged, printing "All branches in this stack have been merged" and
pointing at `gh stack init`, exiting cleanly (exit 0) like submit's
"nothing to submit" path. The linearity and merge-queue precondition
checks already skip merged branches, so they do not fire spuriously.
Tests:
- internal/tui/stackview/model_test.go: the cursor is hidden (-1) when all
branches are merged; up/down/enter do not move it or trigger a checkout;
View renders without panicking on a hidden cursor; buildHeaderConfig
disables every cursor-dependent shortcut (and only those) when all merged,
and leaves them all enabled when active branches remain.
- cmd/modify_test.go: runModify short-circuits on a fully merged stack,
printing the message and returning no error without launching the TUI.
|
||
|
|
9b30b7f381 |
Adopt an existing remote stack on submit instead of erroring (#153)
When a stack existed on GitHub but was not recorded in the local tracking
file (`.git/gh-stack`, i.e. `s.ID == ""`) -- for example a stack created
from the web UI or in another clone -- `gh stack submit` blindly called the
create-stack API. The server rejected the request because the PRs were
already stacked, surfacing a confusing, dead-end error:
Could not create stack: Pull requests are already part of a stack.
`syncStack()` only ever consulted the local `s.ID`. When it was empty it
always POSTed to create, and the only handling for the rejection
(`handleCreate422`) parsed the error string and at best printed "up to
date" -- it never imported the remote stack ID, so the local/remote
mismatch was never resolved and recurred on every submit.
Detect and adopt the existing stack before creating one. When `s.ID` is
empty and there are at least two PRs, `syncStack` now lists the
repository's stacks and reconciles, mirroring the patterns already used by
`checkout` and `link`:
- No remote stack contains our PRs -> create a new one (unchanged).
- The remote stack's PRs are all tracked locally (an exact match, or e.g.
two of three already stacked with a third added on top) -> adopt the
remote stack ID into local tracking and PUT the full, ordered PR list,
appending any new PRs to the top. The adopted ID is persisted by the
existing stack.Save in runSubmit.
- The remote stack contains PRs we are not tracking locally -> refuse and
warn rather than silently dropping them, pointing the user to
`gh stack checkout <pr>` to import the full stack first.
- Our PRs are spread across multiple remote stacks (an unresolvable
divergence, since a PR can belong to only one stack) -> warn and skip.
The new logic reuses `findMatchingStack`, `formatPRList`, and `slicesEqual`
from the link command; `syncStack`'s signature is unchanged, and adoption
is best-effort: listing failures degrade to the previous create path and
never fail the submit, since the PRs are already pushed and created.
Also broaden the create-stack 422 fallback (`handleCreate422`) to recognize
the server's "already part of a stack" phrasing in addition to "already
stacked", so that if the stack listing is unavailable the message is still
actionable instead of the raw "Could not create stack" error above.
Tests: six new cases in cmd/submit_test.go cover exact-match adoption (ID
imported, no create/update call), additive two-of-three adoption (update
with the full list), remote-superset refusal, PRs spanning multiple stacks,
the ListStacks-error fallthrough to create, and the broadened fallback
phrasing. Existing syncStack tests are unchanged.
|
||
|
|
b6bcce1bfe |
Add an interactive submit TUI for customizing each PR's title, description, and draft state (#147)
* Add submitview data model and PR draft override plumbing
Introduce the internal/tui/submitview package that will back the new
interactive `gh stack submit` TUI, and wire its per-PR override contract
into the submit command without changing current behavior.
- submitview: BranchState model (NEW/OPEN/DRAFT/QUEUED/MERGED/CLOSED) with
selectability/editability rules, SubmitNode UI state with edit detection,
PRDraft override type, state derivation, title/description prefill, and
state-badge/panel/tab styles.
- submit: refactor ensurePR/createPR to accept an optional per-branch
override map (title/body/draft/include); deselected NEW branches are
pushed but get no PR.
The override map is nil on the --auto / non-interactive path, so the
agent-compat contract is unchanged. Fully unit tested.
* Add single-screen submit TUI
Introduce an interactive, single-screen editor for `gh stack submit`,
built on Bubble Tea and Lip Gloss.
The left panel renders the stack as a connected tree down to the trunk.
Every branch without a PR is included by default; deselect one with its
checkbox or `^x`. Because each PR builds on the branch below it,
deselecting a branch also deselects the ones stacked above it, and
re-including a branch re-includes the ones below it that it depends on.
The cursor uses its own cyan accent so it reads distinctly from the green
new/included color; existing PRs are shown dimmed with a no-entry glyph.
The right panel edits the focused branch's PR in web-create-PR order: a
header with the branch name and an include chip ("Creating PR" /
"Skipped"), the title, a scrollable description (Glamour markdown preview
and $EDITOR escape, with a scrollbar and mouse click-to-position), and a
ready to draft segmented toggle (defaulting to ready). A footer strip
shows the PR progress, the next branch, and the editor hints. Skipping a
branch dims its body; branches that already have a PR show a read-only
card linking to the PR.
It shares the gh-stack header (art, title, stack info, and keyboard
shortcuts) with `gh stack view` and `gh stack modify` for a unified look.
Submit every included PR at once with Ctrl+S. Full keyboard and mouse
support throughout.
* Wire the single-screen submit TUI into `gh stack submit`
Launch the submit editor from `gh stack submit` in interactive terminals,
collecting per-branch PR drafts and applying them in a single batch. In
non-interactive terminals or with --auto, fall back to auto-generated
titles and skip the editor. Update the README and CLI reference to
describe the single-screen flow.
* Use the API PR title/body for existing PRs and fix new-PR defaults
For existing PRs, the submit TUI showed a commit/template-derived draft
instead of the pull request's real title and body. Fetch the actual title
and body and render them in the read-only card:
- open/draft/queued (tracked) and adopted-open PRs now carry title/body
through the existing batch sync (added the fields to the GraphQL queries
and PRDetails — no extra round trips), and
- merged branches (which skip the live refresh) are filled in by a targeted
enrichment step run only when the submit TUI opens.
Also align the new-PR defaults with the non-TUI submit's defaultPRTitleBody:
- Title: the commit subject only when the branch has exactly one commit,
otherwise the humanized branch name (was: the oldest commit's subject even
for multi-commit branches).
- Description: the PR template, else the single commit's body, else empty
(removed the bulleted commit-subject list for multi-commit branches).
* Stop mouse wheel from leaking escape characters into form fields
Scrolling the mouse wheel while a title or description field was focused
could insert stray characters such as "[<65;54;51M" into the field. The
submit TUI ran the Bubble Tea program with WithMouseAllMotion (mode 1003),
which reports an event on every pointer move. During a wheel scroll that
floods the input stream, and under that volume Bubble Tea splits an SGR
mouse escape sequence ("\x1b[<Cb;Cx;Cy(M|m)") across input reads; the
leftover bytes of a partially-parsed sequence are then emitted as key
runes and inserted into the focused text input.
Two changes fix this:
- Switch to WithMouseCellMotion (mode 1002), which reports clicks, drag,
and wheel but not idle pointer motion. That removes the per-move input
flood, so under a real terminal's reads (up to 256 bytes) the only
fragment that still surfaces is a single, clean burst at each wheel
notch boundary. The TUI never used idle-hover for rendering, so
cell-motion loses nothing.
- Drop any leaked fragments before they reach a field. A split SGR mouse
sequence surfaces as an Alt+"[" (the consumed "\x1b[") followed by
body fragments ("<65;54;5", "1M"), or occasionally the whole body in
one run ("[<65;54;51M"). consumeLeakedMouseKey recognises the start,
swallows the body up to its "M"/"m" terminator, and bails out the
moment a rune does not fit an SGR body, so ordinary typing (including
"<", ";", digits, "M") and bracketed pastes are never eaten.
Tests cover every split point of an SGR sequence, single-run tails,
preserved real typing, a stray Alt+"[", bracketed paste, and that wheel
events never modify the focused field. Verified end-to-end by feeding
1,500 wheel sequences through the real parser under terminal-sized reads
and confirming the field stays empty.
* Re-enable mouse tracking after the external editor closes
Opening the description in $EDITOR with ^e and then quitting left the
mouse unresponsive: clicks and wheel scrolling stopped working while
keyboard navigation still did.
The editor is launched with tea.ExecProcess, which releases the terminal
before running the command and calls Bubble Tea's RestoreTerminal when it
returns. RestoreTerminal re-enables the alt-screen, bracketed paste, and
focus reporting, but it does not re-enable mouse tracking. The editor
(e.g. vim) disables mouse reporting on exit, so once control returns to
the TUI the terminal no longer emits mouse events.
Re-arm mouse mode when the editor-finished message arrives by batching
tea.EnableMouseCellMotion with the handler's command. That re-enables
cell-motion and SGR mouse reporting, matching the WithMouseCellMotion
option the program starts with, on every editor-return path (success or
error).
* dead code cleanup
* support mouse input to move cursor in title field
* use textArea for title to support word wrap for long inputs
|
||
|
|
a4485f5298 |
submit: disable auto-merge on existing PRs before adding to stack (#120)
When a user runs `gh stack submit` and an existing PR is discovered for
a branch via `FindPRForBranch`, that PR may have auto-merge enabled.
Auto-merge is incompatible with stacked PRs because the PR would merge
on its own, breaking the stack's base chain.
Previously, the eligibility guard for auto-merge was only in the `link`
command (which blocks such PRs with an error). The `submit` command had
no such check, allowing users to add auto-merge-enabled PRs to a stack
by running `init` followed by `submit`.
This change adds auto-merge detection and automatic disabling in
`submit`'s `ensurePR` function. When an existing PR with auto-merge
enabled is discovered, the CLI disables auto-merge via the
`disablePullRequestAutoMerge` GraphQL mutation and warns the user.
If the disable call fails, submit continues with a warning (non-fatal).
The `link` command retains its stricter behavior of blocking auto-merge
PRs outright, since the user explicitly chose those PRs and can fix
them before retrying.
Changes:
internal/github/github.go:
- Add DisableAutoMerge() method using the
disablePullRequestAutoMerge GraphQL mutation
internal/github/client_interface.go:
- Add DisableAutoMerge(prID string) error to ClientOps interface
internal/github/mock_client.go:
- Add DisableAutoMergeFn field and mock implementation
cmd/submit.go:
- In ensurePR, after discovering an existing PR with auto-merge
enabled, call DisableAutoMerge before proceeding. Warns on
success ("Disabled auto-merge for PR #N (incompatible with
stacked PRs)") and on failure ("failed to disable auto-merge").
cmd/submit_test.go:
- Add TestSubmit_DisablesAutoMergeOnExistingPR: verifies auto-merge
is disabled and warning is shown
- Add TestSubmit_DisableAutoMergeFailure_ContinuesWithWarning:
verifies submit continues even if the disable call fails
- Add TestSubmit_NoAutoMerge_SkipsDisable: verifies DisableAutoMerge
is not called for PRs without auto-merge
|
||
|
|
d235a21a9c |
alert for unsupported auth tokens (#113)
When users authenticate the GitHub CLI with a personal access token
(PAT) instead of OAuth (`gh auth login`), the `cli_internal` stacks
API endpoints return 404. The CLI previously interpreted this as
"Stacked PRs are not enabled for this repository," which is misleading
— the feature may be enabled, but the token type simply cannot access
the internal endpoints.
This is a recurring source of user confusion. The docs already note
that PATs are not supported, but users don't always read them before
hitting the error.
This change adds token-type detection by inspecting the `gh` auth
token prefix:
- `gho_` → OAuth (supported)
- `ghs_` → GitHub App installation token (supported)
- `ghp_` → Classic PAT (NOT supported)
- `github_pat_` → Fine-grained PAT (NOT supported)
When a PAT is detected, the CLI now shows:
⚠ Personal access tokens are not supported by gh stack
Run `gh auth login` to authenticate with OAuth instead.
Instead of the misleading:
⚠ Stacked PRs are not enabled for this repository
Changes:
- Add `internal/config/auth.go` with auth detection methods on Config:
`IsPersonalAccessToken()`, `WarnIfPAT()`, and `RepoHost()`. Uses a
`TokenForHostFn` field on Config for test overrides, following the
same pattern as `GitHubClientOverride`.
- Add a pre-flight PAT check in `cmd/submit.go` before the
`ListStacks` call. If a PAT is detected, the command aborts early
with a clear error instead of making a doomed API call.
- Update all 404 handlers for `cli_internal` endpoints to check the
token type and show the appropriate message:
- `cmd/submit.go` (createNewStack)
- `cmd/link.go` (listStacksSafe, createLink)
- `cmd/checkout.go` (checkoutRemoteStack)
- Add `warnStacksUnavailableOrPAT()` helper in `cmd/utils.go` that
shows the PAT-specific warning when applicable, falling back to the
generic "not enabled" message for non-PAT tokens.
- Add unit tests in `internal/config/auth_test.go` for token prefix
detection and warning output.
- Add integration tests in `cmd/submit_test.go` verifying that both
classic PATs (`ghp_`) and fine-grained PATs (`github_pat_`) trigger
the pre-flight check and abort before any API calls.
- Add `warnStacksUnavailableOrPAT` tests in `cmd/utils_test.go`
verifying correct message selection based on token type.
- Update existing 404 tests to explicitly set an OAuth token so they
continue exercising the ListStacks 404 path.
|
||
|
|
d3be1b577e |
prune merged branches (#94)
* prune merged branches * interactively prompt for prune * delete remote tracking ref too * disable selecting merged branches in TUIs * include full list (including merged PRs) in PUT request to stacks API * add prune to docs * addressing review comments * increment skill file version |
||
|
|
b71b10c268 |
use PR template when opening PRs (#77)
* use pr template when opening prs * add a helper to clearly distinguish between filesystem errors and actual test failures |
||
|
|
13330406ef |
open PRs as draft by default (#76)
* open prs as draft by default * apply suggested docs updates from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
d1e9d14136 |
run fetch before push operations (#75)
* run fetch before push operations * ignore if ref doesn't exist on remote * rm fetch from link * more durable fetch by trying all first and falling back to individual fetches * run fetch before sync |
||
|
|
7a268fc380 |
modify command (#72)
* git primitives for modify cmd * extract reusable TUI parts * modify cmd * recreate stack after modify * add checks to prevent other modifications while modify is applying * modify continue for resuming after resolving conflicts * fix bug with duplicate stack entries after modifying * reuse conflict resolution help msg from rebase * additional confirmation before overwriting stack on remote * fix recreate order of operations Co-authored-by: Copilot <copilot@github.com> * move base commit instead of cherry picking for fold up * check to ensure we aren't left with zero branches * unify and dedupe across view and modify tui * more detailed help instructions Co-authored-by: Copilot <copilot@github.com> * only recommend submit if stack exists on remote Co-authored-by: Copilot <copilot@github.com> * tests for modify tui, apply modifications, submit modifications * refactor submit for regular and pending modifications * rename recover to abort Co-authored-by: Copilot <copilot@github.com> * docs for modify cmd * tui styling updates * updated tui screenshot * addressing review comments * Fix 4 bugs from code review Bug 1: Move RevParseMap error check before using originalRefs. The error from git.RevParseMap() was deferred past iteration of originalRefs, which could panic on a nil map. Bug 2: Differentiate cherry-pick vs rebase conflicts in modify. Cherry-pick conflicts don't save state as 'conflict' phase, so --continue won't work. Now prints --abort-only instructions for cherry-pick conflicts. Bug 3: Unwind now cleans up branches created by renames. After restoring snapshot branches, Unwind deletes renamed branch names that don't belong to the original snapshot. Bug 4: Simplify push message in submit command. Changed from 'Pushing N branches to remote...' to 'Pushing to remote...' since individual branches may fail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix 7 nit issues from code review 11: Add named constants for phase strings (PhaseApplying, PhaseConflict, PhasePendingSubmit) in state.go; replace remaining raw literals in state.go CheckStateGuard. 14: Fix bottomLines comment mismatch — listed 3 items but value is 2. 15: Extract magic number 88 to MinWidthForArt constant in header.go. 16: Remove unused stackview import anchor in model.go — the import is used via types.go where BranchNode is embedded. 17: Simplify CheckStackLinearity parent resolution — ActiveBaseBranch already handles skipping merged branches. 18: Fix rename undo matching any rename — add NewName check so only the specific rename being undone is matched. 20: Add TestUndoRename and TestUndoRename_DoesNotAffectOtherRenames to validate rename undo behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make cherry-pick conflicts recoverable via --continue Previously, cherry-pick conflicts during fold-down operations could only be resolved with --abort. Now they save full conflict state (phase, conflict type, fold branch/target, remaining branches) to the state file, enabling recovery via 'gh stack modify --continue'. Changes: - Add ConflictType field to StateFile (rebase or cherry_pick) - Add FoldBranch/FoldTarget fields for cherry-pick context - Add CherryPickContinue to git package (cherry-pick --continue) - Save cherry-pick conflict state in ApplyPlan with remaining branches - ContinueApply handles both rebase and cherry-pick conflicts - Unified conflict messaging in cmd/modify.go (both types show --continue) - Updated test to verify cherry-pick conflict state is saved correctly * Apply suggestions from code review Co-authored-by: Luke Ghenco <lukeghenco@github.com> Co-authored-by: Sameen Karim <skarim@github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Luke Ghenco <lukeghenco@github.com> |
||
|
|
42e43a47ae |
ignore stale merged/closed PRs for reused branch names (#49)
* ignore stale merged/closed PRs for reused branch names * guard for edge case of deleted PR |
||
|
|
8893d274f2 |
preflight check for stacked PR availability in submit (#44)
* preflight check for stacked prs before submit * close pipe read end in test to avoid FD leak * concise var reuse |
||
|
|
b01754e4a9 | Initial release |