Skip to content

feat: use GitHub's native stacked PRs where enabled#14840

Open
krlvi wants to merge 1 commit into
masterfrom
github-native-stacks
Open

feat: use GitHub's native stacked PRs where enabled#14840
krlvi wants to merge 1 commit into
masterfrom
github-native-stacks

Conversation

@krlvi

@krlvi krlvi commented Jul 17, 2026

Copy link
Copy Markdown
Member

GitHub is rolling out native stacked pull requests as a per-repository preview. Its model matches ours exactly — each PR targets the branch of the PR below it — so the PRs GitButler publishes can be registered as a stack as-is.

What changed

  • New but_github::stacks module wrapping the stacks REST endpoints: lookup (find the stack containing a PR) and ensure (create a stack, or append missing members on top).
  • Detection is a side effect of the lookup: the endpoints 404 on repositories without the preview, and negative results are cached in-process so repeated syncs don't re-probe.
  • sync_reviews is the single decision point. On a GitHub repo with the feature enabled it registers the stack natively and removes description footers (GitHub renders the stack itself, including any footers left from before the repo was enabled). Everywhere else — GitLab, Bitbucket, forks (cross-fork stacks are unsupported), non-enabled repos — behavior is unchanged.
  • Stack registration is best-effort: a failed create/add logs a warning and never fails the publish or push that triggered it.

Decisions

  • Each sync_reviews batch is now explicitly one stack ordered bottom-to-top; the post-push target reconciliation syncs per stack accordingly.
  • The desktop's TS footer writers were deleted rather than taught about the new API: prFooter.ts now routes through the existing update_review_footers command, continuing the migration of forge logic to the Rust side. Command signatures are unchanged, so no SDK regeneration.
  • The shared footer decision was folded into one FooterSync mode + helper, which also deduplicates the previously triplicated body-update block across the three forge arms.

Not included (deferred): unstacking on tear-off/reorder (the API can only dissolve a stack, not remove a single PR), surfacing native-stack state in the UI, and a "merge whole stack" action.

Copilot AI review requested due to automatic review settings July 17, 2026 10:51
@github-actions github-actions Bot added rust Pull requests that update Rust code @gitbutler/desktop CLI The command-line program `but` labels Jul 17, 2026
@krlvi
krlvi force-pushed the github-native-stacks branch from 9f7d0d2 to f7d3c07 Compare July 17, 2026 10:52

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.

Pull request overview

Adds support for GitHub’s preview “native stacked pull requests” by detecting availability per repo and registering GitButler-published PR chains as GitHub stacks when possible, while keeping existing footer-based behavior for other forges and unsupported repos.

Changes:

  • Introduces a but_github::stacks module to look up and (best-effort) create/extend native stacks on GitHub.
  • Makes but_forge::sync_reviews operate on a single bottom-to-top stack batch, removing/writing footers based on native-stack availability and handling fork-headed PRs.
  • Routes desktop footer updates through the existing backend command (update_review_footers) and adjusts target reconciliation to sync per stack.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/but/src/command/legacy/push.rs Reconciles review target branches by syncing each stack as its own sync_reviews batch.
crates/but-github/src/stacks.rs Adds GitHub native stacks REST wrapper (lookup, ensure) plus negative caching.
crates/but-github/src/lib.rs Exposes the new stacks module.
crates/but-github/src/client.rs Broadens client field visibility to support the stacks module implementation.
crates/but-forge/src/review.rs Updates sync_reviews to treat each batch as a single stack and optionally register native GitHub stacks while adjusting footer behavior.
crates/but-forge/Cargo.toml Adds tracing dependency needed for new warning logs.
crates/but-api/src/legacy/forge.rs Derives base+push forge repo info and passes it into sync_reviews for fork detection.
Cargo.lock Locks tracing addition for but-forge.
apps/desktop/src/lib/forge/shared/prFooter.ts Removes TS-side footer writers; sends stack updates to backend as bottom-to-top ForgeReviewUpdate[].
apps/desktop/src/lib/forge/shared/prFooter.test.ts Replaces footer rendering tests with ordering/target-branch chaining tests for backend-driven updates.
apps/desktop/src/lib/forge/prService.svelte.ts Adds an RTK mutation + service helper for update_review_footers command.
apps/desktop/src/components/forge/ReviewCreation.svelte Switches to the renamed stack-info updater export.

Comment thread crates/but-github/src/stacks.rs Outdated
Comment thread crates/but/src/command/legacy/push.rs
Comment thread apps/desktop/src/lib/forge/shared/prFooter.ts
Copilot AI review requested due to automatic review settings July 17, 2026 10:56

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.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.

Comment thread crates/but-github/src/stacks.rs Outdated
Comment thread crates/but-github/src/stacks.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9f7d0d2dec

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/but-github/src/stacks.rs
Comment thread crates/but/src/command/legacy/push.rs Outdated
GitHub's stacking preview models stacks exactly like GitButler (each PR
targets the branch below), so published PRs can be registered as-is via
the new stacks REST endpoints. sync_reviews now probes the feature per
repository (404 means not enabled; negative results cached) and, where
available, registers the stack with GitHub instead of writing the
description footer, stripping any footer left from before. Fork-headed
stacks keep footers since cross-fork stacks are unsupported, as do
GitLab/Bitbucket.

Each sync_reviews batch is now defined as one stack ordered bottom to
top; the push path syncs per stack accordingly, and the desktop footer
writers route through the same backend command so the footer-vs-native
decision lives in one place.
Copilot AI review requested due to automatic review settings July 17, 2026 11:07
@krlvi
krlvi force-pushed the github-native-stacks branch from f7d3c07 to 173de59 Compare July 17, 2026 11:07

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.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 1 comment.

Comment on lines +1686 to +1690
// Push-only target updates carry no footer content and leave bodies alone.
let footer_sync = if reviews.iter().any(|r| !r.unit_symbol.is_empty()) {
FooterSync::Write
} else {
FooterSync::KeepBody
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLI The command-line program `but` @gitbutler/desktop rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants