Read Anthropic’s case study about Graphite Reviewer

Benefits of stacked diffs in code review

Greg Foster
Greg Foster
Graphite software engineer
Try Graphite

This guide includes a comprehensive and deeply technical exploration of the concept of stacked diffs and how they can significantly improve the code review process.

A stacked diff is a series of related code changes organized into distinct, incremental patches, each built on top of the previous one. Instead of submitting one massive, monolithic pull request (PR) or code review, stacked diffs break the total scope of changes into multiple, logically cohesive segments. Each segment (or "diff") is reviewed and merged in sequence. The result is a "stack" of patches where subsequent diffs depend on the previously approved ones.

How it works conceptually:

Imagine you need to refactor a large subsystem with many interdependent changes. Instead of pushing a single PR that reorganizes code, updates APIs, and modifies tests all at once, you:

  1. Introduce a small foundational change (e.g., add a new interface).
  2. On top of that, introduce another incremental change (e.g., refactor a single class to use the new interface).
  3. Then another incremental change builds on the previous ones (e.g., update another class, or refine the newly introduced interface based on feedback).

By the end, you have a series of PRs that build upon each other. Reviewers tackle them in sequence, merging each only once it passes code review and CI checks.

  1. Reduced Cognitive Load for Reviewers

    • Problem: Large PRs are often difficult and time-consuming to review. Reviewers must hold a lot of context in their minds at once, from understanding the initial motivations to following through on every code path.
    • Solution through stacking: Each stacked diff focuses on a self-contained, conceptually smaller change. Reviewers can easily grok a smaller patch without needing to mentally parse a broad swath of unrelated changes. This reduces the time needed to provide thoughtful feedback and lowers the likelihood of missing important details.
  2. Improved iteration speed

    • Problem: When you submit a large PR and receive feedback, changes may be scattered throughout the code, requiring multiple incremental updates to the same PR. This can lead to confusion over what has already been reviewed, what changed recently, and what remains to be done.
    • Solution through stacking: With stacked diffs, feedback on one layer can be integrated without blocking progress on entirely separate layers. If the first diff needs revision, you fix it and re-request review. Meanwhile, other diffs further up the stack remain unchanged and do not require reviewers to re-parse code not affected by the feedback. This keeps iteration tight and efficient.
  3. Earlier detection of issues

    • Problem: In a single massive PR, structural or architectural issues might be discovered only late in the review process, at which point significant rework is needed.
    • Solution through stacking: Early diffs in the stack often introduce foundational structures, interfaces, or abstractions. Reviewing and refining these building blocks early ensures that subsequent diffs build on a stable, agreed-upon foundation. This leads to fewer large-scale rewrites once later issues are discovered.
  4. Inherent documentation of the change narrative

    • Problem: A single large change can obscure the reasoning behind the refactoring or new feature, making it less clear why certain architectural decisions were made.
    • Solution through stacking: Each incremental diff can be accompanied by a focused commit message and review description. Over time, this creates a narrative of the change that is easier to follow. Future maintainers can trace the evolution of the feature or refactor step-by-step, understanding the rationale for each incremental improvement.
  5. Parallelization of review efforts

    • Problem: Large PRs create bottlenecks. The entire team waits on one big, complex code review.
    • Solution through stacking: While certain layers may still depend on the acceptance of previous ones, different team members can focus on different layers of the stack in parallel (assuming earlier diffs are sufficiently stabilized). For example, a frontend lead can start reviewing a UI-related diff after the underlying backend API diff is stable, while a domain expert focuses on the backend abstractions in another diff. This can improve throughput and reduce time-to-merge.
  6. Integration with Continuous Integration (CI) Systems

    • Problem: When you push a large change, your CI might run the full suite of tests and checks on code that’s both stable and experimental. This can slow feedback loops and complicate build artifacts.
    • Solution through stacking: Each stacked diff can be tested and validated independently. You can ensure that the foundational layers are robust before moving on to more complicated or dependent layers. CI runs become a series of smaller, more targeted validations, making it easier to pinpoint regressions and integration issues earlier in the lifecycle.
  1. Branching strategy A common approach is:

    • Have a main (e.g., master or main) branch.
    • Create a feature branch for the first foundational diff.
    • For subsequent changes, branch off of the previous feature branch rather than main. This ensures your new diff only includes the changes from that previous layer, producing a well-isolated, incremental diff.

    Example:

    Terminal
    main
    ├─> feature/base-refactor
    ├─> feature/add-interface (built on top of feature/base-refactor)
    ├─> feature/refactor-class (built on top of feature/add-interface)
  2. Tooling support While you can manage stacked diffs manually through Git branches, specialized tools can simplify the workflow. Key capabilities to look for:

    • Automatically rebase child diffs when a parent diff changes.
    • Visibility into which diffs are ready for review vs. which are waiting on dependencies.
    • CI pipelines that can trigger incrementally.
  3. Maintaining a clear review flow To ensure reviewers understand the flow:

    • Document the intended diff order clearly, either in a top-level meta-PR or in a dedicated README section.
    • Label PRs or commits with an order indicator (e.g., [1/x], [2/x] in commit messages).
    • Include links between dependent diffs in PR descriptions.
  4. Handling rebase conflicts and dependencies

    • When a lower diff changes, you may need to rebase subsequent diffs on top of the updated code.
    • Good CI and review tooling can show exactly which diffs need re-review due to changes in their parent diffs.
    • Maintaining crisp commit boundaries and orthogonal changes reduces the risk and frequency of conflicts.

With tools like Graphite, managing stacked diffs becomes significantly easier. Graphite provides purpose-built features for developers who want to organize their changes into logical stacks without manual overhead. Its intuitive UI and CLI workflows ensure smooth coordination, rebase handling, and dependency tracking, which can otherwise be tedious with plain Git workflows.

  1. Utilize Graphite's CLI for consistent workflows

Graphite's CLI helps maintain the integrity of stacked diffs with commands for creating, updating, and merging branches in sequence. Use commands like gt branch create, gt stack rebase, and gt stack merge to enforce proper dependencies and avoid common pitfalls.

  1. Take advantage of Graphite's automation

Use Graphite's automated rebase handling to reduce the overhead of conflict resolution across stacks. Its real-time feedback and CI integration ensure that every layer is stable before the next is merged.

  1. Collaborate effectively with Graphite's review tools

Graphite's PR inbox highlights critical diffs requiring attention, tracks review status, and shows clear links between related PRs. Teams can prioritize reviews more effectively, ensuring steady progress.

Stacked diffs introduce a structured, incremental approach to code review. They allow developers and reviewers to tackle large changes methodically, reduce cognitive load, improve iteration speed, and produce more maintainable, high-quality code. With careful management, tools like Graphite, and good communication, stacked diffs can transform your code review process from a daunting slog into a more streamlined and efficient workflow.

Built for the world's fastest engineering teams, now available for everyone