Table of contents
- Historical context and evolution
- What are stacked diffs?
- Benefits of stacked diffs
- Implementing stacked diffs workflow
- Best practices for stacked diffs
- FAQ
Stacked diffs, also known as stacked changes or stacked pull requests, is a workflow concept that involves stacking a series of small, dependent changes atop one another. This method allows developers to review and merge small changes independently, making the code review process more efficient and manageable.
The idea behind stacked diffs is that you can keep working on your main branch, and worry about reviews later
The Pragmatic Engineer
Historical context and evolution
The idea of stacked diffs originated from open-source software development practices, where developers would submit a stack of patches for review. Over time, this practice was formalized into various tools and platforms such as Phabricator (with its Differential tool) and Critique (Google's internal code review tool). These platforms allowed developers to easily manage and review stacks of changes.
What are stacked diffs?
Stacked diffs refer to a series of changes where each change depends on the previous one. Each 'diff' in the stack is a small, self-contained change that builds upon the change before it. This contrasts with the traditional model where large changes are reviewed in a single, monolithic pull request.
While the concept is powerful, managing stacked diffs manually can be complex. Modern tools like Graphite have simplified this process significantly, allowing developers to create, manage, and sync entire stacks of branches with simple commands like gt stack submit
and gt stack sync
—eliminating the need for manual Git gymnastics.
Benefits of stacked diffs
The stacked diffs approach offers several advantages over traditional code review methods:
Improved focus: Reviewers can focus on small parts of the codebase, making it easier to spot issues and understand the context of changes.
Faster feedback loop: Smaller changes can be reviewed and merged more quickly, leading to a faster feedback loop between developers and reviewers.
Easier management: Dependencies between changes are explicitly defined, making it easier to manage and track the progression of features or fixes.
Reduced merge conflicts: By frequently merging small changes, the likelihood of significant merge conflicts is reduced.
Incremental testing: Each change can be tested independently, which helps in identifying the cause of regressions or bugs.
Implementing stacked diffs workflow
To implement a stacked diffs workflow, developers must understand how to break down their work into small, incremental changes. Tools like Graphite, which extend the functionality of version control systems like Git, provide command-line interfaces (CLIs) to facilitate this process.
Key components and concepts:
Branch stacking: Creating branches for each diff that are based on the branch of the previous diff.
Pull requests (PRs): Each diff in the stack corresponds to a PR, which is reviewed independently. Graphite's
gt stack submit
command can submit your entire stack as PRs with a single command.Automatic rebasing: Tools can automatically rebase the stack as diffs are merged, ensuring that each PR is up to date with the base branch. Graphite excels here with its smart rebasing feature that automatically handles dependency changes and stack visualization through
gt log short
.Testing: Each diff should pass all tests before it is merged, ensuring that the main branch remains stable. Graphite's
gt stack sync
command helps keep your stack up-to-date with the main branch, reducing the likelihood of conflicts.
Best practices for stacked diffs
When implementing stacked diffs, following these practices will help ensure success:
Keep diffs small: Each diff should represent a single, coherent change. This makes reviews faster and reduces the chance of introducing bugs.
Ensure dependencies are clear: Make sure that the dependency chain is clear and logical. Tools like Graphite help with this by providing commands like
gt restack
to reorganize your stack when needed.Maintain a stable base branch: The base branch should always be in a deployable state. Use
gt stack sync
to keep your stack up-to-date with the main branch.Frequent communication: Developers and reviewers should communicate frequently to ensure that diffs are reviewed in a timely manner.
Leverage automation: Use tools that automate the tedious parts of stack management. For example, Graphite's
gt branch create
automatically handles branch dependencies, whilegt stack submit
can submit your entire stack as PRs with a single command.
Conclusion
Stacked diffs represent a powerful paradigm shift in the code review process, promoting faster, more focused, and efficient workflows. By implementing a stacked diffs workflow, teams can improve their productivity and code quality, ultimately leading to a more agile development process. Tools like Graphite are at the forefront of this shift, providing the necessary infrastructure to support stacked diffs in modern development environments.
FAQ
What is the difference between stacked diffs and Git?
Git is a version control system that tracks changes to files over time, while stacked diffs is a workflow methodology that uses Git (or other version control systems) to organize code changes. Think of Git as the foundation—it handles the technical aspects of storing and managing code changes. Stacked diffs is a strategy that leverages Git's branching capabilities to create a series of small, dependent changes that can be reviewed and merged independently. Tools like Graphite build on top of Git to make stacked diffs workflows easier to manage.
What are stacked branches?
Stacked branches are a series of Git branches where each branch depends on the previous one in the stack. For example, if you're working on a feature that requires multiple steps, you might create:
feature-step-1
(based on main)feature-step-2
(based on feature-step-1)feature-step-3
(based on feature-step-2)
Each branch contains a small, logical change that builds upon the previous branch. This creates a dependency chain where changes can be reviewed and merged incrementally, rather than as one large change.
What are diffs in programming?
A "diff" (short for difference) in programming refers to the changes made between two versions of code. It shows what was added, removed, or modified. In the context of stacked diffs, each "diff" represents a small, self-contained change that can be reviewed independently. When you create a pull request, you're essentially showing a diff between your branch and the target branch. Stacked diffs take this concept further by organizing multiple related diffs into a logical sequence, making complex changes easier to understand and review.