GitButler ⧓

GuidesCLI Tutorial

Edit commit history

Amend, squash, uncommit, move, and split commits with the GitButler CLI.

GitButler gives each history-editing task a focused command. Start with but status -fv when you need commit IDs and the file IDs inside each commit:

but status -fv

Use the IDs shown in your own output. Commit IDs with a change ID remain stable across history edits; a SHA-based ID can change when GitButler rewrites history.

Amend uncommitted changes

Use but amend when new work belongs in an existing commit. First inspect the uncommitted changes and history:

but diff
but status

Then pass the uncommitted file or hunk IDs as positional sources and select the commit with -t:

but amend -t nn q3 w7:5

This adds file q3 and hunk w7:5 to commit nn. If you target a branch instead, GitButler amends its newest commit:

but amend -t user-bookmarks q3

Squash commits

To combine a newer commit with an older target commit, pass the source commit first and the target with -t:

but squash ss -t nn -m "Add bookmark validation"

The source commit disappears and its changes become part of the target. Pass -m when squashing commits so GitButler doesn't open an editor.

To collapse every commit on one branch into a single commit:

but squash user-bookmarks -m "Add user bookmarks"

Uncommit work

Use but uncommit to move a whole commit back to the uncommitted area:

but uncommit nn

To uncommit one file from a commit, get its committed-file ID from but status -f, then combine the commit and file IDs:

but uncommit nn:a

The rest of commit nn stays committed.

Move commits

If a commit landed on the wrong branch, move it to another branch's tip:

but move nn -b liked-tweets

If liked-tweets doesn't exist, GitButler creates it as an independent branch.

You can also reorder commits on a branch. --below makes the source older than the target, while --above makes it newer:

but move ss --below nn
but move ss --above nn

Move a branch above another branch to turn two independent branches into a stack:

but move liked-tweets --above user-bookmarks

Move a file between commits

Run but status -f to get committed-file IDs:

but status -f

Move file a out of commit nn and into commit mm:

but squash nn:a -t mm

When the source is a committed file, GitButler keeps the target commit's message.

Split a commit

For a top commit, the cleanest split is to uncommit it and create replacement commits from selected changes.

  1. Uncommit the source and inspect the resulting file and hunk IDs:

    but uncommit nn
    but diff
  2. Create the replacement commits from oldest to newest:

    but commit -b user-bookmarks -m "Add bookmark model" q3 w7
    but commit -b user-bookmarks -m "Validate bookmark URLs" p8:5

Changes you don't name remain uncommitted. If the source commit has other commits above it, those commits may need to be moved back to the branch tip after you create the replacements.

Add an empty placeholder commit

An empty commit can reserve a place in history for work you plan to amend later:

but commit --empty --below nn -m "Add bookmark error handling"

When the implementation is ready, inspect its change IDs and amend them into the placeholder:

but diff
but amend -t ee q3 w7

In but status, --above places the placeholder on the line above the target (newer), while --below places it on the line below (older).

Next, learn how to change commit messages and branch names.

Last updated on

On this page

Edit on GitHubGive us feedback