Skip to content

Commit 437c891

Browse files
committed
feat(docs): document Merge Queue support for GitHub-native stacks
The queue merges GitHub's own stacked pull requests, and the page said nothing about them: it described Mergify Stacks throughout and stated that a stack is recognized only when each pull request carries a `Depends-On:` marker, which is not how GitHub-native stacks are detected. Lead the page with GitHub-native stacks, covering how members are queued, how the stack lands bottom-up as GitHub restacks the survivors, and the `exempt` bypass mode the merge path requires. Group the existing sections under a Mergify Stacks heading so their scope is explicit. The ruleset page this one cites is corrected in the next commit of the stack. Part of MRGFY-8578 Change-Id: I81d627f9bf5c51c7bf60355625ae4209c5f0d3bd
1 parent 9d18c05 commit 437c891

1 file changed

Lines changed: 79 additions & 12 deletions

File tree

src/content/docs/merge-queue/stacks.mdx

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,81 @@
11
---
22
title: Stacked Pull Requests
3-
description: "How the merge queue handles stacks created by mergify stack push: auto-propagation, stack-aware batching, and cascade dequeue."
3+
description: "How the Merge Queue lands GitHub-native stacked pull requests and Mergify Stacks: bottom-up landing, auto-propagation, stack-aware batching, and cascade dequeue."
44
---
55

66
import GitGraph from '~/components/GitGraph.astro';
77

8-
The Merge Queue understands [Stacks](/stacks) natively. When you queue a stacked
9-
pull request, the queue treats the whole chain as a unit: it propagates the
10-
queue command up the stack, keeps stacked PRs together when batching, and
11-
cascades failures so the rest of the stack stops cleanly when something
12-
breaks.
8+
The Merge Queue lands stacked pull requests: chains where each pull request
9+
builds on the one below it. It handles both kinds of stack.
1310

14-
## How a Stack Is Detected
11+
- **[GitHub-native stacked pull
12+
requests](#github-native-stacked-pull-requests)**, created with
13+
[gh-stack](/stacks/compare/gh-stack). Every member can be queued, and
14+
members land one at a time from the bottom up.
15+
16+
- **[Mergify Stacks](#mergify-stacks)**, created with `mergify stack push`.
17+
The queue treats the whole chain as a unit: it propagates the queue command
18+
up the stack, keeps stacked PRs together when batching, and cascades
19+
failures so the rest of the stack stops cleanly when something breaks.
20+
21+
## GitHub-Native Stacked Pull Requests
22+
23+
GitHub has its own stacking model, built with
24+
[gh-stack](/stacks/compare/gh-stack), its stacking extension for the `gh`
25+
CLI. Each member is a separate branch targeting the branch below it.
26+
27+
GitHub has no auto-merge for stacked pull requests, so without a queue each
28+
member is merged by hand as the one below it lands.
29+
30+
### Queueing Members
31+
32+
Every member of a GitHub-native stack can be queued. Comment
33+
[`@mergifyio queue`](/commands/queue) on each pull request you want to land.
34+
Mergify enqueues them all, keeps same-stack members together in the queue,
35+
and enforces their order on admission, so a member is never validated ahead
36+
of the members below it.
37+
38+
:::note
39+
Queue propagation is a Mergify Stacks feature. Queueing the top member of a
40+
GitHub-native stack does not enqueue its predecessors, so comment on each
41+
member you want to land.
42+
:::
43+
44+
### How the Stack Lands
45+
46+
Members land one at a time, from the bottom up:
47+
48+
1. The lowest open member merges through GitHub's merge API for stacks.
49+
50+
2. GitHub restacks the survivors: the next member is retargeted onto the base
51+
branch and the rest of the chain is rebased on top of what just landed.
52+
Mergify waits for that retargeting before continuing.
53+
54+
3. The new lowest open member merges, and so on until the stack is drained.
55+
56+
Merged members stay in the stack on GitHub, so the stack never shrinks. What
57+
changes is which member is the lowest open one.
58+
59+
Landing is sequential rather than atomic, so a stack can be partly landed
60+
while the rest is still in flight. If a member fails, the members that
61+
already merged below it stay merged.
62+
63+
### Requirements
64+
65+
Mergify must be a bypass actor with the `exempt` bypass mode on every GitHub
66+
ruleset that applies to the base branch. GitHub's merge API for stacks
67+
recognizes no other bypass mode, and the Merge Queue refuses a stacked pull
68+
request rather than attempting a merge GitHub would reject. See [GitHub
69+
Rulesets Compatibility](/merge-queue/github-rulesets) for how to set the
70+
bypass mode and what it changes.
71+
72+
## Mergify Stacks
73+
74+
[Mergify Stacks](/stacks) are created with `mergify stack push`, which maps
75+
each commit on a single branch to its own pull request. The queue treats such
76+
a stack as one unit.
77+
78+
### How a Stack Is Detected
1579

1680
The queue recognizes a stack only when **both** signals hold at every step:
1781

@@ -37,7 +101,7 @@ them independently.
37101
]}
38102
/>
39103

40-
## Queueing a Whole Stack at Once
104+
### Queueing a Whole Stack at Once
41105

42106
Run [`@mergifyio queue`](/commands/queue) on the **top** PR of a stack and the
43107
queue command propagates synthetically to every predecessor. The whole stack
@@ -56,7 +120,7 @@ until PR1 and PR2 are queued ahead of it.
56120
the queue as soon as `queue_conditions` are met.
57121
:::
58122

59-
## Stack-Aware Base
123+
### Stack-Aware Base
60124

61125
Every stacked PR is queued against the **stack root** (e.g. `main`), not its
62126
immediate parent branch. Without this, PR2 would be queued against PR1's head
@@ -88,7 +152,7 @@ strict digraph {
88152
You don't configure this. It's automatic for any PR detected as part of a
89153
stack.
90154

91-
## Stack-Aware Batching
155+
### Stack-Aware Batching
92156

93157
The queue treats a stack as an ordered chain when assembling
94158
[batches](/merge-queue/batches). Two guarantees hold:
@@ -138,7 +202,7 @@ across consecutive batches bottom-first: the first batch validates the deepest
138202
PRs that fit, and once they merge they drop out of the predecessor set, so the
139203
next batch picks up where the previous one stopped.
140204

141-
## Cascade Dequeue
205+
### Cascade Dequeue
142206

143207
If any PR in a queued stack fails validation or is dequeued, every successor
144208
still in the queue is dequeued automatically with the reason
@@ -172,7 +236,7 @@ After fixing the broken PR, re-queue the stack from the top with
172236
merged successfully (lower in the stack) are untouched.
173237
:::
174238

175-
## Limits
239+
### Limits
176240

177241
- **Maximum stack depth: 20.** Stacks deeper than 20 PRs aren't recognized as
178242
a stack by the queue and fall back to per-PR queueing.
@@ -191,3 +255,6 @@ After fixing the broken PR, re-queue the stack from the top with
191255
- [Batches](/merge-queue/batches): batch-size and CI-cost trade-offs.
192256

193257
- [Scopes](/merge-queue/scopes): how stacks interact with monorepo scopes.
258+
259+
- [GitHub Rulesets Compatibility](/merge-queue/github-rulesets): the
260+
`exempt` bypass mode GitHub-native stacks require.

0 commit comments

Comments
 (0)