TL;DR:

  • GitButler introduces virtual branches — you can work on multiple independent changes simultaneously without ever running git checkout or git stash
  • All your uncommitted work lives on a single local branch; GitButler handles the logical separation and pushes each virtual branch as a real remote branch when you are ready
  • Best for solo developers and small teams who frequently juggle multiple PRs or need to context-switch without losing flow
  • Not a full replacement for Git — it works alongside your existing tools and repos, and has some rough edges on complex merges

Every developer has been there. You are mid-feature, three files modified, deep in flow — and a Slack message arrives asking for a quick hotfix. You stash your changes, pray you remember what you were doing, switch branches, make the fix, switch back, pop the stash, and spend five minutes reconstructing your mental context. Git stash is technically a solution. It does not feel like one.

GitButler is a bet that this entire workflow is broken by design, and that virtual branches are the fix.

The Core Problem with Traditional Git Branch Switching

Git’s branch model was built around the assumption that you work on one thing at a time. In practice, developers juggle multiple workstreams constantly — a feature branch, a bug fix, a dependency upgrade, a quick doc change that came out of a code review. The tooling to manage this — stash, worktrees, WIP commits, branch naming conventions — is a collection of workarounds rather than a coherent solution.

The deeper issue is that git checkout operates on the working directory. Switching branches changes files on disk, which means any uncommitted work either gets carried along (risky), stashed (lossy context), or committed prematurely (messy history). None of these feel right.

What Virtual Branches Actually Do

GitButler’s core insight is to decouple the logical concept of a branch from the working directory state. Here is the key mental model: you have one working directory, but multiple virtual branches that each “own” a subset of your current changes.

When you modify a file, GitButler tracks which virtual branch that hunk belongs to. You can drag hunks between branches, create a new branch and pull changes into it, or mark certain files as belonging to a specific branch. None of this involves touching the actual working directory — GitButler handles all of that in the background.

When you push, GitButler takes a virtual branch, constructs the real commits, and pushes to the remote as a proper Git branch with a real history. From GitHub or GitLab’s perspective, it looks completely normal. From your perspective, you never switched branches.

The underlying mechanism uses a shadow branch system — your local HEAD stays on a single “workspace” branch, and GitButler maintains metadata about how your changes are partitioned. It is not rebasing in real-time; it builds the branches on demand at push time or when you explicitly apply one.

Setup: macOS, Windows, and Linux

GitButler ships as a desktop application. Download the installer from gitbutler.com — native packages for macOS (Apple Silicon and Intel), Windows (x64), and Linux (AppImage and .deb).

Installation is standard: download, install, open. GitButler does not replace your system Git installation; it sits alongside it and operates on existing repositories.

To start using it on a project, open the app, click “Add Local Repo,” and point it at any directory with a .git folder. GitButler reads your existing branches and remotes. You do not need to migrate anything or restructure your workflow — it integrates into whatever you already have.

One dependency: GitButler requires Git 2.34 or later. Most modern macOS and Linux setups are fine; Windows users on older machines may need to update via git-scm.com first.

Core Workflow: Virtual Branches in Practice

Creating a virtual branch — in the GitButler UI, click “New Branch” in the left panel. Give it a name. It does not create a Git branch yet — it creates a virtual lane in GitButler’s workspace.

Assigning changes — as you edit files, GitButler shows modified hunks in the center panel. You drag a hunk to a virtual branch lane, or right-click to assign it. Whole-file assignment works too. Changes not assigned to any branch sit in an “uncommitted” pool you can deal with later.

Pushing a branch — when a virtual branch is ready for review, click “Push.” GitButler constructs the commit history and pushes to your configured remote. A PR is ready to open. Meanwhile, your other virtual branches and uncommitted work stay exactly as they were — nothing moved, nothing was lost.

Continuing work — you keep editing. New changes flow into whatever virtual branch you have active, or into the uncommitted pool. You can keep multiple virtual branches “in progress” simultaneously and push them independently at any time.

Integration with GitHub, GitLab, and Gitea

GitButler supports GitHub and GitLab natively — you can open PRs, view PR status, and see CI results directly from the app without switching to a browser. The GitHub integration requires a personal access token (classic or fine-grained); GitLab uses OAuth.

Gitea integration exists but is more limited — push and remote management work fine, but the in-app PR view does not support Gitea’s API. For Gitea users, the practical workflow is push from GitButler, then manage PRs in the Gitea web UI.

Bitbucket is not natively integrated as of mid-2026, though it works fine as a plain Git remote.

How It Compares to Alternatives

Git Worktrees solve a similar problem by creating multiple working directories pointing to the same repository. This is Git-native and requires no additional tooling, but it means managing multiple filesystem paths and editor windows. It works well for long-lived parallel branches; it is awkward for the “quick fix while mid-feature” scenario because you are still switching mental contexts between directories.

Jujutsu (jj) is a more radical rethink of version control that also allows simultaneous changes across branches with superior merge tracking and conflict resolution. It is better-engineered than GitButler at a fundamental level, but requires fully adopting a new VCS mental model and toolchain. GitButler is an incremental adoption — Jujutsu is a paradigm shift. If you are willing to invest in learning jj, it is arguably the better long-term bet; GitButler is the better choice if you want to improve your workflow tomorrow without relearning anything.

Who Benefits Most

GitButler is a strong fit for solo developers who frequently juggle multiple open PRs, want to keep a hotfix branch ready without disturbing feature work, or find themselves using stash constantly. The UI is polished enough that the overhead of using it is genuinely lower than the alternatives.

For small teams, it works well if everyone adopts it — branch naming stays conventional, remotes look normal, PRs work as expected. Partial adoption within a team does not cause problems; GitButler is invisible to teammates who use standard Git.

For large teams with complex merge policies, strict branch protection rules, or rebase-heavy workflows, GitButler may have friction. The “construct commits at push time” model can occasionally produce unexpected histories on fast-moving shared branches. Test the workflow on a non-critical repo before rolling it out broadly.

The honest summary: GitButler does not solve every Git pain point, and it is still maturing. But for the specific problem of context switching between in-progress work, it is the most practical solution available right now — one that requires almost no commitment to try.