diff --git a/src/components/GitGraph.astro b/src/components/GitGraph.astro index 9580d3ef3b..289fbc5024 100644 --- a/src/components/GitGraph.astro +++ b/src/components/GitGraph.astro @@ -84,7 +84,7 @@ function renderLinear(p: { const R = 18; const SPACING = 80; - const PAD_LEFT = 50; + const PAD_LEFT = 70; const COMMIT_Y = 32; const PR_Y = 100; const PR_H = 26; @@ -115,8 +115,9 @@ function renderLinear(p: { const lines: string[] = []; const push = (s: string) => lines.push(s); + const cssMaxW = Math.min(560, Math.max(360, maxX + 20)); push( - `` + `` ); // branch line diff --git a/src/components/StackMapping.astro b/src/components/StackMapping.astro new file mode 100644 index 0000000000..e61f6af98f --- /dev/null +++ b/src/components/StackMapping.astro @@ -0,0 +1,131 @@ +--- +/** + * Three-column diagram showing how local commits map to remote branches and GitHub PRs. + * Used on the Stacks concepts page to illustrate the mental model. + */ + +interface Entry { + commit: string; + branch: string; + pr: string; +} + +interface Props { + entries: Entry[]; +} + +const { entries } = Astro.props; + +const COL_W = 160; +const COL_GAP = 50; +const ROW_H = 44; +const HEAD_H = 28; +const PAD = 16; +const R = 6; +const FONT = 11; +const HEAD_FONT = 10; +const ARROW_GAP = 8; + +const cols = [ + { label: 'Local Commits', color: '#347D39', x: PAD }, + { label: 'Remote Branches', color: '#6B7280', x: PAD + COL_W + COL_GAP }, + { label: 'GitHub PRs', color: '#2563EB', x: PAD + 2 * (COL_W + COL_GAP) }, +]; + +const totalW = cols[2].x + COL_W + PAD; +const totalH = HEAD_H + entries.length * ROW_H + PAD; + +function boxY(i: number) { + return HEAD_H + i * ROW_H + 6; +} + +const BOX_H = ROW_H - 12; +--- + + + {/* Column headers */} + {cols.map((col) => ( + {col.label} + ))} + + {/* Rows */} + {entries.map((entry, i) => { + const y = boxY(i); + const cy = y + BOX_H / 2; + const values = [entry.commit, entry.branch, entry.pr]; + + return ( + + {/* Boxes */} + {cols.map((col, j) => ( + + + {values[j]} + + ))} + + {/* Arrows between columns */} + {[0, 1].map((j) => { + const x1 = cols[j].x + COL_W + ARROW_GAP; + const x2 = cols[j + 1].x - ARROW_GAP; + return ( + + + + + ); + })} + + ); + })} + + + diff --git a/src/content/docs/stacks.mdx b/src/content/docs/stacks.mdx index 382938f533..368df06998 100644 --- a/src/content/docs/stacks.mdx +++ b/src/content/docs/stacks.mdx @@ -1,139 +1,94 @@ --- -title: "Stacks: Stacked Pull Requests" -description: How to create and manage stacked PRs. +title: Stacks +description: Break large changes into small, reviewable pull requests. One branch, many PRs. --- -import { Image } from "astro:assets" -import GHPRSchema from "../images/stacked-gh-pr.png" -import MergifyStackSchema from "../images/stacked-mergify-pr.png" -import StackComment from "../images/stack-comment.png" +import Button from '~/components/Button.astro'; +import DocsetGrid from '~/components/DocsetGrid/DocsetGrid.astro'; +import Docset from '~/components/DocsetGrid/Docset.astro'; +import GitGraph from '~/components/GitGraph.astro'; -Mergify Stacks allow you to split your local Git branches in multiple pull -requests to make it easier to split you work in small atomic parts. +AI can write 1,000 lines of code in minutes, but nobody wants to review a +1,000-line pull request. Reviewers skim instead of reading, bugs slip through, +and merges stall for days. -## Limitations of GitHub's Pull Request Model + -The conventional GitHub pull request model operates on a branch-based system -where each branch corresponds to one pull request. +## The Problem: One Branch = One PR - +GitHub's pull request model ties every branch to a single PR. As you add +commits, the PR grows, and so does the review burden. -As more commits are added to a branch and pushed, the associated pull request -expands. This continual growth can complicate the review process, making it -challenging for reviewers as the code base increases. Moreover, this model -often discourages the division of work into atomic, manageable commits. + -The concept of Stacks addresses this issue by breaking down work into -incremental, reviewable steps. This structure not only simplifies the review -process but also enhances the digestibility of changes for teammates. +Developers face a bad choice: ship one giant PR that no one can review +thoroughly, or manually manage a chain of dependent branches and rebase each one +whenever the base changes. Git has the tools to split work into atomic commits. +GitHub just doesn't expose them as separate, reviewable units. -Furthermore, should a rollback be necessary, it's far simpler and less -disruptive to revert a single, small pull request rather than an entire branch -of accumulated changes. +## The Solution: One Branch, Many PRs -## Advantages of Using Mergify Stacks +Mergify Stacks maps each commit on your branch to its own pull request, +automatically chained in dependency order. -Mergify Stacks retains the familiar branch model used in Git while innovating -on how pull requests are handled. Instead of opening one pull request for an -entire branch, Mergify Stacks opens a separate pull request for each commit. + - +You work on a single local branch using standard Git: commits, rebase, amend. +When you push, Stacks creates a separate PR for each commit, linked together so +reviewers see the logical progression of your work. -This approach allows developers to maintain all their changes within a single -branch while effectively segmenting their work into smaller, more manageable -parts. Each part is easier to review and quicker to integrate, streamlining the -development process and enhancing overall efficiency. +- Small, focused PRs that reviewers actually read +- One local branch (no juggling N branches for N PRs) +- Automatic PR chaining with dependency tracking +- Smart updates that only touch PRs that changed +- Standard Git, no new commands to learn +- Complements [Merge Queue](/merge-queue) for safe, fast landing -When a commit needs to be changed, [`git rebase ---interactive`](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) can -be used to -change the content of the branch. Mergify Stacks automatically synchronize your -branch to the pull requests. - -This means that there is no need to learn any new tool to manage your Mergify -Stacks: they are just regular Git branches. - -:::note - For Mergify Stacks to function effectively, branches must be in the `heads` - namespace. -::: - -This process ensures that developers don't have to tediously update each -individual pull request manually. Everything is managed under the hood by -Mergify Stacks, from the commit level to the PR level. - -The automated nature of this approach minimizes the chances of human error—like -missing a pull request update or misapplying a change. Developers maintain the -freedom and flexibility of the Git interactive rebase, allowing for granular -and precise changes to commits. - -## Setting Up Mergify Stacks - -First, [install the Mergify CLI](/cli) if you haven't already. - -Then, set up the commit-msg hook in your repository: - -```bash -mergify stack --setup -``` - -## Creating Stacked Pull Requests - -1. Spawn a branch and introduce your changes. - -2. Commit the changes. If Mergify CLI is correctly configured, your commit - message will automatically contain the `Change-Id`. - -3. In case you committed before initializing Mergify CLI, use `git rebase - -i` to reword commits and automatically embed the `Change-Id`. - -4. To construct the stack, run: +## Get Started in 30 Seconds ```bash -mergify stack +uv tool install mergify-cli +mergify stack setup +mergify stack push ``` - - -Mergify CLI will manage the creation of individual pull requests for every -commit in your feature branch. This structured approach ensures smooth and -error-free management of changes and reviews. - -## Updating Stacked Pull Requests - -Inevitably, there will be times when you'll need to modify or refine your pull -requests—perhaps due to feedback from a code review or just a late realization. -Mergify CLI streamlines this process, ensuring your stacked pull requests are -always in sync with your latest changes. - -1. **Stay in Your Feature Branch:** The beauty of stacked PRs lies in their - granular structure. Always make sure you are working within the specific - feature branch where the relevant commits reside. - -2. **Modifying Commits:** To update or modify commits inside your branch: - - Use the interactive rebase feature of Git: - ```bash - git rebase --interactive - ``` - - - Within the interactive rebase session, you can: - - **pick** to retain a commit. - - **reword** to change a commit message. - - **edit** to modify the content of a commit. - - **squash** to combine the commit with the previous one. - - **drop** to remove a commit entirely. - - Make your desired changes and save. This action will reapply your commits on - top of the base branch, incorporating the changes you've made. - -3. **Pushing Updated Stacked PRs:** Once you've made all the necessary - modifications to your branch and are satisfied with the changes, call the - Mergify CLI with the `stack` command: - ```bash - mergify stack - ``` - This command will push your modified commits and update the corresponding - pull requests on GitHub. Mergify CLI intelligently keeps track of the - relationships between your commits and the pull requests, ensuring - everything remains synchronized. +Three commands to go from a branch with commits to a stack of reviewable PRs on +GitHub. See the [setup guide](/stacks/setup) for details. + +## Learn More + + + + How stacks work under the hood: Change-Ids, branch mapping, and PR chaining. + + + Install the CLI and configure your repository in under 2 minutes. + + + Walk through creating your first stack from branch to PRs. + + + Amend, reorder, squash, or add commits and keep PRs in sync. + + + A reviewer's guide to navigating and reviewing stacked PRs. + + + Why and how to roll out stacked PRs across your engineering team. + + diff --git a/src/content/docs/stacks/concepts.mdx b/src/content/docs/stacks/concepts.mdx new file mode 100644 index 0000000000..63e2a9574c --- /dev/null +++ b/src/content/docs/stacks/concepts.mdx @@ -0,0 +1,130 @@ +--- +title: Concepts +description: How Mergify Stacks maps Git commits to GitHub pull requests. +--- + +import { Image } from 'astro:assets'; +import StackComment from '../../images/stack-comment.png'; +import GitGraph from '~/components/GitGraph.astro'; +import StackMapping from '~/components/StackMapping.astro'; + +## The Mental Model + +You work on one local branch with multiple commits. Mergify Stacks maps each +commit to its own GitHub pull request. The PRs are chained together: each one's +base branch is the previous PR's head branch. + + + +Reviewers see one small, focused diff per PR instead of the accumulated changes +of the entire branch. + +When you run `mergify stack push`, each commit goes through three stages: + + + +Your local commits become remote branches, and each remote branch becomes a +pull request. The Change-Id in each commit message is what ties all three +together. + +## Change-Id + +The Change-Id connects your local commits to their corresponding pull requests. +It's a unique identifier embedded as a +[Git trailer](https://git-scm.com/docs/git-interpret-trailers) in each commit +message: + +```text +feat: add user authentication + +Implement JWT-based auth with refresh tokens. + +Change-Id: Ia1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 +``` + +The Change-Id is: + +- Generated automatically by a `commit-msg` Git hook installed during + [setup](/stacks/setup) + +- Persistent across rebases, amends, and history rewrites + +- The mapping key that Stacks uses to know which commit corresponds to which + PR, even after you rewrite your branch + +You never need to manage Change-Ids manually. They're created once and preserved +through all git operations. + +## Branch Mapping + +When you run `mergify stack push`, each commit gets its own remote branch. The +naming convention is: + +```text +stack/{username}/{branch-name}/{Change-Id} +``` + +For example, if user `alice` pushes a branch called `feat/auth` with 3 commits: + +| Commit | Remote Branch | +|--------|--------------| +| A: add data model | `stack/alice/feat/auth/Ia1b2c3...` | +| B: add API endpoint | `stack/alice/feat/auth/Id4e5f6...` | +| C: add tests | `stack/alice/feat/auth/Ig7h8i9...` | + +You can customize the branch prefix via Git config: + +```bash +git config mergify-cli.stack-branch-prefix "my-prefix" +``` + +## PR Chaining + +Each PR targets the previous PR's branch as its base, creating a dependency +chain: + +| Commit | PR Base | PR Head | +|--------|---------|---------| +| A (first) | `main` | `stack/alice/feat/auth/Ia1b2c3...` | +| B (second) | `stack/alice/feat/auth/Ia1b2c3...` | `stack/alice/feat/auth/Id4e5f6...` | +| C (third) | `stack/alice/feat/auth/Id4e5f6...` | `stack/alice/feat/auth/Ig7h8i9...` | + +Stacks also adds a `Depends-On: #NNN` reference in each PR description and +posts a stack comment on every PR listing the full chain: + + + +The stack comment shows where each PR sits in the chain, with links to jump +between them. This gives both authors and reviewers a clear map of the entire +change. + +## Smart Updates + +When you push again after making changes, Stacks doesn't recreate everything. It +compares each commit's Change-Id and SHA against what's already on GitHub: + +- Changed commits get their PR updated (force-push to the remote branch) + +- Unchanged commits are skipped entirely + +- Removed commits (after squashing or dropping) get their orphan remote + branches deleted automatically + +`mergify stack push` is always safe to run. It only does the minimum work needed +to sync your local branch with GitHub. + +## Next Steps + +See [Setup](/stacks/setup) to install the CLI and configure your repository. diff --git a/src/content/docs/stacks/creating.mdx b/src/content/docs/stacks/creating.mdx new file mode 100644 index 0000000000..76ddd2ac86 --- /dev/null +++ b/src/content/docs/stacks/creating.mdx @@ -0,0 +1,103 @@ +--- +title: Creating Stacks +description: Walk through creating your first stack of pull requests. +--- + +import { Image } from 'astro:assets'; +import StackComment from '../../images/stack-comment.png'; +import setupNewPush from '../../images/stacks-setup-new-push.png'; +import stackList from '../../images/stacks-list-output.png'; + +This guide walks you through creating a stack from scratch, from starting a +branch to having multiple chained PRs on GitHub. + +## Start a New Branch + +Use the `stack new` command to create a branch that tracks your main branch: + +```bash +mergify stack new feat/my-feature +``` + +This is equivalent to `git checkout -b feat/my-feature --track origin/main`. You +can also create branches however you normally do. Stacks doesn't require its own +branch creation command. + +## Make Commits + +Work normally. Each commit should represent one logical unit of work, something +that makes sense to review on its own. + +For example, building a new API feature: + +```bash +# First commit: data model +git add src/models/user.py +git commit -m "feat: add user data model + +Define the User schema with fields for auth." + +# Second commit: API endpoint +git add src/api/users.py +git commit -m "feat: add user registration endpoint + +POST /api/users creates a new user account." + +# Third commit: tests +git add tests/test_users.py +git commit -m "test: add user registration tests + +Cover happy path, duplicate email, and validation errors." +``` + +Each commit automatically gets a `Change-Id` trailer. You don't need to do +anything special. + +## Push the Stack + +Run: + +```bash +mergify stack push +``` + +What happens behind the scenes: + +1. **Rebases** your branch on the latest `main` +2. **Creates a remote branch** for each commit +3. **Opens a PR** for each commit, chained in dependency order +4. **Posts a stack comment** on every PR showing the full stack + +The full flow, from setup to push: + + + +The result on GitHub: three small, focused PRs instead of one large one. Each PR +contains exactly one commit's worth of changes. + +Each PR includes a stack comment that shows where it sits in the chain: + + + +## Check Your Stack + +To see the state of your stack at any time: + +```bash +mergify stack list +``` + +This shows each PR, its CI and review status, and a link to GitHub: + + + +:::tip + Use `mergify stack open` to quickly open a PR in your browser. It shows an + interactive picker if your stack has multiple PRs. +::: + +## Next Steps + +To update a commit after code review, see [Updating Stacks](/stacks/updating). +For a reviewer's perspective on navigating stacked PRs, see +[Reviewing Stacks](/stacks/reviewing). diff --git a/src/content/docs/stacks/reviewing.mdx b/src/content/docs/stacks/reviewing.mdx new file mode 100644 index 0000000000..331fc88ffd --- /dev/null +++ b/src/content/docs/stacks/reviewing.mdx @@ -0,0 +1,72 @@ +--- +title: Reviewing Stacks +description: A reviewer's guide to navigating and reviewing stacked pull requests. +--- + +import { Image } from 'astro:assets'; +import StackComment from '../../images/stack-comment.png'; + +Stacked PRs look and feel like regular pull requests, just smaller. You don't +need to install anything or learn new tools to review them. + +## What You'll See + +Each stacked PR contains a single commit's worth of changes. At the top of +every PR, a stack comment shows the full chain and highlights the current PR: + + + +The comment includes links to every PR in the stack, so you can jump between +them. + +## How to Review + +### Start from the Bottom + +Review the stack in order, starting with the first PR (the one targeting +`main`). Each subsequent PR builds on the previous one, so reviewing in order +gives you the narrative of the change. + +### Each PR Shows Only Its Own Changes + +Unlike a single large PR, each stacked PR's diff contains only the changes from +its corresponding commit, not the accumulated changes of the entire branch: + +- PR #1 shows the data model changes +- PR #2 shows only the API endpoint, not the model + endpoint +- PR #3 shows only the tests, not everything combined + +You review small, focused diffs instead of trying to parse hundreds of lines at +once. + +### Navigate Between PRs + +Use the links in the stack comment to move between PRs. The current PR is +marked in the list so you always know where you are in the chain. + +## Leaving Feedback + +Review comments work exactly like any other PR: + +- Leave inline comments on specific lines +- Request changes or approve +- Use GitHub's review features normally + +When the author addresses your feedback, they'll rebase and push. The PR updates +in place, and your review comments stay attached to the relevant lines. + +## Merging Stacked PRs + +Stacked PRs merge bottom-up. The first PR in the stack (targeting `main`) +merges first. Once it lands, the next PR's base automatically updates to `main`, +and you can review and merge that one. Each PR in turn, working up the chain. + +:::tip + Stacks work well with [Merge Queue](/merge-queue). Each stacked PR can enter + the queue independently as its dependencies land, keeping your merge pipeline + flowing. +::: + +You don't need to merge the entire stack at once. If the first two PRs are +approved but the third needs more work, merge the first two and let the author +continue iterating on the rest. diff --git a/src/content/docs/stacks/setup.mdx b/src/content/docs/stacks/setup.mdx new file mode 100644 index 0000000000..d1dd3ef865 --- /dev/null +++ b/src/content/docs/stacks/setup.mdx @@ -0,0 +1,101 @@ +--- +title: Setup +description: Install Mergify CLI and configure your repository for stacked PRs. +--- + +import { Image } from 'astro:assets'; +import deleteHeadBranches from '../../images/github-delete-head-branches.png'; + +## Prerequisites + +1. **Install the Mergify CLI**, see the [CLI installation guide](/cli) for + instructions. + +2. **GitHub authentication**: Stacks needs access to create PRs. Either: + - Set the `GITHUB_TOKEN` environment variable, or + - Install the [GitHub CLI](https://cli.github.com/) and run `gh auth login` + +3. **Enable "[Automatically delete head branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches)"** + in your GitHub repository settings (Settings > General > Pull Requests). + When a stacked PR merges, this cleans up its remote branch automatically + so the next PR in the chain can rebase onto `main` cleanly. + + + +## Initialize Your Repository + +Run the setup command in your Git repository: + +```bash +mergify stack setup +``` + +This installs: + +- A `commit-msg` Git hook that automatically generates a + [Change-Id](/stacks/concepts#change-id) for every new commit. The Change-Id + is how Stacks tracks the relationship between your local commits and their + GitHub pull requests. + +- A `pre-push` hook that warns you if you accidentally use `git push` instead + of `mergify stack push`. + +- A [Claude Code](https://claude.ai/code) skill that teaches the AI + coding agent how to work with Mergify Stacks, so it automatically uses + `mergify stack push` instead of `git push`. + +## Verify It Works + +Create a test commit to confirm the hook is active: + +```bash +echo "test" >> test.txt +git add test.txt +git commit -m "test: verify stack setup" +``` + +Check the commit message: + +```bash +git log -1 +``` + +You should see a `Change-Id` trailer at the bottom of the message: + +```text +test: verify stack setup + +Change-Id: Ia1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 +``` + +:::tip + If you already have commits without Change-Ids, run + `git rebase -i ` and choose **reword** for each commit. The hook + will add the Change-Id automatically when you save the message. +::: + +Clean up the test commit if you don't need it: + +```bash +git reset HEAD~1 +``` + +## Configuration + +These optional Git config settings let you customize Stacks behavior: + +| Setting | Default | Description | +|---------|---------|-------------| +| `mergify-cli.stack-branch-prefix` | `stack/{username}` | Prefix for remote branch names | +| `mergify-cli.stack-create-as-draft` | `false` | Create PRs as drafts by default | +| `mergify-cli.stack-keep-pr-title-body` | `false` | Don't overwrite PR title/body on updates | + +Example: + +```bash +git config mergify-cli.stack-create-as-draft true +``` + +## Next Steps + +Head to [Creating Stacks](/stacks/creating) to push your first stack. diff --git a/src/content/docs/stacks/team.mdx b/src/content/docs/stacks/team.mdx new file mode 100644 index 0000000000..365307ecff --- /dev/null +++ b/src/content/docs/stacks/team.mdx @@ -0,0 +1,84 @@ +--- +title: Team Adoption +description: Why and how to roll out stacked PRs across your engineering team. +--- + +## Why Stacked PRs Matter for Teams + +Code review slows down as PRs get bigger. Reviewers spend less time per line as +the diff grows: a 400-line PR gets a thorough review, a 2,000-line PR gets a +skim and an approval. + +As teams adopt AI coding tools, the amount of code generated per developer is +increasing faster than anyone can review it. Stacked PRs let developers ship +large changes as a series of small, reviewable units instead of one monolith. + +The difference shows up in practice: + +- Faster review cycles: small PRs get reviewed in hours, not days + +- Higher review quality: reviewers catch more issues in focused diffs + +- Faster unblocking: developers can start the next piece while the first is + in review + +- Easier rollbacks: revert one small PR instead of unwinding a monolith + +## Gradual Rollout + +Stacks doesn't require a team-wide rollout. There's no repo-wide configuration, +no CI changes, and no admin setup. + +A single developer can start using stacks today: + +1. [Install the CLI](/cli) locally +2. Run [`mergify stack setup`](/stacks/setup) in their clone +3. Start pushing stacks + +Their teammates review the resulting PRs normally. They just see smaller, +well-organized PRs with stack comments explaining the chain. No one else needs +to install anything. + +As more developers see the benefits in review, adoption spreads naturally. + +## When to Use Stacks + +Not every change needs a stack. Use stacks when the alternative is a large, +hard-to-review PR: + +**Good candidates:** +- Features touching multiple layers (model, API, UI) +- Large refactors that can be broken into logical steps +- AI-generated changes that need careful human review +- Any change that would exceed ~300 lines in a single PR + +**Skip stacks for:** +- One-line bug fixes +- Documentation-only changes +- Simple configuration updates +- Changes that are already small and focused + +## Pairing with Merge Queue + +[Merge Queue](/merge-queue) complements Stacks well: Stacks break large changes +into reviewable pieces, and Merge Queue lands those pieces safely and +efficiently. Each stacked PR can enter the queue independently as its +dependencies land. The bottom PR merges first, then the next one enters the +queue, and so on, without manual coordination. + +## Comparing with Alternatives + +Several tools offer stacked PRs. Here's how Mergify Stacks compares: + +| | Mergify Stacks | Graphite | ghstack | spr | +|---|---|---|---|---| +| **Workflow** | Standard Git | Custom CLI | Standard Git | Standard Git | +| **Branch model** | One local branch | Managed branches | Managed branches | Managed branches | +| **GitHub integration** | PR chaining + deps | PR chaining + dashboard | PR chaining | PR chaining | +| **Merge queue** | [Built-in](/merge-queue) | Separate | None | None | +| **Pricing** | Included with Mergify | Separate subscription | Open source | Open source | +| **Setup** | CLI + one command | CLI + account setup | CLI install | CLI install | + +Mergify Stacks uses standard Git. You don't learn new commands for committing +or managing branches. You use `git commit`, `git rebase`, and +`git commit --amend` like you always have. Stacks handles the GitHub side. diff --git a/src/content/docs/stacks/updating.mdx b/src/content/docs/stacks/updating.mdx new file mode 100644 index 0000000000..6d263af64c --- /dev/null +++ b/src/content/docs/stacks/updating.mdx @@ -0,0 +1,173 @@ +--- +title: Updating Stacks +description: Amend, reorder, add, or remove commits in your stack. +--- + +import GitGraph from '~/components/GitGraph.astro'; + +After pushing a stack, you'll need to make changes: responding to review +feedback, adding commits, rearranging order, or squashing. This page covers +every common scenario. + +In all cases, the workflow is the same: **make your changes locally, then run +`mergify stack push`** to sync with GitHub. + +## Amend the Latest Commit + +Make your changes, then amend: + +```bash +git add src/api/users.py +git commit --amend +``` + +The Change-Id is preserved automatically. Then push: + +```bash +mergify stack push +``` + +Only the PR corresponding to the amended commit is updated. + +## Edit a Commit Mid-Stack + +To modify a commit that isn't at the top of your branch, use interactive rebase. +Stacks provides a shortcut: + +```bash +mergify stack edit +``` + +This opens `git rebase -i` from the fork point of your stack. You'll see your +commits listed: + +```text +pick a1b2c3d feat: add user data model +pick d4e5f6a feat: add user registration endpoint +pick g7h8i9b test: add user registration tests +``` + +Change `pick` to `edit` for the commit you want to modify: + +```text +edit a1b2c3d feat: add user data model +pick d4e5f6a feat: add user registration endpoint +pick g7h8i9b test: add user registration tests +``` + +Save and close. Git pauses at that commit so you can make changes: + +```bash +# Make your changes +git add src/models/user.py +git commit --amend +git rebase --continue +``` + +Then push: + +```bash +mergify stack push +``` + +## Reorder Commits + +Open interactive rebase and change the line order: + +```bash +mergify stack edit +``` + +```text +pick d4e5f6a feat: add user registration endpoint +pick a1b2c3d feat: add user data model +pick g7h8i9b test: add user registration tests +``` + +Save and close. The PRs re-chain automatically when you push. + +:::caution + Reordering can cause conflicts if later commits depend on earlier ones. Git + will pause and ask you to resolve conflicts during the rebase. +::: + +## Add a Commit + +Just commit normally anywhere in your branch: + +```bash +git add src/api/auth.py +git commit -m "feat: add authentication middleware" +``` + +On the next `mergify stack push`, a new PR is created and inserted at the +correct position in the chain. + +## Remove a Commit + +Open interactive rebase and change `pick` to `drop` (or delete the line): + +```bash +mergify stack edit +``` + +```text +pick a1b2c3d feat: add user data model +drop d4e5f6a feat: add user registration endpoint +pick g7h8i9b test: add user registration tests +``` + +On push, the orphan remote branch is deleted and the remaining PRs re-chain. + +## Squash Commits + +To combine two commits into one, use `squash` or `fixup` in interactive rebase: + +```bash +mergify stack edit +``` + +```text +pick a1b2c3d feat: add user data model +squash d4e5f6a feat: add user registration endpoint +pick g7h8i9b test: add user registration tests +``` + +The surviving commit keeps its Change-Id, so the corresponding PR is updated. The +absorbed commit's remote branch is cleaned up automatically. + +## After a PR Merges + +When the bottom PR in your stack merges into `main`, the next PR's base +automatically updates to `main`. To keep your local branch in sync, just push +again: + +```bash +mergify stack push +``` + +Before the merge, your stack looks like this: + + + +After PR #1 merges, commit A lands on `main`. The remaining PRs re-chain: + + + +Stacks rebases on `main` automatically, detects that the merged commit is already +in `main`, and skips it. The remaining PRs update as needed. diff --git a/src/content/images/github-delete-head-branches.png b/src/content/images/github-delete-head-branches.png new file mode 100644 index 0000000000..ee95ff4dc1 Binary files /dev/null and b/src/content/images/github-delete-head-branches.png differ diff --git a/src/content/images/stack-comment.png b/src/content/images/stack-comment.png index d1f65a2841..8e2c99474d 100644 Binary files a/src/content/images/stack-comment.png and b/src/content/images/stack-comment.png differ diff --git a/src/content/images/stacks-list-output.png b/src/content/images/stacks-list-output.png new file mode 100644 index 0000000000..ee7186540e Binary files /dev/null and b/src/content/images/stacks-list-output.png differ diff --git a/src/content/images/stacks-setup-new-push.png b/src/content/images/stacks-setup-new-push.png new file mode 100644 index 0000000000..70fb4c444d Binary files /dev/null and b/src/content/images/stacks-setup-new-push.png differ diff --git a/src/content/navItems.tsx b/src/content/navItems.tsx index 637e9f0d90..d26273e68d 100644 --- a/src/content/navItems.tsx +++ b/src/content/navItems.tsx @@ -190,6 +190,20 @@ const navItems: NavItem[] = [ { title: 'Examples', path: '/merge-protections/examples', icon: 'bi:lightbulb' }, ], }, + { + title: 'Stacks', + path: '/stacks', + icon: 'bi:stack', + children: [ + { title: 'Overview', path: '/stacks', icon: 'fa6-regular:lightbulb' }, + { title: 'Concepts', path: '/stacks/concepts', icon: 'fa6-solid:diagram-project' }, + { title: 'Setup', path: '/stacks/setup', icon: 'fa6-solid:wrench' }, + { title: 'Creating Stacks', path: '/stacks/creating', icon: 'fa6-solid:layer-group' }, + { title: 'Updating Stacks', path: '/stacks/updating', icon: 'fa6-solid:pen-to-square' }, + { title: 'Reviewing Stacks', path: '/stacks/reviewing', icon: 'fa6-solid:magnifying-glass' }, + { title: 'Team Adoption', path: '/stacks/team', icon: 'fa6-solid:people-group' }, + ], + }, { title: 'Workflow Automation', icon: 'bi:gear', @@ -354,7 +368,6 @@ const navItems: NavItem[] = [ }, ], }, - { title: 'Stacks', path: '/stacks', icon: 'bi:stack' }, { title: 'CLI', path: '/cli', icon: 'bi:terminal' }, { title: 'Security', path: '/security', icon: 'fa-solid:shield-alt' }, { title: 'Support', path: '/support', icon: 'fa-solid:life-ring' },