GitButler: An Approach to Git Branch Management

GitButler is a new desktop and CLI Git client built by Scott Chacon - GitHub co-founder, author of the Pro Git book - and Markus Feilner. Its central claim is that the problem with Git isn't the object model, the network transport, or the merge algorithm. The problem is that Git forces you to think in branches before you work, when the natural flow of development pushes in the opposite direction.


Here's what actually happens when you're deep in a codebase fixing a bug: you find the bug, you fix it, and somewhere in the process of working on that code, you notice three other things: a related problem in the same subsystem, a method that's doing too much, and a dependency that should have been upgraded six months ago. None of these are in scope for the branch you're on: all of them might be genuinely worth addressing.

The textbook answer is branch discipline: finish what you started, commit it, open a PR, then create a new branch for each of the other concerns. That's "good advice" - it's the right way to do it, probably, but it also requires you to hold those other threads in suspension while you tie off the first one - context-switching costs, stash gymnastics if you've already poked at something, and the very real risk that the other things simply don't get done because the moment passed.

Discipline can help: maybe you create issues and record requirements as you notice them. That at least allows you to track the problems, and solve them in priority order.

But the tendency is to just fix the things while you're there, let the branch grow a little, and write a commit message that only partially describes what happened. The branch that was supposed to be fix/527/login-timeout ends up touching four subsystems and carrying a dependency bump. When you're tracking the fix for the stream allocation, it's hard to find in the logs, because it wasn't fix/object-allocation-in-collect - it's in that darn login timeout branch. Nobody should be happy about this, but few change their behavior because the alternative feels like more work.

Git gives you the tools to do the right thing. What it doesn't give you is a workflow that makes the right thing feel easier than the wrong thing.


GitButler's approach to this is an inversion of how branching normally works.

In standard Git, a branch is the container you work inside. HEAD points somewhere, and everything you write belongs to wherever HEAD is pointing. To work on two things, you switch branches - which means abandoning your working state, or stashing it, or committing something half-finished just to get out, the (dreaded?) wip commit, for "work in progress."

GitButler treats your working directory as the primary thing. Instead of working inside a branch, you work freely, and then you assign changes to branches. The desktop client shows your in-progress changes as a pool, and you have named lanes - one per logical concern - into which you drag file hunks or whole files. Each lane is a Git branch. When you commit, each branch gets exactly the changes assigned to it and nothing else.

The practical consequence for the scenario above is significant: you can fix the login timeout bug, poke at the stream object allocation problem, and bump the dependency, all in the same working session without switching context. When you're ready to commit, you assign the login fix to one lane, the stream allocation change to another, and the dependency bump to a third. Three clean branches, ready for three separate PRs, assembled from a single working session.

There's an additional structural guarantee baked into this model. Because your working directory represents the merged state of all your in-progress branches simultaneously, GitButler can guarantee that those branches will integrate cleanly with each other - you already have the merge in front of you. You're not creating branches and hoping they'll combine later; you're factoring branches out of a state where they already coexist.


What does this imply for your actual Git repository?

Not a lot, as it turns out: GitButler operates on a standard Git repo. It maintains an internal reference (gitbutler/workspace) that tracks the combined working state, but your actual branch history, your remotes, your GitHub pull requests - all of that is normal Git. Teammates who don't use GitButler don't need to. The tool is entirely local to your working session.

This is a meaningful design constraint. It means GitButler can't change how your history looks once it's pushed, can't restructure the review process downstream, and doesn't require any team-wide adoption to be useful. You can pick it up for your own workflow on a shared repo and nobody else has to know or care. (They should, but they don't have to.)

It also means the upside is bounded. GitButler is a better abstraction over the pre-push slice of your workflow. Everything after the push - code review, CI, merge strategy, history hygiene - remains exactly as it was. If your team already has good branch discipline, GitButler doesn't change much. If your team struggles with the "one branch, too many concerns" problem, it offers a concrete mechanism for doing better.


Chacon's manifesto for the project argues that source code management tools haven't changed fundamentally in 40 years and that Git is being pressed into service for workflows it wasn't designed for. That may be true, and there's a certain irony in the man who literally wrote the book on Git now building a tool designed so you don't need the book. But the more interesting question isn't whether Git's conceptual model is aging - it's whether the specific friction point GitButler targets is real enough to change behavior.

The "wip" commit is the tell. If your commit history contains commits called "wip," "stuff," "temp," or "checkpoint," that's your SCM failing you at exactly the moment GitButler is designed to address. The tool exists because the friction of doing the right thing - clean, scoped, reviewable branches - currently exceeds the friction of doing the convenient thing. Whether a smarter local client is sufficient to shift that balance is what the next year or two will tell us.

The idea is sound. The problem it solves is real. That's a reasonable starting point, and with new SCM tools coming out as "competitors to git" to fix behavioral problems, maybe this is indeed a real problem looking for the right solution.

Comments (2)

Sign in to comment

andrew at April 10, 2026

I think this is missing the forest for the branches about what GitButler is though? Perhaps not talking about the a16z investment is an editor choice but the reason why they invested isn't because it's got an interesting take on branching strategy.

Parallel branches are solving the multi-agent problem which worktrees are being used for constantly in the current paradigm. But duplicating the entire repository for every work tree kinda sucks too. That plus all the agent-specific features embedded are I think why this is also interesting

dreamreal at April 10, 2026

That's a really good observation - and it's worth pointing out, too. It didn't occur to me because I don't really use AI worktrees like that, so the impact didn't stand out on the surface.