Plain Git lets you work on one branch at a time. An urgent fix means stashing your work, switching branches, and switching back. Tidying history means an interactive rebase, where one wrong step can lose work or leave you stuck in a conflict. That friction adds up every day, and it gets worse when AI agents make changes faster than you can sort them into branches.
GitButler is a Git client, with a desktop app and a but CLI, that runs on top of your normal Git repository. It removes most of that friction, and your remote still sees ordinary Git branches and commits.
You can have several branches applied in the same working directory. You make changes, then assign each file or hunk to the branch it belongs to. An urgent fix no longer means putting your feature away.
You are halfway through a feature when a bug report comes in. You stash your work, switch to main, create a fix branch, fix the bug, commit, push, switch back, pop the stash, and then resolve a stash conflict.
❌ Figure: Bad example - Plain Git - the stash-and-switch dance breaks your flow for every small fix
You fix the bug in the same working directory and assign the fix to a new branch. Your feature changes stay exactly where they are.
✅ Figure: Good example - GitButler - the fix gets its own branch without leaving your feature
When one change builds on another, you can stack branches. Each branch becomes its own small, focused pull request instead of one large one. When you change a lower branch, GitButler rebases the branches above it for you.
Amending an older commit, squashing, reordering, and moving changes between commits are drag and drop in the desktop app. GitButler rebases everything above the edit automatically. You end up with a history that tells a clear story, without git rebase -i.
GitButler takes a snapshot before every operation, including your uncommitted work. If something goes wrong, you restore an earlier snapshot. Trying things stops being scary.
When a rebase hits a conflict, GitButler still finishes it. It marks the conflicted commits so you can resolve them later, in any order. The rest of your work stays usable in the meantime.
Several AI agent sessions can work in the same folder at once. Each agent uses the but CLI to commit only the changes for its own task to its own branch. You don't need a separate worktree, dependency install, and dev server per agent.
2 agent sessions work in the same folder on plain Git. One adds checkout validation and the other fixes a caching bug. When both finish, git status shows one mixed list of changes, and you split them into 2 branches by hand.
❌ Figure: Bad example - Plain Git - 2 agents in one folder produce one mixed diff
3 agent sessions work in the same folder with GitButler. Each one commits its own changes to its own branch. You end up with 3 focused branches, each ready for its own pull request.
✅ Figure: Good example - GitButler - 3 agents in one folder produce 3 clean branches
This works best when the agents work on different parts of the code. When two agents will edit the same files, give each one its own Git worktree instead.
GitButler can write commit messages, branch names, and pull request descriptions with AI. It also creates pull requests on GitHub and GitLab.
gitbutler/workspace branch and installs Git hooks that block git commit on it. Switching branches with plain Git takes you out of GitButler until you set it up againgitbutler/workspace branch instead of the branch you are working onIf it doesn't suit you, but teardown takes the repository back to plain Git.
but instead of Git?AI agents know plain Git very well, so they reach for git commit and git checkout by habit. In a GitButler workspace, those commands fight GitButler. Tell the agent to use but, then back that up with a guard.
Run but agent setup in the repository. It installs the GitButler skill for agents such as Claude Code, Codex, Cursor, and GitHub Copilot, and can write version-control instructions for them.
Put the policy where every agent reads it, so it applies in every session:
## Version controlThis repository uses GitButler. Use the `but` CLI for every change to branches and commits.Never run `git commit`, `git checkout`, `git switch`, `git stash`, `git rebase`, `git reset`, or `git merge`.Read-only Git commands such as `git log` and `git diff` are fine.
Instructions steer an agent, but they don't stop it. In Claude Code, add deny rules to .claude/settings.json. A deny rule wins over any allow rule:
{"permissions": {"deny": ["Bash(git commit *)","Bash(git checkout *)","Bash(git switch *)","Bash(git stash *)","Bash(git rebase *)","Bash(git reset *)","Bash(git merge *)"]}}
GitButler's own pre-commit hook is the last line of defence. It rejects git commit on the workspace branch and tells the agent how to fix it.