Use GitButler CLI for efficient branching, committing, and diffing.
Install
mkdir -p .claude/skills/but && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7231" && unzip -o skill.zip -d .claude/skills/but && rm skill.zipInstalls to .claude/skills/but
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
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.Key capabilities
- →Stage specific file hunks for commits
- →Manage multiple branches in a workspace
- →Amend or squash existing commit history
- →Undo recent git operations
- →Create and push branches with PRs
How it works
The tool replaces standard Git write commands with a specialized CLI that manages commit order, branch placement, and history edits through stable change IDs.
Inputs & outputs
When to use but
- →Stage specific file hunks for commits
- →Manage multiple branches in a workspace
- →Amend or squash existing commit history
- →Undo recent git operations
About this skill
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 barebut diff) — the part after the colon is the hunk's ID, not a line range (uvw:16-40is invalid). Do not invent flags like--changes/--hunk/--ids, pass a line range, or comma-separate IDs —uvw,qyois parsed as one ID and fails. but diffis the exception: it accepts at most one target. Barebut diffshows all uncommitted files; inspect committed files or other entities one target at a time — neverbut 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 bybut 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 diffand 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
- Use
butfor all write operations. Never rungit add,git commit,git push,git checkout,git merge,git rebase,git stash, orgit cherry-pick. If the user says agitwrite command, translate it tobutand run that. Running from a linked worktree shows the same workspace and IDs as the main worktree, and@still means the main worktree's changes; a barebut commitorbut difftakes that worktree's changes, and<worktree>:@names them from anywhere.but setuprefuses to run from a worktree. - Mutation commands print their result without appending workspace status. Add
--status-afteronly when the next step needs resulting workspace IDs or details; otherwise trust the mutation result and do not run a verification status/diff. - Branches marked
(merged upstream)have landed; start new work on another branch. That marker alone does not meanbut pullremoves them: runbut pull --checkfirst.but pullremoves only branches listed[integrated]("has been integrated upstream and removed locally") and rebases the rest, which stay applied. To clear a landed branch that stays applied, usebut unapply <branch>(acts on its whole stack;but apply <branch>restores it) rather thanbut discard.pushand mutations (commit,amend,squash,uncommit,reword,move) refuse landed branches and commits,absorbskips them with a notice, andcommitskips them when picking a default target. - In non-interactive CLI workflows, do not narrate progress between routine commands. Execute the needed
butcommands and give a concise final summary. - Prefer this skill and
but skill referenceover exploratory help calls. Use<command> --helpwhen 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 commitcalls 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 commitfails 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-bwhenever the branch matters. - Always pass
-m "<msg>"(or--no-message) tobut commit, and tobut squashwhenever 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 forbut commit, the joined source messages forbut 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), orbut 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>(--belowalso works). The name must not exist;-bcannot 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--unstackalso 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>" - For
but splitand committed-changebut move, use-m/--messageto name the new commit directly; repeated-mvalues are joined with blank lines. Omitting it creates an empty-message commit without opening an editor.but move -mrejects whole-commit and branch sources. - Squash a whole branch into one commit:
but squash <branch> -m "<msg>"(no-t) - Uncommit and remove a branch:
but uncommit <branch> - Reorder commits:
but move <commit-id> --below <commit-id>(--abovefor the other direction; commit IDs, not branch names) - Reorder a block:
but move <commit-id> <commit-id> --below <following-commit-id>or--above <preceding-commit-id>(both anchors accept multiple space-separated sources) - Move commit to branch top:
but move <commit-id> -b <branch> - Move commits or committed changes onto a new named branch:
but move <source> --above <branch> -b <new-name>(--belowalso works); usebut move <source> --unstack -b <new-name>for an independent branch. Omit-bfor a generated name. Naming is not supported when stacking or unstacking a branch source. - Stack branches:
but move <branch-name> --above <target-branch-name>(use full branch names) - Tear off a branch:
but move <branch> --unstack - Discard:
but discard <id> [<id>...]— accepts branches, commits, committed changes, uncommitted changes, or@for all uncommitted changes - Push:
but push <top-branch>— pushes the selected branch and its ancestors; to update a stack, select its top branch once and never loop. Barebut pushpushes all unpushed work when run non-interactive
Content truncated.
When not to use it
- →Linked worktrees
- →Conflicted commits when using amend
Limitations
- →Linked worktrees are unsupported
- →Conflicted commits do not support amend
How it compares
It provides a higher-level interface that manages staging and history mutations as atomic operations rather than requiring manual Git index manipulation.
Compared to similar skills
but side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| but (this skill) | 1 | 2mo | Review | Intermediate |
| resolve-conflicts | 81 | 10mo | Review | Intermediate |
| openspec-onboard | 10 | 8mo | Review | Beginner |
| codex-cli-bridge | 9 | 11mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
resolve-conflicts
antinomyhq
Use this skill immediately when the user mentions merge conflicts that need to be resolved. Do not attempt to resolve conflicts directly - invoke this skill first. This skill specializes in providing a structured framework for merging imports, tests, lock files (regeneration), configuration files, and handling deleted-but-modified files with backup and analysis.
openspec-onboard
studyzy
Guided onboarding for OpenSpec - walk through a complete workflow cycle with narration and real codebase work.
codex-cli-bridge
alirezarezvani
Bridge between Claude Code and OpenAI Codex CLI - generates AGENTS.md from CLAUDE.md, provides Codex CLI execution helpers, and enables seamless interoperability between both tools
skill-sync
KyleKing
Syncs Claude Skills with other AI coding tools like Cursor, Copilot, and Codeium by creating cross-references and shared knowledge bases. Invoke when user wants to leverage skills across multiple tools or create unified AI context.
github-workflow-automation
ruvnet
Advanced GitHub Actions workflow automation with AI swarm coordination, intelligent CI/CD pipelines, and comprehensive repository management
git-advanced-workflows
wshobson
Master advanced Git workflows including rebasing, cherry-picking, bisect, worktrees, and reflog to maintain clean history and recover from any situation. Use when managing complex Git histories, collaborating on feature branches, or troubleshooting repository issues.