惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
J
Java Code Geeks
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
M
MIT News - Artificial intelligence
U
Unit 42
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
I
InfoQ
WordPress大学
WordPress大学
H
Help Net Security
D
Docker
B
Blog
腾讯CDC
A
About on SuperTechFans
Recent Announcements
Recent Announcements
雷峰网
雷峰网
有赞技术团队
有赞技术团队
C
Check Point Blog
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Graphite blog

Introducing Code Tours: a new way to review Introducing Cursor Cloud Agents in Graphite Building the future of software development with Cursor Reimagining the PR Page: Designing for speed and focus Graphite changelog [11-20-2025] Graphite changelog [11-04-2025] Graphite changelog [10-16-2025] The future of engineering is collaborative (and already here) Meet Graphite Agent: the next evolution of AI code review Introducing frozen branches: A safer way to build on your teammates’ work Graphite changelog [09-17-2025] How we sped up code search for Graphite Chat Introducing Graphite Chat AI is writing code—here's why it also needs to review that code How I got Claude to write code I could actually ship How we built the first stack-aware merge queue (and why it matters) How we organize our monorepo to ship fast Graphite brings stacking to Tower Code review tooling: Should you build or buy? Making AI code review available to everyone Introducing: The new Graphite + Linear integration Graphite raises $52M and launches Diamond to reimagine code review for the age of AI Why AI will never replace human code review How stacked PRs unblock distributed development teams Graphite is going to Developer Week 2025 Beating the end of year code freeze How Graphite’s eng team ships code remarkably fast Why we chose Anthropic's Claude to power Graphite Reviewer AI code generation will remain fragmented How we redesigned Graphite's landing page in-house
Why large companies and fast-moving startups are banning ...
Greg Foster · 2023-11-07 · via Graphite blog

Cursor Cloud Agents are now in Graphite. Create, review, and ship without leaving your PR.

author

Greg Foster

Nov 6, 2023

As a developer creating pull requests in a git repo, you almost certainly use one of two distinct workflows for integrating changes from one branch into another: merging or rebasing. There are three key points in the development process where you need to do this:

  1. Updating your code change before merging to trunk: you can either rewrite the initial change commit or create a second commit on your feature branch

  2. Pulling in changes from the trunk branch to your outstanding branch: you can either rebase your branch onto the latest updates from trunk or generate a “merge commit” on your branch.

  3. Merging your changes into the trunk branch: you can either craft a merge commit that links your branch’s history with the trunk or rebase your branch onto the trunk. This latter approach simulates the instant creation of your feature as fresh trunk commits, rendering the separate branch obsolete.

Merge vs. rebase has long been a hotly debated topic among developers, but the recent popularity of trunk-based development among fast-moving companies is starting to tip the scales in favor of rebase.

Over the past decade, more and more closed-source repos have started banning merge commits on trunk and shifting to a squash-rebase-and-merge workflow. The benefits are clear: rebasing creates a cleaner, more understandable history & state of the world without the clutter of merge commits. Trunk branches remain linear, and branches function as brief, atomic diffs off the trunk. Some operations become more complex (largely due to incomplete/missing Git tooling), but the end state is a tidier history.

In a context where there's no single trunk and branches are long-lived (i.e. open-source development), forking and merging hold more significance. However, in closed-source development, having one authoritative source of truth (the trunk branch) with small, transient changes avoids the pain of merging a long-lived feature branch. Google's 2016 paper Why Google Stores Billions of Lines of Code in a Single Repository describes this well:

Trunk-based development is beneficial in part because it avoids the painful merges that often occur when it is time to reconcile long-lived branches. Development on branches is unusual and not well supported at Google, though branches are typically used for releases. Release branches are cut from a specific revision of the repository. Bug fixes and enhancements that must be added to a release are typically developed on mainline, then cherry-picked into the release branch (see Figure 6). Due to the need to maintain stability and limit churn on the release branch, a release is typically a snapshot of head, with an optional small number of cherry-picks pulled in from head as needed. Use of long-lived branches with parallel development on the branch and mainline is exceedingly rare.

Figure 6. Release branching model.

credit: Rachel Potvin, Josh Levenberg

Lastly, rebasing makes reverting much less painful, especially as projects grow to contain a larger and larger history. Merge commits have more than one parent, and Git doesn’t automatically know which parent was the trunk, and which parent was the branch you want to un-merge. The squash, rebase, and merge strategy leaves you with a single commit in main that’s easily revertible without running git revert --help.

The most common critique of the rebase workflow can be boiled down to inadequate support from native Git and GitHub. Rebase commands can be intimidating to execute, and recovering previous commit versions often requires unnerving dives into the Git ref-log. Even with everything done right, a rebase-centric workflow will flood your GitHub PR timeline with force push events. These force pushes happen even when you've merely rebased your changes onto a newer trunk, leaving the diff unchanged.

Despite these hurdles, rebasing is slowly gaining acceptance as the superior workflow for closed-source development; it just requires better tooling. One notable example of rebase-centric tooling is Phabricator, Facebook’s internal code review platform. Phabricator enforces a single trunk branch per repo, and developers create atomic “diffs” off of the trunk branch, which are then rebased onto trunk once tested and approved.

Measuring the shift towards rebase

Even without specialized internal tooling, rebasing is quickly becoming the preferred workflow for fast-moving teams. Based on data from the tens of thousands of repos where engineers are using Graphite, over 60% of large repos (more than 10k PRs) ban merge commits. Notably, these large repos are more than twice as likely to ban merge commits than small repos with less than 10k PRs (sample size 217 large repos, 48,560 small repos).

From a sample of 2k repos with a minimum of 1k pull requests, we can see that newer repos are also more reliably banning merge commits.

While the merge vs. rebase debate will almost certainly continue to rage across Twitter & HN for years to come, it’s pretty clear that large tech companies and the next wave of fast-moving startups are increasingly banning merge commits in favor of a rebase-centric workflow.

Rebasing can be scary

While the trend is clear more and more developers are moving away from merge commits, rebasing manually with the git CLI can be intimidating at first. Rebase commands can be intimidating to execute, and recovering previous commit versions often requires unnerving dives into the git ref-log. Even with everything done right, GitHub floods your feature branch timeline with “force push” events. This occurs even when you've merely rebased your changes onto a newer trunk, leaving the diff unchanged.

Luckily however there is tooling in place that can automate away a lot of the complexity associated with manually rebasing your changes. Using the Graphite CLI for instance, you can "stack" dependent PRs on top of one another, and the CLI will automatically, recursively rebase the entire stack for you upon upstream changes. This makes it easy to keep your branches in sync without having to deal with messy merge conflicts, while also helping you avoid merge commits in favor of the squash-rebase-merge workflow.

Rebasing is scary, but it doesn't have to be. Join the thousands of other companies already banning merge commits, and try out the squash-rebase-merge workflow today.

Related articles