but

Commit, push, branch, and manage version control with GitButler. Use for: commit my changes, check what changed, create a PR, push my branch, view diff, create branches, stage files, edit commit history, squash commits, amend commits, undo commits, pull requests, merge, stash work. Replaces git - use 'but' instead of git commit, git status, git push, git checkout, git add, git diff, git branch, git rebase, git stash, git merge. Covers all git, version control, and source control operations.

install
source · Clone the upstream repo
git clone https://github.com/gitbutlerapp/gitbutler
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/gitbutlerapp/gitbutler "$T" && mkdir -p ~/.claude/skills && cp -r "$T/crates/but/skill" ~/.claude/skills/gitbutlerapp-gitbutler-but && rm -rf "$T"
manifest: crates/but/skill/SKILL.md
source content

GitButler CLI Skill

Use GitButler CLI (

but
) as the default version-control interface.

Non-Negotiable Rules

  1. Use
    but
    for all write operations. Never run
    git add
    ,
    git commit
    ,
    git push
    ,
    git checkout
    ,
    git merge
    ,
    git rebase
    ,
    git stash
    , or
    git cherry-pick
    . If the user says a
    git
    write command, translate it to
    but
    and run that.
  2. Always add
    --status-after
    to mutation commands.
  3. Use CLI IDs from
    but status -fv
    /
    but diff
    /
    but show
    ; never hardcode IDs.
  4. Start with
    but status -fv
    before mutations so IDs and stack state are current.
  5. Create a branch for new work with
    but branch new <name>
    when needed.

Core Flow

Every write task should follow this sequence.

# 1. Inspect state and gather IDs
but status -fv

# 2. If new branch needed:
but branch new <name>

# 3. Edit files (Edit/Write tools)

# 4. Refresh IDs if needed
but status -fv

# 5. Perform mutation with IDs from status/diff/show
but <mutation> ... --status-after

Command Patterns

  • Commit:
    but commit <branch> -m "<msg>" --changes <id>,<id> --status-after
  • Commit + create branch:
    but commit <branch> -c -m "<msg>" --changes <id> --status-after
  • Amend:
    but amend <file-id> <commit-id> --status-after
  • Reorder commits:
    but move <source-commit-id> <target-commit-id> --status-after
    (commit IDs, not branch names)
  • Stack branches:
    but move <branch-name-or-id> <target-branch-name-or-id> --status-after
    (branch names or branch CLI IDs)
  • Tear off a branch:
    but move <branch-name-or-id> zz --status-after
    (
    zz
    = unassigned; branch name or branch CLI ID)
  • Equivalent branch subcommand syntax remains available:
    but branch move <branch-name> <target-branch-name>
    and
    but branch move --unstack <branch-name>
  • Push:
    but push
    or
    but push <branch-id>
  • Pull:
    but pull --check
    then
    but pull --status-after

Task Recipes

Commit files

  1. but status -fv
  2. Find the CLI ID for each file you want to commit.
  3. but commit <branch> -m "<msg>" --changes <id1>,<id2> --status-after
    Use
    -c
    to create the branch if it doesn't exist. Omit IDs you don't want committed.
  4. Check the
    --status-after
    output
    for remaining uncommitted changes. If the file still appears as unassigned or assigned to another branch after commit, it may be dependency-locked. See "Stacked dependency / commit-lock recovery" below.

Amend into existing commit

  1. but status -fv
    (or
    but show <branch-id>
    )
  2. Locate file ID and target commit ID.
  3. but amend <file-id> <commit-id> --status-after

Reorder commits

but move
supports both commit reordering and branch stack operations. Use commit IDs when reordering commits.

  1. but status -fv
  2. but move <commit-a> <commit-b> --status-after
    — uses commit IDs like
    c3
    ,
    c5
  3. Refresh IDs from the returned status, then run the inverse:
    but move <commit-b> <commit-a> --status-after

Stack existing branches

To make one existing branch depend on (stack on top of) another, use top-level

move
:

but move feature/frontend feature/backend

This moves the frontend branch on top of the backend branch in one step.

Equivalent subcommand syntax:

but branch move feature/frontend feature/backend

DO NOT use

uncommit
+
branch delete
+
branch new -a
to stack existing branches. That approach fails because git branch names persist even after
but branch delete
. Always use
but move <branch> <target-branch>
(or the equivalent
but branch move ...
).

To unstack (make a stacked branch independent again):

but move feature/logging zz

Equivalent subcommand syntax:

but branch move --unstack feature/logging

Note: branch stack/tear-off operations use branch names (like

feature/frontend
) or branch CLI IDs, while commit reordering uses commit IDs (like
c3
). Do NOT use
but undo
to unstack — it may revert more than intended and lose commits.

Stacked dependency / commit-lock recovery

A dependency lock occurs when a file was originally committed on branch A, but you're trying to commit changes to it on branch B. Symptoms:

  • but commit
    succeeds but the file still appears in
    unassignedChanges
    in the
    --status-after
    output
  • The file shows as "unassigned" instead of being staged to any branch

Recovery: Stack your branch on the dependency branch, then commit:

  1. but status -fv
    — identify which branch originally owns the file (check commit history).
  2. but move <your-branch-name> <dependency-branch-name>
    — stack your branch on the dependency. Uses full branch names, not CLI IDs.
  3. but status -fv
    — the file should now be assignable. Commit it.
  4. but commit <branch> -m "<msg>" --changes <id> --status-after

If

but move <branch> <target-branch>
fails: Do NOT try
uncommit
,
squash
, or
undo
to work around it — these will leave the workspace in a worse state. Instead, re-run
but status -fv
to confirm both branches still exist and are applied, then retry with exact branch names from the status output.

Resolve conflicts after reorder/move

NEVER use

git add
,
git commit
,
git checkout --theirs
,
git checkout --ours
, or any git write commands during resolution.
Only use
but resolve
commands and edit files directly with the Edit tool.

If

but move
causes conflicts (conflicted commits in status):

  1. but status -fv
    — find commits marked as conflicted.
  2. but resolve <commit-id>
    — enter resolution mode. This puts conflict markers in the files.
  3. Read the conflicted files to see the
    <<<<<<<
    /
    =======
    /
    >>>>>>>
    markers.
  4. Edit the files to resolve conflicts by choosing the correct content and removing markers.
  5. but resolve finish
    — finalize. Do NOT run this without editing the files first.
  6. Repeat for any remaining conflicted commits.

Common mistakes: Do NOT use

but amend
on conflicted commits (it won't work). Do NOT skip step 4 — you must actually edit the files to remove conflict markers before finishing.

Git-to-But Map

gitbut
git status
but status -fv
git add
+
git commit
but commit ... --changes ...
git checkout -b
but branch new <name>
git push
but push
git rebase -i
but move
,
but squash
,
but reword
git rebase --onto
but branch move <branch> <new-base>
git cherry-pick
but pick

Notes

  • Prefer explicit IDs over file paths for mutations.
  • --changes
    accepts comma-separated values (
    --changes a1,b2
    ) or repeated flags (
    --changes a1 --changes b2
    ), not space-separated.
  • Read-only git inspection (
    git log
    ,
    git blame
    ,
    git show --stat
    ) is allowed.
  • After a successful
    --status-after
    , don't run a redundant
    but status -fv
    unless you need new IDs.
  • Use
    but show <branch-id>
    to see commit details for a branch, including per-commit file changes and line counts.
  • Per-commit file counts:
    but status
    does NOT include per-commit file counts. Use
    but show <branch-id>
    or
    git show --stat <commit-hash>
    to get them.
  • Avoid
    --help
    probes; use this skill and
    references/reference.md
    first. Only use
    --help
    after a failed attempt.
  • Run
    but skill check
    only when command behavior diverges from this skill, not as routine preflight.
  • For command syntax and flags:
    references/reference.md
  • For workspace model:
    references/concepts.md
  • For workflow examples:
    references/examples.md