diff --git a/docs/src/content/docs/faq.md b/docs/src/content/docs/faq.md index aaa4206..38d7381 100644 --- a/docs/src/content/docs/faq.md +++ b/docs/src/content/docs/faq.md @@ -100,7 +100,41 @@ You cannot merge a PR in the middle of the stack before the PRs below it are mer ### How does squash merge work? -Squash merges are fully supported. Each PR in the stack produces one clean, squashed commit when merged. The rebase engine automatically detects squash-merged PRs and replays commits from the remaining branches onto the squashed result. +Squash merges are fully supported. Each PR in the stack produces one clean, squashed commit when merged. Merging `n` PRs will create `n` squashed commits on the base. + +When a PR is squash-merged, the original commits disappear from the history, which can cause artificial merge conflicts during rebasing. Both the CLI and the server handle this using `git rebase --onto`: + +``` +git rebase --onto +``` + +**Example:** Consider a stack with three PRs: + +``` +PR1: main ← A, B (branch1) +PR2: main ← A, B, C, D (branch2) +PR3: main ← A, B, C, D, E, F (branch3) +``` + +When PR1 and PR2 are squash-merged, `main` now looks like: + +``` +S1 (squash of A+B), S2 (squash of C+D) +``` + +Then the following rebase is run: + +``` +git rebase --onto S2 D branch3 +``` + +Which rewrites `branch3` to: + +``` +S1, S2, E, F +``` + +This moves the unique commits from the unmerged branch and replays them on top of the newly squashed commits on the base branch, avoiding any merge conflicts. ### How does merge commit work? diff --git a/docs/src/content/docs/getting-started/quick-start.md b/docs/src/content/docs/getting-started/quick-start.md index 9b2e50f..b9c4b52 100644 --- a/docs/src/content/docs/getting-started/quick-start.md +++ b/docs/src/content/docs/getting-started/quick-start.md @@ -9,6 +9,10 @@ description: Install the gh stack CLI and create your first Stacked PR in minute - Git 2.20 or later - A GitHub repository you can push to +:::caution[Private Preview] +Stacked PRs is currently in private preview. This feature will **not work** unless enabled for your repository. [Sign up for the waitlist →](https://gh.io/stacksbeta) +::: + ## Install the CLI Extension ```sh diff --git a/docs/src/content/docs/guides/stacked-prs.md b/docs/src/content/docs/guides/stacked-prs.md index 5ff2bb7..5be37ce 100644 --- a/docs/src/content/docs/guides/stacked-prs.md +++ b/docs/src/content/docs/guides/stacked-prs.md @@ -21,13 +21,13 @@ Each PR in a stack shows only the diff for its layer — the changes between its - **Review individual PRs** when you're focusing on a specific concern (e.g., reviewing only the API layer). - **Use the stack map** to navigate between PRs without going back to the PR list. -## Merging Step by Step +## Merging from the Bottom Up -Stacks are merged **from the bottom up**. You cannot merge a PR in the middle of the stack before the PRs below it are merged. +Stacks are merged **from the bottom up** — you can merge any number of PRs at once, as long as they form a contiguous group starting from the lowest unmerged PR. For example, in a stack of four PRs, you can merge just the bottom one, or the bottom three together, but you cannot merge only the second and third PRs while leaving the first unmerged. Mid-stack merges are not allowed. -1. When the bottom PR meets all merge requirements, merge it. -2. After the bottom PR is merged, the remaining stack is **automatically rebased** — the next PR's base is updated to target `main` directly. -3. The next PR is now at the bottom and can be reviewed, approved, and merged. +1. When the lowest unmerged PR (and any PRs above it that you want to include) meet all merge requirements, merge them. +2. After the merge, the remaining stack is **automatically rebased** — the next unmerged PR's base is updated to target `main` directly. +3. The next unmerged PR is now at the bottom and can be reviewed, approved, and merged. 4. Repeat until the entire stack is landed. For details on merge methods (squash, merge commit, rebase) and merge requirements, see [Merging Stacks](/gh-stack/introduction/overview/#merging-stacks) in the Overview. diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 1a05930..fdcb414 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -15,7 +15,7 @@ hero: icon: right-arrow --- -import { Card, CardGrid } from '@astrojs/starlight/components'; +import { Card, CardGrid, Aside } from '@astrojs/starlight/components'; import { Image } from 'astro:assets'; import stackDiagram from '../../assets/stack-diagram.svg'; import stackNavigator from '../../assets/screenshots/stack-navigator.png'; @@ -53,14 +53,18 @@ GitHub understands stacks end-to-end: the pull request UI shows a **stack map** The stack navigator in a pull request header -## How It Works +## Working with Stacks -The `gh stack` CLI handles the local workflow: creating branches, managing rebases, pushing to GitHub, and creating PRs with the correct base branches. On GitHub, the PR UI gives reviewers the context they need — a stack map for navigation, focused diffs for each layer, and proper rules enforcement. +**While the `gh stack` CLI makes the local workflow seamless, it is entirely optional.** You can create and manage Stacked PRs directly via the GitHub UI, the API, or your standard Git workflow. If you choose to use the CLI, it handles creating branches, managing rebases, pushing to GitHub, and creating PRs with the correct base branches. On GitHub, the PR UI gives reviewers the context they need — a stack map for navigation, focused diffs for each layer, and proper rules enforcement. -When you're ready to merge, you can merge all or a part of the stack. Each PR can be merged directly or through the merge queue. After a merge, the remaining PRs in the stack are automatically rebased so the lowest unmerged PR targets the base branch. +When you're ready to merge, you can merge all or a part of the stack. Each PR can be merged directly or through the merge queue. **If you want to merge multiple PRs at once (e.g., the bottom two PRs in a stack), simply wait for CI to pass on those specific layers, and you can merge them in a single step.** After a merge, the remaining PRs in the stack are automatically rebased so the lowest unmerged PR targets the updated base branch. ## Get Started + + ```sh # Install the CLI extension gh extension install github/gh-stack diff --git a/docs/src/content/docs/introduction/overview.md b/docs/src/content/docs/introduction/overview.md index 947dd07..8d4b0f6 100644 --- a/docs/src/content/docs/introduction/overview.md +++ b/docs/src/content/docs/introduction/overview.md @@ -77,6 +77,7 @@ Rebasing is the trickiest part of working with Stacked PRs, and GitHub handles i - **In the PR UI** — A rebase button lets you trigger a cascading rebase across all branches in the stack. - **From the CLI** — `gh stack rebase` performs the same cascading rebase locally. - **After partial merges** — When you merge a PR at the bottom of the stack, the remaining branches are automatically rebased so the next PR targets `main` and is ready for review and merge. +- **Safe squash-merge handling** — Squash merges are fully supported. The rebase engine safely replays your unique commits on top of the squashed base, avoiding artificial merge conflicts. See the [FAQ](/gh-stack/faq/#how-does-squash-merge-work) for a detailed description of how this works. ## The CLI: `gh stack` @@ -93,6 +94,8 @@ While the PR UI provides the review and merge experience, the `gh stack` CLI han The CLI is not required to use Stacked PRs — the underlying git operations are standard. But it makes the workflow simpler, and you can create Stacked PRs from the CLI instead of the UI. +**Bring Your Own Tools:** You don't need to use the `gh stack` CLI for your local workflow. If you use tools like Jujutsu, Sapling, or custom tools to manage and push your local branches, you can then use the CLI or the GitHub UI to open a stack of PRs from those branches. See the [FAQ](/gh-stack/faq/#will-this-work-with-a-different-tool-for-stacking) for examples. + ## Thinking About Stack Structure Each branch in a stack should represent a **discrete, logical unit of work** that can be reviewed independently. Think of a stack from the reviewer's perspective: the PRs should tell a cohesive story, where each one is a small, logical piece of the whole. diff --git a/docs/src/styles/custom.css b/docs/src/styles/custom.css index c1b86e9..3795cd8 100644 --- a/docs/src/styles/custom.css +++ b/docs/src/styles/custom.css @@ -248,6 +248,16 @@ header starlight-theme-select { margin-right: auto; } +.hero .tagline code { + font-size: 0.9em; + letter-spacing: -0.02em; + word-spacing: -0.1em; + padding: 0.15em 0.4em; + border-radius: 6px; + background: rgba(110, 118, 129, 0.15); + font-weight: 500; +} + /* Center the action button group */ .hero .sl-flex .sl-flex { justify-content: center !important; @@ -596,6 +606,14 @@ a.sl-link-button[data-variant='primary']:hover, /* Code blocks and tables — let Starlight/ExpressiveCode handle layout. Colors flow through the --sl-color-* variables set above. */ +/* Light mode copy button: make icon visible on light code blocks */ +:root[data-theme='light'] .expressive-code .copy button { + background-color: rgba(175, 184, 193, 0.3) !important; +} +:root[data-theme='light'] .expressive-code .copy button::after { + background-color: #1f2328 !important; +} + /* Blockquotes — light color adjustments only */ .sl-markdown-content blockquote { color: #9198a1;