Inspecting and Diffing
Looking at commits, branches and work in progress with GitButler
When you're working with projects, sometimes you'll need to inspect things to see what the differences are or summarize work.
The first thing to remember is that GitButler is basically an advanced Git client, which means that you can use any Git inspection command without problems when you're using GitButler.
This includes things like git show, git diff, git log, git blame, git bisect, etc. So we have not tried to recreate the functionality of these, but instead focused on some of the common needs in a modern workflow that these tools may not do well.
Let's look at a simple scenario.
╭┄zz [unstaged changes] ┊ g0 M Gemfile ┊ h0 M README.md ┊ ┊╭┄us [user-bookmarks] ┊● fde72a6 add user changes ┊│ fd:0 M app/models/user.rb ┊● 85efe19 create bookmarks ┊│ 85:0 A app/controllers/bookmarks_controller.rb ┊│ 85:1 A app/views/bookmarks/index.html.erb ├╯ ┊ ┴ 32a2175 (common base) [origin/main] 2025-11-03 Merge pull request #65 from schacon/feature-bookma(checked 15 seconds ago) Hint: run `but diff` to see uncommitted changes and `but stage <file>` to stage them to a branch
Here we have an unstaged file (Gemfile), a file staged to the user-bookmarks branch (README.md), and two commits on our branch.
Diffing things
For most of this, you could use git diff. For example, to see everything that is uncommitted, you can just run git diff.
diff --git c/Gemfile w/Gemfile index 5cd27fa8..5c76922c 100644 --- c/Gemfile +++ w/Gemfile @@ -21,7 +21,7 @@ gem "jbuilder" # gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] +gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable gem "solid_cache" @@ -42,7 +42,7 @@ gem "thruster", require: false group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + gem "debug", platforms: %i[ mri mingw mswin x64_mingw ], require: "debug/prelude" # Static analysis for security vulnerabilities [https://brakemanscanner.org/] gem "brakeman", require: false diff --git c/README.md w/README.md index 32fb79f3..57d59121 100644 --- c/README.md +++ w/README.md @@ -76,6 +76,6 @@ bundle exec rubocop This project is open source and available under the [MIT License](LICENSE). -## New Stuff +## Even More New Stuff -New stuff is always coming +New stuff is always coming, and more is on the way!
However, I don't find that a super readable format, even if it's useful in applying with the Unix patch command. Since most people tend not to be emailing patches around, we tried to optimize for a much more human readable format:
──────────╮ i0 Gemfile│ ──────────╯ 21 21│ # gem "bcrypt", "~> 3.1.7" 22 22│ 23 23│ # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 24 │-gem "tzinfo-data", platforms: %i[ windows jruby ] 24│+gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] 25 25│ 26 26│ # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable 27 27│ gem "solid_cache" ──────────╮ j0 Gemfile│ ──────────╯ 42 42│ 43 43│ group :development, :test do 44 44│ # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem 45 │- gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" 45│+ gem "debug", platforms: %i[ mri mingw mswin x64_mingw ], require: "debug/prelude" 46 46│ 47 47│ # Static analysis for security vulnerabilities [https://brakemanscanner.org/] 48 48│ gem "brakeman", require: false ────────────╮ k0 README.md│ ────────────╯ 76 76│ 77 77│ This project is open source and available under the [MIT License](LICENSE). 78 78│ 79 │-## New Stuff 79│+## Even More New Stuff 80 80│ 81 │-New stuff is always coming 81│+New stuff is always coming, and more is on the way!
You can see that this is the same information, but a bit more easily understandable.
You can also focus the diff output to any of the short codes in that status output. For example, to just see what is staged to user-bookmarks you can run but diff l0. To only see the changes committed to the bookmarks controller file in the "create bookmarks" commit you can run but diff n0, to only see what modifications have not been staged you can run but diff zz, and so on.
Listing Branches
When GitButler creates and modifies branches, it is manipulating real Git branches, so you can see them and inspect them with normal Git commands as well. While you can use the git branch command to see all your branches, the but branch command is a bit nicer.
Here is what git branch might output (this example repo has over 100 branches, so let's just truncate it):
update-homepage2 gitbutler/edit update-homepage sc-switch-wording-to-x sc-lefty-branch * gitbutler/workspace user-bookmarks move-second-commit squash-example sc-tests-controllers
This output is actually better than the default Git output for this, because I have a config setting of branch.sort -comitterdate, so at least it's showing me the branches by last commit rather than the default of alphabetically.
The but branch command, however, is built specifically to help you identify the branches you're looking for and give you some useful information about them. Let's give it a try:
Applied Branches 00 active ✓ *user-bookmark… 1w ago Scott Chacon Unapplied Branches 01 local ✓ update-homepage2 ↑2 today Scott Chacon 02 local ✓ update-homepage ↑3 1w ago Scott Chacon 03 local ✓ sc-switch-wording-to-x ↑2 1w ago Scott Chacon 04 local ✓ sc-lefty-branch ↑1 1w ago Scott Chacon 05 local ✓ move-second-commit ↑1 1w ago Scott Chacon 06 local ✓ squash-example ↑1 1w ago Scott Chacon 07 local ✓ sc-tests-controllers ↑1 2w ago Scott Chacon 08 local ✓ sc-likes ↑1 3w ago Scott Chacon 09 local ✓ sc-bookmarks-comments2 ↑2 3w ago Scott Chacon 0a local ✓ docs-tests-likes-bookmarks ↑1 2mo ago Scott Chacon 0b local ✗ sc-branch-30 ↑3 2mo ago Scott Chacon 0c local ✗ sc-branch-29 ↑1 2mo ago Scott Chacon 0d local ✓ gitbutler/worktree/2c7f3480… ↑1 2mo ago Scott Chacon 0e remote ✓ test ↑1 2mo ago Scott Chacon 0f local ✓ new-branch ↑0 3mo ago Scott Chacon 0g local ✓ new-branch2 ↑0 3mo ago Scott Chacon 0h local ✓ new-branch3 ↑0 3mo ago Scott Chacon 0i local ✓ test-branch-delete-me ↑4 3mo ago GitButler 0j local ✓ feature-a-frontend ↑3 3mo ago Scott Chacon 0k local ✓ feature-a-backend ↑1 3mo ago Scott Chacon ... and 121 more branches (use --all to show all)
You can immediately notice that this is a very different type of listing. We're not just showing the names of the branches, but also some very useful information about all of the branches that are available to us.
First, we show any applied branches - these are the branches that are currently applied into your workspace. Next, all the unapplied branches - that is, the other branches that you don't currently have active in your working directory.
For each branch, you'll see how many commits "ahead" it is, that is, how many commits are on that branch that are not on the target branch (eg origin/main). In other words, if this branch were merged to production, what would come in with it?
There is also a "✓" or "✗" that indicates if this branch is cleanly mergeable with your target branch.
It also shows the last author of a commit on that branch and orders everything by how long ago the last commit was.
The point of this listing is to help you easily see what work you have available, not merged into your target, that you might want to work on.
Filtering your Branches
Running but branch defaults to running but branch list, which has a bunch of other options (filtering to only local or remote branches, not calculating mergability for speed, etc). The most useful option might be the filtering, for example, you can type a partial match string and it will filter the output:
Applied Branches 00 active ✓ *user-bookmark… 1w ago Scott Chacon Unapplied Branches 01 local ✓ sc-bookmarks-comments2 ↑2 3w ago Scott Chacon 02 local ✓ docs-tests-likes-bookmark… ↑1 2mo ago Scott Chacon 03 local ✓ feature-bookmarks ↑0 4mo ago Scott Chacon
Looking at a Branches
If you want to see what is on a branch, you can inspect a specific branch by running but branch show <branch>. This will show the commits on this branch ahead of your target.
Essentially, it runs the equivalent of git log origin/main..<branch> with some more introspection.
commit 464aae4d905fc53df7a1a5d02f86ae8117b3a92b
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Oct 9 11:39:50 2025 +0200
add user changes
commit ca81308347d2fbaba043227f8de79aa34fc6132a
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Oct 9 11:39:41 2025 +0200
create bookmarks
Now let's look at but branch show
Branch: feature-awesome-thing (2 commits ahead) 464aae4 add user changes 2025-10-09 11:39:50 by Scott Chacon 2 files changed, 27 insertions, 0 deletions ca81308 create bookmarks 2025-10-09 11:39:41 by Scott Chacon 4 files changed, 131 insertions, 2 deletions
Pretty much a short log of the branch difference from our target branch. However, there are a bunch of options if you want to dig in further.
The -r option will show you PR information if one is opened on this branch. The -f option will show you the files modified in each commit.
The real fun one is adding --ai, which will take a look at the changes and summarize what the changes actually do.
Let's run all of them at the same time:
Branch: sc-branch-28 (#59) (2 commits ahead) 0294f53 rest 2025-10-23 12:05:58 by Scott Chacon 2 files changed, 90 insertions, 2 deletions Gemfile (+2, -2) app/views/bookmarks/index.html.erb (new file, +88) 85d5e67 routes 2025-10-23 12:05:58 by Scott Chacon 1 file changed, 5 insertions, 0 deletions config/routes.rb (+5, -0) Reviews: PR/MR: #59 Title: The Best Pull Request Probably Ever Made URL: https://github.com/schacon/why/pull/59 Description: This is one of the greatest Pull Requests that has ever been made. You will cower in fear of it's awesomeness. AI Summary: Add basic bookmarks UI and route configuration. This branch updates the Gemfile and introduces a new bookmarks index view to display bookmarks, and modifies routes to wire up the bookmarks resource. Overall it lays groundwork for a bookmarks feature by adding the front-end listing and necessary routing.
Showing a Commit
If you want to look at a specific commit in any of these circumstances, you can use the but show command with the commit hash.
Commit: a42580b96ed7b432ac9906f3685e99014bb12c0e Change-ID: yltmulxpvktwwmkzrmtmztwtkwskvzzu Author: Scott Chacon <schacon@gmail.com> Date: 2026-01-24 16:24:29 +0100 (1w ago) add user changes Files changed: M app/models/user.rb
Deleting Branches
As long as we're talking about branches, let's show how to get rid of them. If you've merged one, it will by default not be shown anymore with but branch anyhow, but if you have one with some work on it that you want to abandon, you can also easily delete it with but branch delete (or -d).
Last updated on