Git And Collaboration Workflows

Stacked Pull Requests And Merge Queues

A stacked pull request workflow splits a large change into dependent branches that can be reviewed in order. A merge queue serializes approved changes against a current base.

Why This Matters

Small reviews reduce cognitive load, but dependency chains introduce rebasing, base-branch, and merge-order work. These are hosting and team workflows built on Git, not a single core Git feature.

Working Model

Each stack branch is based on the previous branch. Reviewers compare one layer at a time. After a lower layer changes or merges, higher layers must be restacked. A merge queue retests candidate combinations before updating the protected branch.

Practical Rules

  • Make each layer independently understandable and as buildable as practical.
  • Set each pull request base to the preceding branch until that layer merges.
  • Describe dependency order prominently.
  • Use range-diff or platform tooling after restacking.
  • Keep stacks short enough that reviewers can follow ownership and rollout.

Failure Modes

  • Calling stacked PRs a new Git primitive.
  • Opening many dependent branches without a merge and restack plan.
  • Merging an upper layer before its prerequisites.
  • Assuming approval remains valid after a substantial restack.

Verification

  • Review each layer's diff against its actual base.
  • Run required checks for every layer and queued merge result.
  • Confirm branch deletion does not strand upper layers.
  • Re-request review when restacking changes reviewed behavior.

Official References

What You Should Be Able To Do

After this lesson, you should be able to explain how dependent pull requests and merge queues coordinate review without confusing them with core Git commands, choose a suitable approach for a real PHP project, and verify the result instead of relying on assumptions.

Stacking Splits Large Work Into Reviewable Dependencies

A stacked pull request workflow breaks a large change into a sequence of dependent branches. Instead of one enormous branch that modifies infrastructure, domain code, API responses, and templates at once, each branch builds on the previous one. Reviewers can approve the foundation before reading the next layer.

A stack is useful when the work has natural steps: introduce a value object, migrate callers, add a new endpoint, update UI, then remove compatibility code. It is also useful when early pieces can merge before the final feature is enabled. The goal is smaller reviews with clear dependency order.

The Cost Of Stacks

Stacks require discipline. Each branch has a base, and when an early branch changes, later branches may need rebasing. Review platforms vary in how well they display stacked dependencies. CI may test each branch against its immediate base or against the main branch plus earlier stack items. The team must understand the chosen tool.

If a stack becomes ten branches deep and every review change rewrites all of them, the workflow may be too complex. Sometimes a feature flag and two ordinary pull requests are clearer. Use stacks when they reduce review risk, not because they look sophisticated.

Branch Naming And Dependency Clarity

Name stacked branches so their order is visible: refunds/01-schema, refunds/02-domain, refunds/03-api, or a similar convention. Each pull request should link to its parent and child. The description should say whether the branch can merge independently or must wait for the stack.

Keep each branch meaningful. A branch that only renames a variable may not need its own pull request unless it separates a mechanical change from behavior. A branch that changes a public contract should clearly state compatibility and deployment impact.

Rebasing A Stack

When the base branch moves, rebase from the bottom of the stack upward. After rewriting an early branch, update the branches that depend on it. Use range-diff or your stacking tool's comparison view to show reviewers what changed. Force-push with lease and communicate rewrites.

Conflict resolution in a stack can be repetitive. git rerere may help, but inspect reused resolutions. A conflict resolved correctly for branch two may not be correct after branch three changes the surrounding code.

Merge Queues With Stacks

A merge queue tests candidate merges before updating the protected branch. With stacks, the queue needs to respect dependency order. Merging a child before its parent usually makes no sense. Some tools automatically retarget children after parents merge; others require manual updates.

If the queue squashes each pull request, think about how commit messages and release notes will read. A stack can preserve a clear sequence in review but become several squash commits on main. That is often fine if each squash commit has a useful message.

Testing Each Layer

Each stacked branch should have enough tests for its layer. A schema branch might include migration validation and compatibility tests. A domain branch includes unit or integration tests. An API branch includes request/response behavior. Waiting until the final branch for all tests makes earlier approvals less meaningful.

Also test the final combined stack before release. Passing each branch in isolation does not always prove the whole feature works, especially when flags, migrations, generated clients, or UI behavior span branches.

Review Etiquette

Authors should tell reviewers where to start and what is intentionally deferred. Reviewers should avoid asking branch one to solve concerns already handled in branch three unless the earlier branch is unsafe on its own. Everyone needs the stack context.

When a lower branch changes after review, mark dependent branches as needing another look. A small foundation change can alter assumptions above it. Range-diff is the author's tool for making that re-review efficient.

When Not To Stack

Do not stack for tiny independent fixes. Do not stack to bypass review size limits while hiding one inseparable change. Do not stack when the team lacks tooling and the dependency management will confuse reviewers. The workflow should reduce coordination cost overall.

After this lesson, you should be able to split large work into dependent pull requests, name and document stack order, rebase and communicate stack changes, combine stacks with merge queues, test each layer and the final result, and decide when a stack is more complexity than the change deserves.

Keeping A Stack Healthy

A healthy stack has a visible base, a clear order, and small pull requests that each leave the project in a valid state. If branch two cannot pass tests until branch five lands, the stack is not giving reviewers reliable evidence. Use feature flags, compatibility shims, or narrower slices to make intermediate states safe.

When review changes an early branch, update dependent branches promptly. Do not let child pull requests continue collecting comments on code that no longer matches their parent. A short comment such as "rebased children after schema review; range-diff shows only constructor naming changes" saves reviewers time.

Stacks also need an exit plan. After the parent branches merge, retarget or rebase children. Delete merged branches. Remove temporary compatibility code in a later branch with its own tests. Otherwise the stack may merge successfully while leaving cleanup work invisible.

Practice Exercise

Create a three-branch stack in a disposable repository. The first branch adds a small helper, the second uses it, and the third removes an old path. Open or simulate reviews in that order. Then change the helper in branch one and rebase the child branches. Inspect the diffs reviewers would now need to reread.

Next, imagine a merge queue testing the parent branch while the child branch waits. Write down when the child should be retargeted and which checks must rerun. This exercise makes stack maintenance visible before the workflow is used for urgent production work.

Splitting Work Safely

The safest stack starts with changes that are useful on their own. A database compatibility branch can merge before code depends on it. A refactor branch can introduce a new abstraction while preserving old behavior. A later branch can switch callers, and a final branch can remove the old path.

Avoid stacks where early branches knowingly break the application. If a branch cannot pass tests without later branches, reviewers have to reason about an invisible final state. That defeats the purpose of stacking. Use temporary adapters, flags, or no-op compatibility layers so each merge point is deployable.

For public APIs, keep compatibility explicit. A stack that changes a request shape in branch one and updates clients in branch four may be unsafe if branch one can merge alone. Reviewers should be able to approve a parent branch without reading every child branch first. If the parent is safe only because of future work, the stack order is wrong or the branch needs a guard. The merge queue can enforce tests, but it cannot infer product intent. When in doubt, draw the stack as a list with base branches and merge order. If the drawing is hard to explain, the branch structure is too clever for routine collaboration. The stack should make review smaller, not merely distributed. Prefer clarity over theoretical elegance. Keep dependencies explicit.

Practice

Practice: Split A Large Change

Split a schema change, repository refactor, API behavior change, and UI update into a reviewable stack.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Use ordered branches for compatible schema groundwork, internal repository refactor, API behavior, then UI consumption. Document dependencies and keep each layer deploy-compatible where possible.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Restack After Review

The first branch in a four-branch stack changes after review. Plan the update.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Update the first branch, rebase each higher branch in order onto its revised parent, resolve conflicts layer by layer, run checks, use range-diff, force-push with leases, and tell reviewers which layers changed materially.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Use A Merge Queue

Two approved pull requests pass independently but conflict when merged close together. Explain how a merge queue helps.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

The queue creates or evaluates a candidate based on the latest protected branch plus queued changes, reruns required checks, and merges only a passing candidate. It reduces stale-base races but does not replace meaningful tests.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.