Skip to main content
Stacked branches (or stacked PRs) are a workflow where you build a chain of dependent branches, each one based on the previous. This lets you break large changes into small, reviewable pieces without waiting for each PR to merge before starting the next.

The Problem

Without stacking, you either:
  • Wait: Finish PR 1, wait for review and merge, then start PR 2. Slow.
  • Branch from main: Start PR 2 from main, duplicate or conflict with PR 1’s changes. Messy.
  • Stack manually: Create PR 2 on top of PR 1’s branch, but then juggle rebasing when PR 1 changes. Error-prone.

How gx Solves It

gx tracks parent-child relationships between branches and automates the rebasing, pushing, and bookkeeping:
When feature/auth changes (new commits, or after code review updates), gx sync --stack rebases the entire chain in order and pushes all branches.

Workflow

1. Create the stack

2. Visualize

3. Sync after changes

When you update a branch (e.g., address PR review feedback on feature/auth):
This rebases feature/tests and feature/dashboard in sequence, then pushes all three.

4. Navigate

Move through the stack without remembering branch names:

5. Retarget after merge

When feature/auth is merged into main, retarget feature/tests:
This rebases feature/tests onto main, pushes, updates the config, and retargets the GitHub PR.

6. Clean up

The stack.json Format

gx stores stack relationships in .git/gx/stack.json:

Fields

Key Properties

  • Stored in .git/gx/: Not tracked by git, local to each clone
  • Auto-created: First gx stack call creates it if missing
  • Read-only tree building: BuildTree reads stack.json but never writes to it. Only explicit commands (gx stack, gx sync, gx retarget) modify the config
  • Explicit only: Only branches explicitly created with gx stack appear in the graph. There is no auto-discovery of relationships
  • parent_head for precise rebasing: The parent_head field stores the parent’s HEAD SHA at the time of the last sync, enabling precise --onto rebasing