gitbutlerapp/gitbutler8 files

But

Commit, push, branch, and manage version control with GitButler. Use for commits, selective dirty-file or hunk commits, branches, diffs, PRs, history edits, squashes, amends, undo, merge, apply, and unapply. For selected dirty files or hunks, inspect with `but diff`; use compact `but status` for commit order, branch/stack placement, or conflict overview; use `but status -fv` when file/hunk IDs or per-commit file details matter. Replaces git write commands.

Specification
Skill ID
gitbutlerapp/gitbutler/but
Publisher
gitbutlerapp
Repository
gitbutler
Installs
0
Files
8
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

gitbutlerapp/gitbutler/butInstalls these files
  • AGENTS.md
  • CLAUDE.md
  • README.md
  • SKILL.md
  • references/concepts.md
  • references/examples.md
  • references/reference.md
  • stub.md

What this skill tells the agent

GitButler CLI Skill

Use GitButler CLI (but) as the default version-control interface.

Start Here

Choose the narrowest first command by task; avoid ritual status checks:

# Selected dirty files/hunks:
but diff

# Commit order, branch/stack placement, conflict overview:
but status

# File/hunk IDs, per-commit files, amend/split details:
but status -fv

# Details for one known branch or commit:
but show <id>

Do not run plain but status and then but status -fv unless the compact output lacks file/hunk details needed for the task.

For "commit just/only/specific changes on a new branch", use the fast path:

but diff
but commit -b <branch> -m "<msg>" <id> <id>

but commit -b <branch> ... creates the branch when it does not exist and prints the created commit. Do not run a separate but branch new, status command, or verification diff unless the task needs workspace information that the result does not provide.

IDs

The first token on each but diff / but status line is that line's ID. When a command needs an ID, copy it exactly from the current output; never hardcode or invent one. ID lifetimes differ by entity:

  • Changes and sources are positional, space-separated IDs (but commit -b feat -m "msg" uvw:2e4 uvw:e2c). An uncommitted hunk ID is written <file-id>:<hunk-id> (e.g. uvw:2e4, copied from bare but diff) — the part after the colon is the hunk's ID, not a line range (uvw:16-40 is invalid). Do not invent flags like --changes / --hunk / --ids, pass a line range, or comma-separate IDs — uvw,qyo is parsed as one ID and fails.
  • but diff is the exception: it accepts at most one target. Bare but diff shows all uncommitted files; inspect committed files or other entities one target at a time — never but diff <id> <id>.
  • A committed file is <commit-id>:<file-id> (e.g. mzm:uvw, shown under each commit). A committed hunk is <commit-id>:<file-id>:<hunk-id> and is shown by but diff <commit-id>. @ means the uncommitted area.
  • Commit IDs are stable change IDs that survive history edits (amend, squash, move, uncommit, reword). Commits without a change ID (e.g. upstream-only) lead with a sha prefix instead, and #N-suffixed refs disambiguate duplicates — both go stale after history edits, and a stale sha can silently resolve to the wrong commit. The (sha …) on verbose commit lines is informational — do not pass it to commands.
  • Branch short IDs are snapshot-local selectors. Use full branch names for branch-targeting mutations; short IDs are safe only for immediate read-only inspection.
  • File/hunk IDs copied from one diff read generally remain usable across chained commits. If one stops resolving, re-read but diff and retry.

Chaining: mutation output is concise by default, so you may chain mutations with && off one inspection read. Do not chain branch short IDs through mutations; use full branch names. Add --status-after only when the next step needs workspace IDs or details that the mutation result does not provide. Chained but commit calls stack in the order written — the first is oldest, each later one goes on top. History edits may run in sequence when every commit ref involved is a change-ID ref; run them one at a time with --status-after when a ref is sha-based or #N-suffixed, or when the next command needs freshly issued IDs. Chaining but uncommit <id> && but diff is safe because bare diff needs no ID from the uncommit output.

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. Running from a worktree acts on the main workspace, the same as running from the main worktree; address that worktree's own changes as <worktree>:@. but setup refuses to run from a worktree.
  2. Mutation commands print their result without appending workspace status. Add --status-after only when the next step needs resulting workspace IDs or details; otherwise trust the mutation result and do not run a verification status/diff.
  3. Branches marked (merged upstream) have landed; run but pull to remove them, or start new work on another branch. push and mutations (commit, amend, squash, uncommit, reword, move) refuse landed branches and commits, absorb skips them with a notice, and commit skips them when picking a default target.
  4. In non-interactive CLI workflows, do not narrate progress between routine commands. Execute the needed but commands and give a concise final summary.
  5. Prefer this skill and but skill reference over exploratory help calls. Use <command> --help when required syntax is missing or a command fails; use top-level help only when you genuinely need to discover an undocumented command.

Command Patterns

  • Commit: but commit -b <branch> -m "<msg>" <id> <id> — -b <branch> creates the branch if it does not exist
  • Commit everything uncommitted: but commit -b <branch> -m "<msg>" (omit the IDs)
  • Several commits from one diff: chain but commit calls with && (commits stack oldest-first)
  • Commit at a specific history position: --above <commit-or-branch> or --below <commit-or-branch> (mutually exclusive). With a branch target, add -b <new-name> to name the new branch; otherwise its name is generated. The name must not already exist. Do not combine -b (even without a name) with commit/worktree targets.
  • Targeting is required when more than one stack is applied; without it but commit fails with "Unclear where to commit. Found more than one stack". Several branches stacked together count as one stack — an untargeted commit then silently lands on the stack's top branch, so pass -b whenever the branch matters.
  • Always pass -m "<msg>" (or --no-message) to but commit, and to but squash whenever its sources are commits or branches unless the target is @ — those compose a new message; without a flag an agent run keeps whatever the command composed (empty for but commit, the joined source messages for but squash) and a terminal opens an editor. Squash sources that are uncommitted or committed changes reuse the target's message and need no flag; squashing into @ rejects message flags outright.
  • Amend: but amend -t <commit-or-branch> <file-or-hunk-id> <file-or-hunk-id> — a branch target resolves to its newest commit
  • Uncommit: but uncommit <commit-id> (whole commit), but uncommit <branch> (all commits and remove branch), but uncommit <commit-id>:<file-id> (committed file), or but uncommit <commit-id>:<file-id>:<hunk-id> (committed hunk); committed files and hunks may be mixed, but all must come from one commit
  • Insert empty commit: but commit --empty -b <branch> -m "<msg>"
  • Pick onto a new named branch: but pick <commit-sha> --above <branch> -b <new-name> (--below also works). The name must not exist; -b cannot be combined with commit/worktree targets.
  • Squash commits: but squash <source-commit-id> [<source-commit-id>...] -t <target-commit-id> -m "<msg>"
  • Move committed changes into an existing commit or @: but squash <commit-id>:<file-id> -t <commit-id-or-@> for a committed file; but squash <commit-id>:<file-id>:<hunk-id> -t <commit-id-or-@> for a committed hunk; all sources must come from one commit
  • Move committed changes into a new commit at a chosen position: but move <commit-id>:<file-id> --above <commit-or-branch> -m "<msg>" for a committed file; but move <commit-id>:<file-id>:<hunk-id> --above <commit-or-branch> -m "<msg>" for a committed hunk (--below, --branch, and --unstack also work)
  • Split selected committed changes into a new commit immediately above their source: but split <committed-file-or-hunk-id> [<committed-file-or-hunk-id>...] -m "<msg>"

Use this skill in a project

Open any RiverX project, search the Skills panel for gitbutlerapp/gitbutler/but, and install it in one click.

Use this skill