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

推荐订阅源

H
Help Net Security
S
Secure Thoughts
I
Intezer
Project Zero
Project Zero
Stack Overflow Blog
Stack Overflow Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Full Disclosure
P
Proofpoint News Feed
T
The Exploit Database - CXSecurity.com
人人都是产品经理
人人都是产品经理
博客园_首页
J
Java Code Geeks
Recorded Future
Recorded Future
K
Kaspersky official blog
GbyAI
GbyAI
S
Schneier on Security
The Cloudflare Blog
Spread Privacy
Spread Privacy
C
Cisco Blogs
The Hacker News
The Hacker News
博客园 - 三生石上(FineUI控件)
H
Hackread – Cybersecurity News, Data Breaches, AI and More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
Know Your Adversary
Know Your Adversary
T
Tenable Blog
A
Arctic Wolf
Blog — PlanetScale
Blog — PlanetScale
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
O
OpenAI News
Last Week in AI
Last Week in AI
B
Blog RSS Feed
T
Troy Hunt's Blog
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
Vercel News
Vercel News
量子位
The Register - Security
The Register - Security
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
U
Unit 42
Security Archives - TechRepublic
Security Archives - TechRepublic
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News and Events Feed by Topic

Butler's Log

Agentic Version Control Benchmarks Grit: rewriting Git in Rust with agents Git Merge 2026 Agent-safe Git with GitButler We’ve raised $17M to build what comes after Git Announcing the GitButler CLI for Linux The Great CSS Expansion A couple of git nits Simplifying Git by Using GitButler Introducing the GitButler CLI GitButler 0.19 - "Commander Keen" But Head: Crafting a Custom Font MCP vs RAG: Two Very Different Ways to Gain Context Getting Started With GitButler Agents Using the GitButler MCP Server to Build Better AI-Driven Git Workflows Using GitButler With Multiple GitHub Accounts Advent of Code! Upcoming GitButler Events Use GitButler for your Gerrit workflow Integrating GitButler and GitHub Enterprise Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 3 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 2 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 1 Grid Happens: Because Flexbox Wasn’t Enough Using Cursor Hooks for automatic version control Deep Dive into the new Cursor Hooks A Responsive Item Counter with CSS only GitButler 0.16 - "Sweet Sixteen" GitButler's Claude Code tab GitButler's Annual Open Source Pledge Report Git Mini Summit 2025 Videos Automate Your AI Workflows with Claude Code Hooks Managing Multiple Claude Code Sessions Without Worktrees GitButler 0.15 - "Quirky Quinceañera" 20 years of Git. Still weird, still wonderful. GitButler's new patch based Code Review (Beta) Going down the rabbit hole of Git's new bundle-uri How to do patch-based review with git range-diff How Core Git Developers Configure Git Why is Git Autocorrect too fast for Formula One drivers? Stacked Branches with GitButler Git Merge 2024 Talks are Up GitButler 0.13 - "Lucky Baseball" Git Merge 2024 Why GitHub Actually Won GitButler is joining the Open Source Pledge The New Era of Town Hall Chat The Future of Open Source GitButler is now Fair Source Git Merge 2024 GitButler 0.12 - "Stingy Baker" The Birth of THE MERGE GitButler for Windows Fixing up Git with Autosquash The Git Zeitgeist Git Worktrees and GitButler DevWorld Git Slides Git Tips and Tricks Git Tips 1: Oldies but Goodies Git Tips 2: New Stuff in Git Git Tips 3: Really Large Repositories FOSDEM Git Talk Opening Up GitButler Debugging Tauri in VS Code Advent of GitButler Code Signing Commits in Git, Explained Virtual Branches Alpha Our We Are Developers Adventure Building Virtual Branches DevDays in Vilnius The Future of Software and Open Source Introducing GitButler
Fearless Rebasing
Scott Chacon · 2024-10-23 · via Butler's Log

I have a confession to make. For most of my Git life, I have been a merger.

I have been asked countless times if it's better to merge or to rebase and while I never want to stir up a hornet's nest, I have always advocated merging over rebasing. Not only that, but I have nearly always done so myself when working on a project.

To me, merging has always been better. It keeps more of the history, there are by definition fewer conflicts since it only has to merge the last tree rather than every intermediate tree, it's easier to see what each series actually was, it's easier to see when it was integrated, etc.

However, let's admit it, rebasing is sexy.

Rebasing versus merging, which is better?

I've always loved the idea of a linear history, of rewriting a series until it's perfect and getting that nice useful blame and bisecting power. Getting rid of that subway map history graph in favor of a nice simple series of patches.

But rebasing is also a pain in the ass.

You run rebase --pull and get conflict after conflict and can't do anything else until you're done. You can't save your progress if you get tired of the exercise halfway through. It's also difficult to keep your series clean anyhow - doing fix-up commits, autosquashing, interactive rebasing. Even those of us fairly used to the tooling mess up or get frustrated sometimes. Now compound that with the need for your entire team to feel comfortable with this tooling. Heavy sigh.

Recently, however, I have completely changed my mind. I am now an official rebaser.

The reason is not because I was convinced by someone that I've been wrong this whole time, nor was it because Git's tooling around rebasing got better. It's because of Fearless Rebasing.

One of the things that GitButler has never been very good at so far is merge conflicts. We just didn't have a good story for it because we weren't sure what a good way was to handle it. What is actually an ideal (or even, not horrible) way to deal with merge conflicts?

When researching other tools, I ran across the Jujutsu project that is being developed at Google.

Jujutsu has a novel concept of "first class conflicts", where it can record conflicted states in it's commit objects. Git can't do this. If Git runs into a conflict when trying to merge, rebase or cherry-pick something, it halts everything and makes you fix it before moving forward. It has no way to save the conflict for later resolution and keep going.

But Jujutsu does, which means that every time you do a rebase operation, it is always successful.

How does this work?

When Jujutsu tries to rebase commits and runs into a conflict, instead of writing the conflict out to the working directory and throwing a bunch of status files into your .git directory, it instead writes a specially formatted commit that lists out the trees it attempted to merge, pretends that this commit was not there and continues with the next commits.

This means that you can end up in a state like this, where you have several conflicted commits and then some commits after them that are not in a conflicted state.

Then to resolve the conflicts, you can edit one of the commits and resolve it, which amends that commit and automatically rebases everything above it again.

We loved this concept so much that we decided to implement an approach that is very similar.

When working with a virtual branch, we want to empower you to think about your changes as a series of patches that you can constantly and easily change, amend, squash, split, edit and rebase.

If you can do all of that fearlessly, knowing that everything is easy to do, simple to undo and much more painless to resolve, then that lets us maintain that beautiful and simple history.

In our 0.13 release of GitButler, we are introducing a very similar workflow to rebasing your commits to what Jujutsu does. If you create a series of commits and then rebase it onto new upstream work and there are conflicts, we will always rebase successfully but mark any problematic commits and only apply the parts of them to your working directory that do not conflict.

So let's say that you have three commits in your branch and rebase and the first two have conflict problems. Now we will partially apply them (whichever hunks do not conflict), write a special commit that has a conflicted header, then try the next one.

Now you can solve these conflicts one by one. Even in any order - you don't have to approach the first one first, you can start with the second one if you prefer.

To solve the conflicts, you can click on a commit that is in a conflicted state and click the "Resolve Conflicts" button, which now checks out just those conflicts into your working directory.

It also changes your GitButler UI to let you know you are in this special state and allows you to either abort the session using the "Cancel" button or save your conflicted state and rebase the remaining commits with the "Save" button.

Now the entire rebasing workflow in Git is massively easier. You can solve conflicts whenever you prefer and you can push off the work until you're ready to work on them, even continuing to make new commits while some of your commits are in a conflicted state.

We believe that fearless rebasing is a much nicer way to deal with conflicts. If you want to try it out, download GitButler and see how it feels. Maybe we'll make a rebaser out of you too.

Scott Chacon

Written by Scott Chacon

Scott Chacon is a co-founder of GitHub and GitButler, where he builds innovative tools for modern version control. He has authored Pro Git and spoken globally on Git and software collaboration.