diff --git a/app/.well-known/api-catalog/route.ts b/app/.well-known/api-catalog/route.ts
index b55007c..17c3dc0 100644
--- a/app/.well-known/api-catalog/route.ts
+++ b/app/.well-known/api-catalog/route.ts
@@ -13,10 +13,10 @@ export function GET(): Response {
title: "Getting Started Guide"
},
{
- href: absoluteUrl("/features/ai-integration/mcp-server"),
+ href: absoluteUrl("/ai-agents/overview"),
rel: "service-doc",
type: "text/html",
- title: "GitButler MCP Server"
+ title: "GitButler AI Agents"
},
{
href: absoluteUrl("/api/search/openapi"),
diff --git a/app/.well-known/mcp/server-card.json/route.ts b/app/.well-known/mcp/server-card.json/route.ts
deleted file mode 100644
index ebb8246..0000000
--- a/app/.well-known/mcp/server-card.json/route.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { absoluteUrl } from "@/app/utils/site"
-
-export function GET(): Response {
- const document = {
- name: "gitbutler-mcp",
- description:
- "GitButler's MCP server is exposed by the local `but mcp` command and helps coding agents checkpoint and organize repository changes.",
- websiteUrl: absoluteUrl("/features/ai-integration/mcp-server"),
- documentationUrl: absoluteUrl("/features/ai-integration/mcp-server"),
- serverInfo: {
- name: "GitButler MCP Server",
- version: "1.0.0"
- },
- transports: [
- {
- type: "stdio",
- command: "but",
- args: ["mcp"]
- }
- ],
- capabilities: {
- tools: [
- {
- name: "gitbutler_update_branches",
- description:
- "Record agent-generated file changes in GitButler so they can be grouped into branches, checkpoints, and commits."
- }
- ]
- }
- }
-
- return Response.json(document, {
- headers: {
- "cache-control": "public, max-age=3600"
- }
- })
-}
diff --git a/app/api/search/openapi/route.ts b/app/api/search/openapi/route.ts
index 3626d43..6f422db 100644
--- a/app/api/search/openapi/route.ts
+++ b/app/api/search/openapi/route.ts
@@ -49,7 +49,7 @@ export function GET(): Response {
content: { type: "string" },
url: {
type: "string",
- examples: [absoluteUrl("/features/ai-integration/mcp-server")]
+ examples: [absoluteUrl("/ai-agents/overview")]
}
},
required: ["id", "type", "content", "url"]
diff --git a/app/components/WebMcpTools.tsx b/app/components/WebMcpTools.tsx
index f174aa6..a0e69e0 100644
--- a/app/components/WebMcpTools.tsx
+++ b/app/components/WebMcpTools.tsx
@@ -75,7 +75,7 @@ export default function WebMcpTools(): null {
properties: {
path: {
type: "string",
- description: "Docs path like /guide or /features/ai-integration/mcp-server."
+ description: "Docs path like /guide or /ai-agents/getting-started."
}
},
required: ["path"]
diff --git a/app/utils/agent-ready.ts b/app/utils/agent-ready.ts
index 6f6d61e..1ff2841 100644
--- a/app/utils/agent-ready.ts
+++ b/app/utils/agent-ready.ts
@@ -37,26 +37,26 @@ Use this skill when you need to explain the first-run GitButler workflow to a us
`
},
{
- id: "gitbutler-mcp-setup",
- name: "GitButler MCP Setup",
- description: "Configure a coding agent to use GitButler's MCP server from the CLI.",
+ id: "gitbutler-ai-agent-setup",
+ name: "GitButler AI Agent Setup",
+ description: "Configure a coding agent to use GitButler's `but` CLI and agent skill.",
type: "documentation",
- content: `# GitButler MCP Setup
+ content: `# GitButler AI Agent Setup
-Use this skill when an agent needs to help a developer connect GitButler to Cursor, VS Code, or Claude Code.
+Use this skill when an agent needs to help a developer organize coding-agent changes with GitButler.
## Recommended flow
-1. Read the MCP setup guide at ${absoluteUrl("/features/ai-integration/mcp-server")} as markdown.
-2. Confirm that the \`but\` CLI is installed before configuring the MCP server.
-3. Use the documented \`but mcp\` stdio transport for agent integrations.
-4. Suggest an automation rule that calls the GitButler MCP tool after file edits.
+1. Read /ai-agents/getting-started as markdown.
+2. Confirm that the \`but\` CLI is installed.
+3. Install or update the GitButler agent skill with \`but skill install\`.
+4. Add baseline version-control instructions so the agent uses GitButler for branching, committing, pushing, and history edits.
## Key references
-- MCP server guide: ${absoluteUrl("/features/ai-integration/mcp-server")}
-- AI overview: ${absoluteUrl("/features/ai-integration/ai-overview")}
-- Claude Code hooks: ${absoluteUrl("/features/ai-integration/claude-code-hooks")}
+- AI agents overview: ${absoluteUrl("/ai-agents/overview")}
+- Getting started: ${absoluteUrl("/ai-agents/getting-started")}
+- Tuning agent behavior: ${absoluteUrl("/ai-agents/tuning-agent-behavior")}
`
},
{
diff --git a/app/utils/discovery.ts b/app/utils/discovery.ts
index c8b8dc6..87fc203 100644
--- a/app/utils/discovery.ts
+++ b/app/utils/discovery.ts
@@ -33,9 +33,9 @@ export function getDiscoveryLinks(): DiscoveryLink[] {
type: "application/openapi+json"
},
{
- href: absoluteUrl("/features/ai-integration/mcp-server"),
+ href: absoluteUrl("/ai-agents/overview"),
rel: "service-doc",
- title: "GitButler MCP Server Docs",
+ title: "GitButler AI Agents Docs",
type: "text/html"
},
{
diff --git a/content/docs/ai-agents/getting-started.mdx b/content/docs/ai-agents/getting-started.mdx
new file mode 100644
index 0000000..5dfa21f
--- /dev/null
+++ b/content/docs/ai-agents/getting-started.mdx
@@ -0,0 +1,103 @@
+---
+title: Getting started
+description: Install `but`, install the GitButler agent skill, and add a baseline version-control policy for coding agents.
+---
+
+This page is for coding agents that can read local instruction files and run
+commands in your repository. The GitButler skill does not give the agent new
+permissions. It tells the agent how to use `but` instead of driving Git through
+checkout, stash, add, commit, and rebase commands.
+
+## Install the `but` CLI
+
+If you already have GitButler Desktop installed, you can install the CLI from
+the Desktop Client settings. For terminal-only setup, run:
+
+```sh
+curl -fsSL https://gitbutler.com/install.sh | sh
+```
+
+See [Installation and setup](/cli-guides/installation) for the full CLI install
+options.
+
+## Install the GitButler skill
+
+Run the installer from the same repository:
+
+```sh
+but skill install
+```
+
+The installer prompts for scope first: current repository or global home
+directory. It then prompts for the skill format. Current formats include Agent
+Skills (`.agents/skills`), Claude Code, OpenCode, Codex, GitHub Copilot, Cursor,
+and Windsurf.
+
+For custom paths, global installs, non-interactive updates, and skill checks,
+see [`but skill`](/commands/but-skill).
+
+## Set up the repository
+
+GitButler currently needs the repository in workspace mode for its multi-branch
+model: multiple GitButler branches in one working directory.
+
+From the repository where the agent will work, run:
+
+```sh
+but setup
+```
+
+You can also skip this step and let the agent run `but setup` when it first
+needs GitButler. For the full list of setup changes, see
+[`but setup`](/commands/but-setup).
+
+GitButler is working toward a plain Git mode that switches into a workspace only
+when multiple concurrent branches are needed. Follow
+[gitbutlerapp/gitbutler#11866](https://github.com/gitbutlerapp/gitbutler/issues/11866)
+for that work.
+
+## Add optional agent instructions
+
+The GitButler skill tells the agent how to use `but`. Your own instructions
+tell the agent what behavior you want.
+
+Put project defaults in a repository instruction file such as `AGENTS.md` or
+`CLAUDE.md`. Put personal defaults in a global instruction file such as
+`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, Cursor rules, Copilot custom
+instructions, or the equivalent for your tool.
+
+These files steer agent behavior; they are not access controls. Use your usual
+repository permissions and branch protection for hard limits.
+
+Use this baseline to keep agent work isolated:
+
+```md
+## Version control
+
+- Use GitButler (`but`) for version-control write operations, including
+ branching, committing, pushing, and history edits.
+- Assume multiple agents may be working in this repository. Do not move, amend,
+ squash, discard, commit, push, or otherwise modify another agent's work unless
+ the user asks.
+- Use a dedicated GitButler branch for each agent session, unless the user asks
+ for a different branch structure. Commit only changes that belong to that
+ session.
+- Do not push or open pull requests unless the user asks.
+- Keep commit messages and pull request descriptions succinct: explain what
+ changed, why it changed, and any important decision.
+```
+
+You can also tune the agent to:
+
+- amend local fixes into existing commits;
+- create checkpoint commits and tidy them before review;
+- create stacked pull requests for dependent work;
+- follow your branch and commit naming conventions;
+- publish, update from main, or create recovery points only when your policy
+ allows it.
+
+For copyable snippets, see
+[Tuning agent behavior](/ai-agents/tuning-agent-behavior).
+
+For prompt examples that ask for specific branch and commit outcomes, see
+[Useful requests](/ai-agents/useful-requests).
diff --git a/content/docs/ai-agents/meta.json b/content/docs/ai-agents/meta.json
new file mode 100644
index 0000000..0b09916
--- /dev/null
+++ b/content/docs/ai-agents/meta.json
@@ -0,0 +1,12 @@
+{
+ "title": "AI Agents",
+ "defaultOpen": false,
+ "pages": [
+ "overview",
+ "getting-started",
+ "useful-requests",
+ "parallel-agents",
+ "review-agent-work",
+ "tuning-agent-behavior"
+ ]
+}
diff --git a/content/docs/ai-agents/overview.mdx b/content/docs/ai-agents/overview.mdx
new file mode 100644
index 0000000..ccaf722
--- /dev/null
+++ b/content/docs/ai-agents/overview.mdx
@@ -0,0 +1,56 @@
+---
+title: Overview
+description: Use GitButler to keep coding-agent changes organized into branches and commits you can inspect and review.
+---
+
+Use GitButler with coding agents when you want messy local changes to become
+reviewable branches and commits without moving every task into a separate
+worktree.
+
+GitButler keeps one working directory while organizing changes into separate
+branches and commits. Agents can do that through the [`but` CLI](/cli-overview),
+and you can inspect the same state in the [Desktop Client](/overview). For when
+to use GitButler instead of separate worktrees, see
+[Parallel agents](/ai-agents/parallel-agents#how-this-differs-from-worktrees).
+
+You decide how far the agent goes. You can tell it to stop after local commits,
+or you can allow it to push and open pull requests. GitButler gives the agent
+version-control commands; your instructions decide when it stops.
+
+## What agents can do with GitButler
+
+- **Parallel branches in one workspace.** An agent can create separate branches
+ for independent work while staying in the same working directory. That gives
+ you separate review branches without creating a new worktree, directory, and
+ setup for each task.
+- **Selected files and hunks.** The agent can assign selected files or hunks to
+ a branch, then commit that branch. You can inspect the split before the work
+ is pushed.
+- **Stacked branches for dependent work.** If one change depends on another, the
+ agent can put the dependent branch on top of the branch it needs.
+- **History edits without an interactive rebase.** The agent can move a change
+ from one commit to another, reorder commits, reword commits, absorb fixes, or
+ split a commit with `but` commands.
+- **Review and recovery before publishing.** You can inspect the same branches
+ and commits in the CLI or Desktop Client, then use [`but oplog`](/commands/but-oplog)
+ to restore an earlier local GitButler state if the branch layout needs to be
+ rolled back.
+
+## History edits as direct commands
+
+History edits are where agent workflows often get brittle. Moving one file's
+changes from one commit to another with Git can involve patch restore/reset
+steps, fixup commits, autosquash, or an interactive rebase with one or more
+`edit` stops.
+
+With GitButler, that kind of edit becomes a direct operation: move this file's
+changes into that commit. The operation can still rewrite commits and can still
+conflict. The difference is control flow: the agent gets targeted tools for the
+edit instead of driving a multi-step rebase session.
+
+For more detail, see the [`but rub` command reference](/commands/but-rub) and
+the [CLI guide to moving changes between commits](/cli-guides/cli-tutorial/rubbing#moving-files-between-commits).
+
+GitButler does not currently focus on a direct "push to main" workflow. Today,
+it is best used to get from agent changes to clean local branches, commits, and
+PRs or MRs quickly.
diff --git a/content/docs/ai-agents/parallel-agents.mdx b/content/docs/ai-agents/parallel-agents.mdx
new file mode 100644
index 0000000..3e1e8a8
--- /dev/null
+++ b/content/docs/ai-agents/parallel-agents.mdx
@@ -0,0 +1,96 @@
+---
+title: Parallel agents
+description: Run multiple coding agents in one GitButler workspace without creating separate worktrees.
+---
+
+Parallel agents do not require separate worktrees or pre-created branches. Once
+agents use GitButler for version-control writes, you can start another coding
+session in the same repository and prompt it like any other task:
+
+```text
+Work on checkout validation.
+```
+
+When either session is ready, ask it to commit:
+
+```text
+Commit your changes.
+```
+
+The agent uses GitButler to commit the changes for its task to its GitButler
+branch. The branch routing is the agent's job; your prompt can stay small.
+
+If two sessions touch the same file or generated output, have the agents call
+out the overlap before committing.
+
+You can also ask an agent to split independent work out of the current session.
+For example, if a feature session also finds a small bug fix, the agent can
+move the relevant changes or commits to a new branch and prepare a separate PR
+instead of stacking the fix on the feature.
+
+For more background on the branch model, see
+[Parallel branches](/features/branch-management/virtual-branches).
+
+The baseline `Version control` instructions from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions)
+are useful if you want to steer commit behavior, but they are not a separate
+parallel-agent setup step.
+
+## How this differs from worktrees
+
+Git has one checked-out branch per worktree. If you want two agents to work on
+two branches at the same time, the usual Git answer is multiple worktrees.
+
+GitButler gives you a different option: multiple active branches in one
+worktree, with each agent's commits organized onto the branch for its session.
+
+| | Multiple worktrees | GitButler parallel branches |
+| --- | --- | --- |
+| Workspace | One directory per agent | One shared working directory |
+| Branches | One checked-out branch per worktree | Multiple active branches in one worktree |
+| Isolation | Separate checkout | Shared filesystem and runtime state |
+| Setup cost | Usually more directories, dependency installs, build outputs, and dev servers | Reuse one install and dev server when tasks can share runtime state |
+| Version-control shape | Branches stay separate because work happens in separate directories | GitButler can commit the right subset of changes to each branch |
+| Best fit | Competing attempts, incompatible checkout states, isolated runtimes | Unrelated features or fixes that can share one workspace |
+
+Use multiple worktrees when agents need incompatible checkout states, separate
+runtime state, or competing attempts at the same task. Use GitButler parallel
+branches when the tasks are independent enough to share one workspace and you
+want less local overhead.
+
+## Handle dependencies explicitly
+
+Parallel agents work best when sessions start independent. If one session
+starts depending on another, make that relationship explicit by stacking the
+branches:
+
+```text
+The notification settings work now depends on checkout validation. Stack your
+branch on top of the checkout validation branch.
+```
+
+If an unrelated fix shows up inside a feature session, tell the agent to extract
+it instead:
+
+```text
+The cache invalidation fix is independent. Move it to a separate GitButler
+branch and prepare a separate PR for it.
+```
+
+If the feature depends on the fix, put the fix on the lower branch and stack the
+feature above it instead. For stacked PR policy, see
+[Create stacked pull requests](/ai-agents/tuning-agent-behavior#create-stacked-pull-requests).
+
+## Know what is shared
+
+Parallel GitButler branches are not runtime isolation. The agents share one
+filesystem, dependency install, generated files, and app state. That can surface
+overlap and broken builds earlier, but it can also hide accidental
+dependencies.
+
+Before shipping a branch independently, check whether it depends on another
+active branch. If two agents start editing the same files or generated output,
+decide whether to keep the work parallel, stack one branch on the other, or use
+separate worktrees.
+
+For more request examples, see [Useful requests](/ai-agents/useful-requests).
diff --git a/content/docs/ai-agents/review-agent-work.mdx b/content/docs/ai-agents/review-agent-work.mdx
new file mode 100644
index 0000000..55a9d79
--- /dev/null
+++ b/content/docs/ai-agents/review-agent-work.mdx
@@ -0,0 +1,65 @@
+---
+title: Inspect and adjust agent work
+description: Choose a GitButler surface for previewing and adjusting coding-agent branch and commit history.
+---
+
+import ImageSection from "@/components/ImageSection"
+
+When your coding agent uses GitButler, it can do the version-control work for
+you: create branches, commit changes, move work between commits, and reshape
+local history. The agent usually does this through the GitButler CLI.
+
+You may still want to preview what it created or manually adjust the branch and
+commit history before anything is pushed or turned into a PR. GitButler gives
+you three ways to inspect and adjust that state: the TUI, the CLI, and the
+Desktop Client GUI. Use this page to pick the surface you want. The detailed
+CLI and Desktop workflows live in their own docs.
+
+## GitButler TUI
+
+Use the TUI when you want a terminal view of the workspace without switching to
+the Desktop Client. It is useful for checking branch state, looking at what is
+on a branch or still unassigned, and making small manual adjustments to branch
+assignment, commit membership, or history shape.
+
+```sh
+but tui
+```
+
+
+
+## GitButler CLI
+
+Use the CLI when you want exact output, scriptable commands, or the same view of
+the repository state that the agent uses.
+
+For command details, start with the [CLI overview](/cli-overview).
+
+## GitButler Desktop Client
+
+Use the Desktop Client when you want a visual overview of branches, commits,
+assigned changes, unassigned changes, parallel work, and stacked work. It is
+also the visual surface for moving changes between branches and adjusting
+commit history.
+
+```sh
+but gui
+```
+
+For details, see the [Desktop Overview](/overview),
+[Branch lanes](/features/branch-management/branch-lanes), and
+[Commits](/features/branch-management/commits).
+
+## Operations history
+
+GitButler records version-control operations so you can inspect or undo local
+history edits. If a branch reorganization does not look right, inspect the
+operation history before making more changes. See
+[Timeline](/features/timeline), [`but oplog`](/commands/but-oplog), and
+[`but undo`](/commands/but-undo).
diff --git a/content/docs/ai-agents/tuning-agent-behavior.mdx b/content/docs/ai-agents/tuning-agent-behavior.mdx
new file mode 100644
index 0000000..d14406e
--- /dev/null
+++ b/content/docs/ai-agents/tuning-agent-behavior.mdx
@@ -0,0 +1,171 @@
+---
+title: Tuning agent behavior
+description: Add optional instruction snippets that steer how coding agents amend, checkpoint, stack, publish, and recover work with GitButler.
+---
+
+Add these optional bullets under the same `## Version control` section as the
+baseline from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions).
+Use this page as a menu: copy only the policies you want for the repository and
+agent you are using.
+
+## Amend local fixes into the right commits
+
+Use this when you want the agent to fold follow-up fixes into unpublished local
+commits when the new change clearly belongs with that commit's intent. With
+GitButler, the agent can move the relevant change into the commit where it
+belongs.
+
+```md
+- For small cleanup or follow-up fixes, amend an unpublished local commit when
+ the change clearly belongs with that commit's intent.
+- Do not create tiny fixup commits unless I ask.
+- Use GitButler to move the relevant changes into the commit where they belong.
+- Ask before rewriting pushed, reviewed, shared, or ambiguous history.
+```
+
+You do not need to tell the agent which command to use. The GitButler skill
+gives it the relevant operations. For background, see
+[`but absorb`](/commands/but-absorb) and [`but amend`](/commands/but-amend).
+
+## Commit checkpoints after each completed turn
+
+Use this when you want local savepoints while the agent works. The checkpoints
+do not need to be the final review history. Before review, you can ask the
+agent to tidy unpublished local history.
+
+```md
+- Commit after a working checkpoint, when the requested change is complete and
+ relevant checks have passed or been reported.
+- Treat checkpoint commits as local savepoints, not final review history.
+- When I ask you to tidy the history, use GitButler to squash commits, reword
+ commits, and move changes between commits where appropriate.
+- Only tidy unpublished local history unless I explicitly authorize changing
+ pushed or shared history.
+```
+
+## Create stacked pull requests
+
+Use this when you want dependent work reviewed as stacked pull requests. This is
+useful when one agent session depends on another session's branch, or when an
+agent is working on a branch that sits at the bottom of a stack.
+
+```md
+- If this session depends on another in-flight branch, stack its branch on top
+ of that dependency instead of mixing the changes.
+- If this session is working in a stack, put commits on the branch where they
+ belong.
+- Ask before moving commits onto lower, pushed, reviewed, or shared branches.
+- Use `but move` for branch stacking and restacking. Do not recreate branches
+ to simulate stacking.
+- For stacked branches, create pull requests with `but pr`, not `gh`, so
+ GitButler keeps the right PR base branches and stack metadata.
+```
+
+For background, see [Stacked branches](/features/branch-management/stacked-branches),
+[`but move`](/commands/but-move), and [`but pr`](/commands/but-pr).
+
+## Customize branch names
+
+Use this when your team has a naming convention for branches the agent creates.
+This is only an example; replace the prefix and shape with your convention.
+
+```md
+- When creating a GitButler branch for an agent session, use
+ `feature/-` when a ticket ID is available.
+```
+
+## Customize commit messages
+
+Use this when your team has a commit-message convention. This is only an
+example; replace it with your preferred style.
+
+```md
+- Use Conventional Commits, such as `feat: add branch naming policy` or
+ `fix: handle empty branch names`.
+```
+
+## Publish when you say "ship it"
+
+Use this when you want a short phrase to authorize the agent to finish the
+version-control work for its session. This commits, pushes, and creates or
+updates a pull request, so use it only when the agent is allowed to publish.
+
+```md
+- When I say "ship it", commit this session's changes on its dedicated
+ GitButler branch, creating one if needed.
+- Push the branch and open or update its pull request with GitButler.
+- Reuse the existing branch or pull request for this session when one already
+ exists.
+```
+
+For background, see [`but push`](/commands/but-push) and
+[`but pr`](/commands/but-pr).
+
+## Update from main automatically
+
+Use this when your project moves quickly and you want the agent to keep its
+workspace current with the target branch, usually `main` or `master`. The
+GitButler command for this is `but pull`, which fetches the target branch and
+rebases applied branches onto the new target commit. This is a preference: in
+some repositories, you may want the agent to ask before updating.
+
+Add the last bullet only if you want the agent to handle update conflicts.
+
+```md
+- When GitButler status shows new changes on the target branch, run
+ `but pull --check`.
+- If the check is clean and the update affects only this session's branches,
+ update the workspace with `but pull`.
+- If the check reports conflicts or the update would affect another agent's
+ branch, ask before updating.
+- If I ask you to handle update conflicts, use GitButler's conflict tools. Ask
+ before resolving semantic conflicts, dependency updates, generated files, or
+ conflicts involving another person's work.
+```
+
+You do not need to tell the agent which command to use. For background, see
+[`but pull`](/commands/but-pull) and [`but resolve`](/commands/but-resolve).
+
+## Open draft pull requests by default
+
+Use this when the agent is allowed to publish work, but you still want review to
+start in draft. Creating a draft pull request still publishes the branch.
+
+```md
+- When I ask you to open a pull request, create it as a draft with GitButler
+ unless I say it is ready for review.
+```
+
+## Create a recovery point before large history edits
+
+Use this when you want the agent to be more cautious before reorganizing several
+commits or branches.
+
+```md
+- Before squashing, splitting, moving commits between branches, or reorganizing
+ multiple branches, run `but oplog snapshot -m ""`.
+- Use GitButler history-edit commands such as `but move`, `but squash`,
+ `but reword`, `but absorb`, and `but amend` instead of raw Git rebases.
+- If an operation makes the branch or history layout worse, stop and inspect the
+ operation log before attempting another fix.
+- Prefer `but undo` or `but oplog restore` over trying to repair a bad state
+ with more history edits.
+```
+
+For command details, see [`but oplog`](/commands/but-oplog) and
+[`but undo`](/commands/but-undo).
+
+## Split unrelated hunks
+
+Use this when agents tend to commit whole files even when one file contains
+separate changes.
+
+```md
+- If one file contains unrelated changes, split them by hunk instead of
+ committing the whole file.
+- Keep tests with the behavior they verify.
+- Split generated output, docs-only edits, or mechanical cleanup into separate
+ commits when each commit remains coherent on its own.
+- If the split is ambiguous, summarize the options before committing.
+```
diff --git a/content/docs/ai-agents/useful-requests.mdx b/content/docs/ai-agents/useful-requests.mdx
new file mode 100644
index 0000000..f3b9622
--- /dev/null
+++ b/content/docs/ai-agents/useful-requests.mdx
@@ -0,0 +1,123 @@
+---
+title: Useful requests
+description: Ask coding agents to commit, reshape history, split work, and create stacked pull requests with GitButler.
+---
+
+Once the GitButler skill is installed and your baseline version-control
+instructions are in place, ask for the branch, commit, or pull request outcome
+you want. You do not need to know the `but` commands or CLI IDs; the agent uses
+those to build the structure you describe.
+
+Use these examples as one-off requests you can mix with normal coding prompts.
+They are intentionally short; add whatever constraints matter in your repo. For
+standing rules that always apply, see
+[Tuning agent behavior](/ai-agents/tuning-agent-behavior).
+
+## Commit changes
+
+With the baseline instructions from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions),
+the agent commits on the dedicated GitButler branch for its session. It commits
+that session's changes there, not unrelated user or agent work.
+
+You can tell your agent:
+
+```text
+Commit your changes.
+```
+
+Relevant command: [`but commit`](/commands/but-commit).
+
+## Clean up history
+
+GitButler gives the agent direct tools for moving commits, squashing commits,
+rewording commits, and moving changes between commits. Describe the end result
+you want instead of writing out an interactive rebase plan.
+
+Keep history cleanup to unpublished local work unless you explicitly authorize
+rewriting pushed or shared branches.
+
+```text
+Clean up the history. Squash WIP commits, split unrelated work, and reword
+messages based on intent. Show me the plan before changing history or pushing.
+```
+
+Relevant commands: [`but move`](/commands/but-move),
+[`but squash`](/commands/but-squash), [`but reword`](/commands/but-reword),
+and [`but rub`](/commands/but-rub).
+
+## Split a large commit into smaller commits
+
+Use this when a commit is too large to review as one unit. Say how you want the
+work grouped; the agent can create the intermediate commits and move the right
+changes into them.
+
+This prompt is an example; replace the grouping rules with whatever matters for
+your project.
+
+```text
+Split this into smaller commits by concern. Keep tests with the behavior they
+verify.
+```
+
+## Put uncommitted fixes into existing commits
+
+Use this after review feedback, test fixes, or a small follow-up edit that
+belongs with an earlier local commit.
+
+```text
+Amend your follow-up fixes into the appropriate local commits.
+```
+
+Relevant commands: [`but absorb`](/commands/but-absorb) and
+[`but amend`](/commands/but-amend).
+
+## Take changes out of a commit
+
+Use this when something was committed by mistake, or when one commit contains a
+change that belongs somewhere else.
+
+```text
+Take the debug logging out of the commit and leave it uncommitted.
+```
+
+```text
+Move the docs changes out of the feature commit and into a separate docs commit.
+```
+
+Relevant commands: [`but uncommit`](/commands/but-uncommit) and
+[`but rub`](/commands/but-rub).
+
+## Create stacked pull requests
+
+Stacked pull requests help when one change depends on another, but reviewers can
+still review the lower branch first. Creating draft PRs still pushes branches,
+so use this only when the agent is allowed to publish.
+
+```text
+Make the API work the base branch and stack the UI work on top. Create draft
+PRs.
+```
+
+The agent can also stack or restack existing branches when the dependency
+structure changes. If branches have already been pushed or reviewed, ask the
+agent to show which PRs will change before restacking. If something in a stack
+turns out to be independent, ask the agent to move it out into a separate
+branch.
+
+For more background, see
+[Stacked branches](/features/branch-management/stacked-branches),
+[`but move`](/commands/but-move), and [`but pr`](/commands/but-pr).
+
+## Work in parallel
+
+Use parallel branches when the work does not depend on another branch.
+GitButler lets multiple branches be active in the same workspace, so different
+agents can work on their own branches without creating and managing separate
+worktrees.
+
+This works best when the tasks do not depend on each other and are not editing
+the same files.
+
+Stack branches only when one branch depends on another. For the fuller
+multi-agent workflow, see [Parallel agents](/ai-agents/parallel-agents).
diff --git a/content/docs/cli-guides/cli-tutorial/ai-stuff.mdx b/content/docs/cli-guides/cli-tutorial/ai-stuff.mdx
index 53c1064..ff37943 100644
--- a/content/docs/cli-guides/cli-tutorial/ai-stuff.mdx
+++ b/content/docs/cli-guides/cli-tutorial/ai-stuff.mdx
@@ -1,33 +1,39 @@
---
title: Working with AI
-description: How to use the GitButler CLI with AI and agents
+description: Use AI-backed CLI options and install the GitButler skill for coding agents.
---
-There are a couple of different ways that the GitButler CLI can use or interact with AI tools. Some are via `--ai` options to commands to use AI to help with tasks, others are ways that coding agents can more easily use the CLI to accomplish tasks.
+Use `--ai` when you want the CLI to generate text for a single command. Use
+`but skill install` when you want a coding agent to use GitButler's
+version-control workflow.
-## Dash Dash AI
+## `--ai` options
-There are a few commands that will take a `--ai` option to use a configured AI provider to generate something.
+Supported commands can take `--ai` to generate text from your current changes.
### `but commit --ai`
-Probably the most commonly used would be `but commit --ai`, which will take a look at the changes in the files you're committing and generate an example commit message for you. If you're not feeling like writing anything more than "did some stuff", this could be a nice option for you.
+Use `but commit --ai` to generate a commit message from the changes you are
+committing.
-This will automatically commit the work specified with the generated message, but you can also easily edit it with `but reword ` if you wish.
+This commits the selected work with the generated message. You can edit the
+message afterward with `but reword `.
### `but squash --ai`
-If you squash two commits together, by default it will simply concatenate the commit messages together, which is rarely what you probably want. You can easily edit the message afterwards, but if you want to let AI try to combine the messages for you, you can give `but squash --ai` a try.
+Use `but squash --ai` to generate a combined commit message when squashing
+commits.
-We're working on integrating AI features into many more of our commands, so keep an eye out.
+More commands will gain `--ai` support over time.
-## Skills
+## `but skill install`
-If you're using an AI coding agent that can read skills, you can have GitButler automatically install a GitButler specific skill for various agents with `but skill install`.
+If your coding agent can read skills, install the GitButler skill with
+`but skill install`.
```git
❯ but skill install
@@ -42,8 +48,16 @@ Select a skill folder format:
GitHub Copilot - GitHub Copilot global skill format (./.copilot/skills/gitbutler)
```
-We keep these templates up to date, so if you update GitButler, you may want to update the skills too.
+We keep these templates up to date, so if you update GitButler, you may want to
+update the skill too.
-## Hooks and MCP
+## Agent workflow docs
-You can also install explicit hooks or an MCP server if you prefer. You can read more about those options [over here](/features/ai-integration/ai-overview)
+`but skill install` is only the install step. For the full workflow:
+
+- Start with [AI agents overview](/ai-agents/overview).
+- Install and configure the skill with
+ [Getting started with AI agents](/ai-agents/getting-started).
+- Use [Useful requests](/ai-agents/useful-requests) for prompt examples.
+- Use [Tuning agent behavior](/ai-agents/tuning-agent-behavior) for standing
+ instructions.
diff --git a/content/docs/commands/but-skill.mdx b/content/docs/commands/but-skill.mdx
index 7082a79..aab9a27 100644
--- a/content/docs/commands/but-skill.mdx
+++ b/content/docs/commands/but-skill.mdx
@@ -1,10 +1,10 @@
---
title: "`but skill`"
-description: "Manage Claude AI skills for GitButler."
+description: "Manage GitButler skills for coding agents."
---
-Skills provide enhanced AI capabilities for working with GitButler through
-Claude Code and other AI assistants.
+Skills give coding agents instructions for working with GitButler through the
+`but` CLI.
Use `but skill install` to install the GitButler skill files into your
repository or globally.
@@ -29,14 +29,14 @@ but skill install --global
### `but skill install`
-Install the GitButler CLI skill files for Coding agents
+Install the GitButler CLI skill files for coding agents.
-By default, installs the skill into the current repository. The command
-will prompt you to select a skill folder format (Claude Code, OpenCode, Codex, GitHub Copilot,
-Cursor, Windsurf) unless you specify a custom path with --path.
+By default, installs the skill into the current repository. The command prompts
+you to select a skill folder format: Claude Code, OpenCode, Codex, GitHub
+Copilot, Cursor, or Windsurf.
-Use --global to install the skill in a global location instead of the
-current repository.
+Use `--path` to choose a custom location. Use `--global` to install the skill
+in a global location instead of the current repository.
## Examples
@@ -74,7 +74,7 @@ but skill install --detect
### `but skill check`
-Check if installed GitButler skills are up to date with the CLI version
+Check if installed GitButler skills are up to date with the CLI version.
Scans for installed skill files and compares their version with the current
CLI version. By default, checks both local (repository) and global installations.
@@ -106,4 +106,3 @@ but skill check --global
* `-g`, `--global` — Only check global installations (in home directory)
* `-l`, `--local` — Only check local installations (in current repository)
* `-u`, `--update` — Automatically update any outdated skills found
-
diff --git a/content/docs/features/ai-integration/ai-overview.mdx b/content/docs/features/ai-integration/ai-overview.mdx
deleted file mode 100644
index d9a3c6c..0000000
--- a/content/docs/features/ai-integration/ai-overview.mdx
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: AI Overview
-description: Overview of AI integrations with GitButler including MCP server and Claude Code hooks for automated commit management.
----
-
-import ImageSection from "@/components/ImageSection"
-
-If you're using AI agent tools like Cursor, Windsurf, or Claude Code, GitButler can enhance your coding experience by managing commits, saving points, and more. These integrations allow you to focus on coding with your agents while GitButler handles the version control aspects.
-
-https://www.youtube.com/watch?v=J6xV_Wyz9zg
-
-There are currently three main ways to use AI tools with GitButler:
-
-1. **Our Coding Agent**: If you have Claude Code setup, you can use our [Code Agent](/features/coding-agents) as a GUI for running Claude Code directly.
-2. **Using Hooks in Claude Code or Cursor**: This method allows you to use GitButler's CLI as hook commands to manage commits and branches in either Claude Code or Cursor.
-3. **Using the MCP Server**: This method allows you to set up your AI agent to communicate with GitButler's MCP server, enabling features like automatic commits and save points.
-
-## Enabling the experimental feature flag
-
-Note that as of GitButler version `0.15.2` these features have to be enabled via an experimental feature flag. You can find that under `Global Settings` -> `Experimental` -> `GitButler Actions`.
diff --git a/content/docs/features/ai-integration/claude-code-hooks.mdx b/content/docs/features/ai-integration/claude-code-hooks.mdx
deleted file mode 100644
index e589e88..0000000
--- a/content/docs/features/ai-integration/claude-code-hooks.mdx
+++ /dev/null
@@ -1,86 +0,0 @@
----
-title: Claude Code Hooks
-description: Set up Claude Code hooks to automatically manage commits and branches when using GitButler with AI coding agents.
----
-
-If you are using Claude Code, you can use the new ["hooks"](https://docs.anthropic.com/en/docs/claude-code/hooks) functionality to manage the output of even multiple simultaneous instances, while isolating all the generated code into virtual or stacked branches automatically. In this case, there is no need to set up the MCP server, as the hooks will handle everything for you.
-
-Here's a short video showing how GitButler works with Claude Code:
-
-https://youtu.be/AwwPwSc9qhA
-
-Ok, let's get it set up.
-
-## Install the GitButler CLI
-
-First, you need to install the GitButler CLI, which can be done in your General settings. See the [MCP Server documentation](./mcp-server) for more details on how to install the CLI.
-
-## Installing GitButler as a Hook
-
-Hooks in Claude Code are defined in one of your settings files.
-
-```
-~/.claude/settings.json - User settings
-.claude/settings.json - Project settings
-.claude/settings.local.json - Local project settings (not committed)
-```
-
-Wherever you want to add GitButler to handle your commits automatically, you can add us as a hook by adding the following to the `hooks` array in whatever settings file you want to use:
-
-```json
-{
- "hooks": {
- "PreToolUse": [
- {
- "matcher": "Edit|MultiEdit|Write",
- "hooks": [
- {
- "type": "command",
- "command": "but claude pre-tool"
- }
- ]
- }
- ],
- "PostToolUse": [
- {
- "matcher": "Edit|MultiEdit|Write",
- "hooks": [
- {
- "type": "command",
- "command": "but claude post-tool"
- }
- ]
- }
- ],
- "Stop": [
- {
- "matcher": "",
- "hooks": [
- {
- "type": "command",
- "command": "but claude stop"
- }
- ]
- }
- ]
- }
-}
-```
-
-Essentially, you want to run the `but claude pre-tool` command before any code generation or editing, and the `but claude post-tool` command after it. The `but claude stop` command will run when you stop the agent, ensuring that all changes are committed and branches are updated accordingly.
-
-You also might want to add to your "memories" to ask Claude not to try commiting using Git as it will be handled by GitButler. You can do something like this:
-
-```
-❯ cat ~/.claude/CLAUDE.md
-## Development Workflow
-- Never use the git commit command after a task is finished.
-```
-
-## Using GitButler with Claude Code
-
-With the hooks setup, Claude will tell GitButler when it has generated code or edited files and in which session, which helps GitButler to try to isolate the changes into a single branch per session.
-
-For example, if you have three sessions of Claude Code running at the same time, each will be communicating with GitButler at each step and GitButler will be assigning each change to the correct branch automatically.
-
-When the agent is done, GitButler will commit all the changes and write a more sophisticated commit message based on what you had prompted your agent.
diff --git a/content/docs/features/ai-integration/cursor-hooks.mdx b/content/docs/features/ai-integration/cursor-hooks.mdx
deleted file mode 100644
index e007518..0000000
--- a/content/docs/features/ai-integration/cursor-hooks.mdx
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Cursor Hooks
-description: Set up Cursor hooks to automatically manage commits and branches when using GitButler with AI coding in Cursor.
----
-
-GitButler integrates seamlessly with Cursor through hooks that automatically manage your commits and branches while you're using AI coding features. This allows you to automatically maintain clean git history and organized parallel branches.
-
-Here's a short video showing how GitButler works with Cursor hooks:
-
-https://youtu.be/NOYK7LTFvZM
-
-Ok, let's get it set up.
-
-## Install the GitButler CLI
-
-First, you need to install the GitButler CLI, which can be done in your General settings. See the [MCP Server documentation](mcp-server) for more details on how to install the CLI.
-
-## Installing GitButler as a Hook
-
-Once the command line tool is installed, you can add the `but cursor` commands as hooks.
-
-You will need to create or edit your `~/.cursor/hooks.json` file (globally) or `[project]/.cursor/hooks.json` file (single project) to have `afterFileEdit` and `stop` hooks like this:
-
-```json
-{
- "version": 1,
- "hooks": {
- "afterFileEdit": [
- {
- "command": "but cursor after-edit"
- }
- ],
- "stop": [
- {
- "command": "but cursor stop"
- }
- ]
- }
-}
-```
-
-## Using GitButler with Cursor
-
-Once the hooks are setup, Cursor will automatically call GitButler when it edits files and when it's done with a task, which will trigger GitButler to:
-
-- Create a branch if the chat session is new
-- Assign edits to an active branch
-- Commit with a message based on the prompt when a task is done
diff --git a/content/docs/features/ai-integration/mcp-server.mdx b/content/docs/features/ai-integration/mcp-server.mdx
deleted file mode 100644
index edc0732..0000000
--- a/content/docs/features/ai-integration/mcp-server.mdx
+++ /dev/null
@@ -1,190 +0,0 @@
----
-title: MCP Server
-description: Configure GitButler's MCP server integration with AI agents like Cursor, VSCode, and Claude Code for automatic commit management.
----
-
-import ImageSection from "@/components/ImageSection"
-
-If you use an AI agent (such as Cursor, Windsurf, Claude Code) to help you with your code, you can easily setup GitButler to manage your commits automatically, keep save points, and more. You know, _vibe_ commit...
-
-## Setting up your Agent to use GitButler
-
-The first step is to let your agent know about GitButler, which is done via MCP - you need to tell your agent to use the GitButler MCP server.
-
-### Installing the CLI
-
-GitButler provides a CLI that can be used to interact with the GitButler platform. Before you can setup AI Agent integration, you will need to install the CLI.
-
-This can be found by opening the GitButler global settings, and then clicking on the "Install CLI" button in the General settings.
-
-
-
-Now that you have the `but` CLI installed, your agent can use the CLI's MCP server to interact with GitButler.
-
-### Cursor
-
-To install the GitButler MCP server in Cursor, first go to the Cursor settings, and then click on the "Extensions" tab, then click on "Tools and Integrations" and click on "New MCP Server".
-
-This will open your `~/.cursor/mcp.json` file.
-
-Add the following to the `mcpServers` object:
-
-```json
-{
- "mcpServers": {
- "gitbutler": {
- "command": "but",
- "args": ["mcp"]
- }
- }
-}
-```
-
-You should see the GitButler MCP server in the list of MCP servers and it should have the tool `gitbutler_update_branches` available.
-
-### VSCode
-
-To install the GitButler MCP server in VSCode, you need to select "MCP: List Servers" from the actions menu. Then select "Add Server". Select "stdio" as the server type.
-
-Now you can type your command (`but mcp`) and name it something. After this, it should open up your settings file and show you something like this:
-
-```json
- "mcp": {
- "servers": {
- Running | Stop | Restart | 1 tools
- "gitbutler-mcp": {
- "type": "stdio",
- "command": "but",
- "args": ["mcp"]
- }
- }
- }
-```
-
-However, if you have Cursor's MCP already setup, VSCode will notice and help you automatically reuse the settings.
-
-
-
-### Claude Code
-
-Adding an MCP server to Claude Code is done by running the `claude mcp add` command.
-
-```
-❯ claude mcp add gitbutler but mcp
-Added stdio MCP server gitbutler with command: but mcp to local config
-
-❯ claude mcp list
-gitbutler: but mcp
-```
-
-## Rules: How to configure auto committing
-
-Once you have installed the MCP server in your editor or agent, you can optionally configure it to automatically commit your changes.
-
-We've found that adding something like this to your rules works well:
-
-```
-If you generate code or modify files, run the gitbutler update branches MCP tool.
-```
-
-## How to add rules
-
-Cursor stores its rules in `~/.cursor/rules` file, but you can also manually set them by going to the Cursor Settings pane, clicking 'Rules' and adding them to the User Rules section.
-
-In VSCode's Copilot Agent Mode, you can use ["custom instructions"](https://code.visualstudio.com/docs/copilot/copilot-customization#_custom-instructions) to accomplish this.
-
-In Claude Code, they are now called "memories" and you can add them by hitting '#' and storing them in user memory (or local if you just want them in one project).
-
-
-
-Or directly in your `~/.claude/CLAUDE.md` rules file:
-
-```
-❯ cat ~/.claude/CLAUDE.md
-## Development Workflow
-- When you're done with a task where code was created or files edited, please run the gitbutler mcp update_branches command.
-```
-
-## Using GitButler with your agent
-
-If you've set up a rule/instruction/memory, then every time a chat session is completed, the agent will send the changes and prompt to GitButler and it will automatically commit the changes.
-
-
-
-If you're using Claude Code, it may look something like this:
-
-
-
-If you don't have the agent setup to automatically call our tool, then you can also just manually type 'update gitbutler branches' in the chat, but that's a little less magical.
-
-## GitButler interface
-
-There are two phases to GitButler's MCP agent interaction. The first is the agent sending the changes and prompt to GitButler, which GitButler will quickly record and then return a success to the agent. The second is GitButler processing that raw recorded change and attempting to process that change into a commit.
-
-### Recording the changes
-
-When your agent calls the `gitbutler_update_branches` tool, GitButler will record the changes and prompt and then immediately return to the agent, so the call should be very fast.
-
-So for instance, let's say that I prompted my coding agent to update my `README.md` file to add a list of contributing authors. When the agent is done, it should call the update branches MCP tool, which will record a commit that looks something like this:
-
-
-
-### Processing the changes
-
-Then, if you have AI tooling setup, GitButler will see that and turn it into a commit message like this:
-
-
-
-You can see all of these steps in the "Actions" section of the GitButler interface, which you can toggle by hitting the "Actions" button in the top right of the interface.
-
-
-
-In the near future, we will also be able to do more interesting things like auto-absorbing changes into existing commits, creating new branches based on the prompt theme, creating stacked branches, and more.
diff --git a/content/docs/features/ai-integration/meta.json b/content/docs/features/ai-integration/meta.json
deleted file mode 100644
index 55d80f4..0000000
--- a/content/docs/features/ai-integration/meta.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "title": "AI Agent Integrations",
- "defaultOpen": false,
- "pages": ["ai-overview", "mcp-server", "claude-code-hooks", "cursor-hooks"]
-}
diff --git a/content/docs/features/branch-management/rules.mdx b/content/docs/features/branch-management/rules.mdx
index 2d17e37..73d4c35 100644
--- a/content/docs/features/branch-management/rules.mdx
+++ b/content/docs/features/branch-management/rules.mdx
@@ -3,8 +3,6 @@ title: Rules
description: Automate change assignment with rules that match file patterns and automatically route changes to the right branch.
---
-import ImageSection from "@/components/ImageSection";
-
Rules are a powerful automation feature in GitButler that automatically assign file changes to specific branches based on conditions you define. Instead of manually dragging changes between lanes, you can set up rules that automatically route changes where they belong.
## Overview
@@ -53,7 +51,7 @@ If you don't add any filters, the rule will match all changes.
## Filter Types
-Rules support several types of filters to match changes:
+Rules support filters that match file paths or changed line content.
### Path Matches Regex
@@ -89,33 +87,13 @@ Matches the content of changed lines using a regular expression pattern. This fi
Creating a rule that assigns changes containing "fix" to a specific branch
-### Claude Code Session ID
-
-Matches changes that originated from a specific Claude Code session. This filter is automatically used when GitButler's AI features create branches and rules for you.
-
-**Note**: Rules with Claude Code Session ID filters have lower priority than manually created rules. If a change matches both an AI-generated rule and a manual rule, the manual rule takes precedence.
-
-
-
- AI-generated rules based on Claude Code sessions
-
-
## Managing Rules
### Editing Rules
To edit an existing rule:
-1. Double-click the rule or click the elepsis menu (...) and select "Edit rule"
+1. Double-click the rule or click the ellipsis menu (...) and select "Edit rule"
2. Modify the branch assignment or filters
3. Click **Save rule**
@@ -123,12 +101,10 @@ To edit an existing rule:
To delete a rule:
-1. Click the elepsis menu (...) on the rule
+1. Click the ellipsis menu (...) on the rule
2. Select "Delete rule"
3. Confirm the deletion
-**Note**: AI-generated rules and implicit rules cannot be edited.
-
## Understanding Rule Evaluation
### Order Matters
@@ -159,11 +135,9 @@ Rules respect hunk dependencies (locks). If a change depends on a commit in a sp
## Limitations
- Rules can only assign changes to branches that exist in your workspace (applied branches)
-- Implicit (AI-determined) rules cannot be edited through the UI
- Rules currently only support the `assign` action for filesystem changes
## Related Features
- [Parallel Branches](/features/branch-management/virtual-branches): Understanding the branch system that rules work with
- [Branch Lanes](/features/branch-management/branch-lanes): How lanes are organized and how rules interact with lane positioning
-- [AI Assistance](/features/branch-management/ai-assistance): How AI can create and manage rules automatically
diff --git a/content/docs/features/coding-agents.mdx b/content/docs/features/coding-agents.mdx
deleted file mode 100644
index ca0d0e9..0000000
--- a/content/docs/features/coding-agents.mdx
+++ /dev/null
@@ -1,151 +0,0 @@
----
-title: Code Agent Assistant
-description: Use our Claude Code integration to assign coding agents to specific branches, even multiple parallel branches at one time
----
-
-import ImageSection from "@/components/ImageSection"
-
-GitButler can also orchestrate your coding agents and help automatically manage, checkpoint and commit the work that they do for you.
-
-
- Currently the only supported agent is [Claude Code](https://www.anthropic.com/claude-code), but we
- are working on more agent support.
-
-
-You can start a session by clicking the AI stars on a branch header, or use the shortcut for a new branch and AI session in the top right corner of the window.
-
-
-
-Each session is tied to a branch such that you can run them in parallel, and changes are assigned to the respective branch as long as they are mutually exclusive. Information about the branch is also added to the respective context, giving the agent knowledge of the work they contain.
-
-# Setup
-
-There is some basic setup that may need to be done the first time, if you've never used Claude Code before.
-
-### Installing Claude Code
-
-Before you can use the agents integration, you need to have Claude Code installed as we wrap the SDK that it provides. If we can't find the binary, you should see something like this:
-
-
-
-To install Claude Code, you can read through the docs [here](https://docs.anthropic.com/en/docs/claude-code/quickstart), but the simple version is to use their "Native Install" method:
-
-{/* */}
-
-
-
- ```bash
- curl -fsSL https://claude.ai/install.sh | bash
- ```
-
-
- ```bash
- irm https://claude.ai/install.ps1 | iex
- ```
-
-
- ```bash
- curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del
- install.cmd
- ```
-
-
-{/* */}
-
-You will then need to setup and login to Claude Code, which will require an Anthropic account. You can either connect it to an API key for direct billing or use one of the plans. You can learn more on the [Claude Code](https://www.anthropic.com/claude-code) page.
-
-
- GitButler does not charge you for agent use, but Anthropic does. This goes directly through Claude
- Code usage, we simply help manage the agent.
-
-
-# Generating Code with an Agent
-
-Once your agent is setup, you can select a branch to work on, type in a prompt and we will run that though Claude Code, same as if you ran it in the terminal.
-
-
-
-While this is still running Claude Code, running through the GitButler UI will make sure that each agent works on the branch it is attached to. You can run multiple agents at once, each committing to their attached branches.
-
-### Model Selection
-
-There are a few different models that you can choose from for running your task. You can change your active model in the model selection dialog of the chat box.
-
-
-
-### Thinking Modes
-
-Claude Code also allows for selection of a "thinking mode". The lower modes are faster, the higher modes tend to take longer and be more expensive, but can produce better results.
-
-
-
-### Prompt Templates
-
-If you find that you're using similar prompts over and over, you can easily setup several prompt templates. Selecting one will seed the prompt with the contents of that template.
-
-
-
-You can also edit your available templates by selecting the "Edit templates" option, which opens up our JSON file in your editor of choice. The templates look something like this:
-
-````json
-{
- "templates": [
- {
- "label": "Bug Fix",
- "template": "Please fix the bug in this code:\n\n```\n// Your code here\n```\n\nExpected behavior:\nActual behavior:\nSteps to reproduce:"
- },
- {
- "label": "Code Review",
- "template": "Please review this code for:\n- Performance issues\n- Security vulnerabilities\n- Best practices\n- Code style\n\n```\n// Your code here\n```"
- },
- {
- "label": "Refactor",
- "template": "Please refactor this code to improve:\n- Readability\n- Performance\n- Maintainability\n\n```\n// Your code here\n```\n\nRequirements:"
- },
- {
- "label": "Add Tests",
- "template": "Please write comprehensive tests for this code:\n\n```\n// Your code here\n```\n\nTest cases should cover:\n- Happy path\n- Edge cases\n- Error conditions"
- }
- ]
-}
-````
-
-### Context Clearing
-
-After a while, your context in a single branch can get long. If you no longer need all the context but want to keep your agent working on the same branch, you can clear it with the "Clear Context" button in the context menu.
diff --git a/content/docs/features/meta.json b/content/docs/features/meta.json
index 4992924..4a13f0d 100644
--- a/content/docs/features/meta.json
+++ b/content/docs/features/meta.json
@@ -1,5 +1,5 @@
{
"title": "Features",
"defaultOpen": false,
- "pages": ["branch-management", "timeline", "forge-integration", "ai-integration", "coding-agents", "gerrit-mode"]
+ "pages": ["branch-management", "timeline", "forge-integration", "gerrit-mode"]
}
diff --git a/content/docs/meta.json b/content/docs/meta.json
index f52319c..a6ff354 100644
--- a/content/docs/meta.json
+++ b/content/docs/meta.json
@@ -11,6 +11,8 @@
"butler-flow",
"features",
"troubleshooting",
+ "---AI Agents---",
+ "...ai-agents",
"---GitButler CLI---",
"cli-overview",
"cli-guides",
diff --git a/public/img/docs/ai-agents-tui.png b/public/img/docs/ai-agents-tui.png
new file mode 100644
index 0000000..18d4325
Binary files /dev/null and b/public/img/docs/ai-agents-tui.png differ
diff --git a/public/llms-full.txt b/public/llms-full.txt
index 28d6636..cd67183 100644
--- a/public/llms-full.txt
+++ b/public/llms-full.txt
@@ -15,7 +15,6 @@
- [fetch-push](#fetch-push.mdx)
- [fixing-conflicts-outside-gitbutler](#fixing-conflicts-outside-gitbutler.mdx)
- [recovering-stuff](#recovering-stuff.mdx)
-- [coding-agents](#coding-agents.mdx)
- [gerrit-mode](#gerrit-mode.mdx)
- [timeline](#timeline.mdx)
- [github-integration](#github-integration.mdx)
@@ -31,10 +30,6 @@
- [stacked-branches](#stacked-branches.mdx)
- [upstream-integration](#upstream-integration.mdx)
- [virtual-branches](#virtual-branches.mdx)
-- [ai-overview](#ai-overview.mdx)
-- [claude-code-hooks](#claude-code-hooks.mdx)
-- [cursor-hooks](#cursor-hooks.mdx)
-- [mcp-server](#mcp-server.mdx)
- [debugging](#debugging.mdx)
- [contact-us](#contact-us.mdx)
- [open-source](#open-source.mdx)
@@ -42,6 +37,7 @@
- [but-absorb](#but-absorb.mdx)
- [but-alias](#but-alias.mdx)
- [but-amend](#but-amend.mdx)
+- [but-apply](#but-apply.mdx)
- [but-branch](#but-branch.mdx)
- [but-commit](#but-commit.mdx)
- [but-config](#but-config.mdx)
@@ -66,6 +62,7 @@
- [but-stage](#but-stage.mdx)
- [but-status](#but-status.mdx)
- [but-teardown](#but-teardown.mdx)
+- [but-unapply](#but-unapply.mdx)
- [but-uncommit](#but-uncommit.mdx)
- [but-undo](#but-undo.mdx)
- [but-unmark](#but-unmark.mdx)
@@ -86,6 +83,11 @@
- [scripting](#scripting.mdx)
- [tutorial-overview](#tutorial-overview.mdx)
- [updating-the-base](#updating-the-base.mdx)
+- [getting-started](#getting-started.mdx)
+- [parallel-agents](#parallel-agents.mdx)
+- [review-agent-work](#review-agent-work.mdx)
+- [tuning-agent-behavior](#tuning-agent-behavior.mdx)
+- [useful-requests](#useful-requests.mdx)
# butler-flow.mdx
@@ -113,7 +115,7 @@ In a nutshell, the basic development cycle is very simple.
In stock, vanilla Git tooling, there is nothing specified as the production branch, no special "trunk". It is only by convention that this is enforced.
-In GitButler, parallel branches will not work without the specification of a special "target branch". Everything exists in relation to this special branch, everything that differs from it must be accounted for by being owned by some other branch, until those changes are integrated.
+In GitButler, branches will not work without the specification of a special "target branch". Everything exists in relation to this special branch, everything that differs from it must be accounted for by being owned by some other branch, until those changes are integrated.
### Parallel Branches
@@ -142,7 +144,7 @@ Parallel branches can remain applied locally until they are merged into your ups
In addition to the Desktop graphical client, GitButler ships with a command line interface that allows you to do all of the same powerful things that the GUI does, but from the terminal or via scripts or agents.
-https://www.youtube.com/watch?v=loavN_hHuEs
+https://www.youtube.com/watch?v=Jg8L3SbgZ3o
This includes tooling for:
@@ -166,53 +168,59 @@ For a quick reference of the most commonly used commands, check out our [**GitBu
Feel free to get started with our [Tutorial](cli-guides/installation) or just dig into the available commands.
-# index.mdx
-
-## Overview
-
-GitButler is a new Source Code Management system designed to manage your branches, record and backup your work, be your Git client, help with your code and much more. Our focus is everything after writing code in your editor and before sharing it on GitHub. We're focused on your working directory and how we can help with everything you do there.
-
-We ship a [desktop GUI client](/overview) and [a CLI](/cli-overview) that work together.
-
-### Desktop Client
-
-
-
-### Command Line Interface
-
-
-
-Here you will find documentation on the product and the way that we're running our beta and building our product with your help.
-
-## Getting Started
-
-Check out our [Getting Started](/guide) guide to get started with GitButler, or check out our helpful video overview:
-
-https://www.youtube.com/watch?v=DhJtNNhCNLM
-
-## Why We're Doing This
-
-Read about it over [Why GitButler](/why-gitbutler) Section.
-
-## What We Do
-
-The GitButler client is a powerful Git client. You can manage your branches, work on multiple things at once, push and fetch from your Git server, easily rebase and modify commits and more. We have a unique approach to merge conflicts that helps split up any conflicting work. It also keeps a timeline so that you can easily undo any operation.
+# overview.mdx
-- [Parallel Branches](/features/branch-management/virtual-branches)
-- [First Class Conflicts](/features/branch-management/merging)
-- [Project History](/features/timeline)
+Use GitButler with coding agents when you want messy local changes to become
+reviewable branches and commits without moving every task into a separate
+worktree.
+
+GitButler keeps one working directory while organizing changes into separate
+branches and commits. Agents can do that through the [`but` CLI](/cli-overview),
+and you can inspect the same state in the [Desktop Client](/overview). For when
+to use GitButler instead of separate worktrees, see
+[Parallel agents](/ai-agents/parallel-agents#how-this-differs-from-worktrees).
+
+You decide how far the agent goes. You can tell it to stop after local commits,
+or you can allow it to push and open pull requests. GitButler gives the agent
+version-control commands; your instructions decide when it stops.
+
+## What agents can do with GitButler
+
+- **Parallel branches in one workspace.** An agent can create separate branches
+ for independent work while staying in the same working directory. That gives
+ you separate review branches without creating a new worktree, directory, and
+ setup for each task.
+- **Selected files and hunks.** The agent can assign selected files or hunks to
+ a branch, then commit that branch. You can inspect the split before the work
+ is pushed.
+- **Stacked branches for dependent work.** If one change depends on another, the
+ agent can put the dependent branch on top of the branch it needs.
+- **History edits without an interactive rebase.** The agent can move a change
+ from one commit to another, reorder commits, reword commits, absorb fixes, or
+ split a commit with `but` commands.
+- **Review and recovery before publishing.** You can inspect the same branches
+ and commits in the CLI or Desktop Client, then use [`but oplog`](/commands/but-oplog)
+ to restore an earlier local GitButler state if the branch layout needs to be
+ rolled back.
+
+## History edits as direct commands
+
+History edits are where agent workflows often get brittle. Moving one file's
+changes from one commit to another with Git can involve patch restore/reset
+steps, fixup commits, autosquash, or an interactive rebase with one or more
+`edit` stops.
+
+With GitButler, that kind of edit becomes a direct operation: move this file's
+changes into that commit. The operation can still rewrite commits and can still
+conflict. The difference is control flow: the agent gets targeted tools for the
+edit instead of driving a multi-step rebase session.
+
+For more detail, see the [`but rub` command reference](/commands/but-rub) and
+the [CLI guide to moving changes between commits](/cli-guides/cli-tutorial/rubbing#moving-files-between-commits).
+
+GitButler does not currently focus on a direct "push to main" workflow. Today,
+it is best used to get from agent changes to clean local branches, commits, and
+PRs or MRs quickly.
# guide.mdx
@@ -227,7 +235,7 @@ Here is a quick overview of how to get started with GitButler. In this guide, we
## Importing a Local Repository
-After [downloading](https://app.gitbutler.com/downloads) and installing GitButler, you will be greeted with the welcome screen. From here you can
+After [downloading](https://gitbutler.com/downloads) and installing GitButler, you will be greeted with the welcome screen. From here you can
For more information, check out the [pinned issue](https://github.com/tauri-apps/tauri/issues/9662) in the Tauri repository.
+# index.mdx
+
+## Overview
+
+GitButler is a new Source Code Management system designed to manage your branches, record and backup your work, be your Git client, help with your code and much more. Our focus is everything after writing code in your editor and before sharing it on GitHub. We're focused on your working directory and how we can help with everything you do there.
+
+We ship a [desktop GUI client](/overview) and [a CLI](/cli-overview) that work together.
+
+### Desktop Client
+
+
+
+### Command Line Interface
+
+
+
+Here you will find documentation on the product and the way that we're running our beta and building our product with your help.
+
+## Getting Started
+
+Check out our [Getting Started](/guide) guide to get started with GitButler, or check out our helpful video overview:
+
+https://www.youtube.com/watch?v=DhJtNNhCNLM
+
+## Why We're Doing This
+
+Read about it over [Why GitButler](/why-gitbutler) Section.
+
+## What We Do
+
+The GitButler client is a powerful Git client. You can manage your branches, work on multiple things at once, push and fetch from your Git server, easily rebase and modify commits and more. We have a unique approach to merge conflicts that helps split up any conflicting work. It also keeps a timeline so that you can easily undo any operation.
+
+- [Parallel Branches](/features/branch-management/virtual-branches)
+- [First Class Conflicts](/features/branch-management/merging)
+- [Project History](/features/timeline)
+
+
+# why-gitbutler.mdx
+
+The GitButler manifesto, as it were.
+
+Everyone loves a good manifesto. So, why is there a need for a new Git client in the world? Don't we have enough? Isn't the command line just fine?
+
+Having cofounded GitHub, trained dozens of corporate teams on distributed version control tools and literally written the book on Git, we have spent a lot of time and energy over the last decade thinking about the source code management tools that software developers use every day.
+
+GitHub has changed the way that millions of developers across the world collaborate and work with their source code, but as sophisticated and user friendly as that tool is in our daily coding lives, using GitHub or GitLab or Bitbucket still requires all of those developers to work with a command line tool that is confusing, difficult to use, error prone and not originally designed or built for the workflows and processes that most developers today use. That tool is Git.
+
+Sure, some small minority will use a GUI of some sort, but even those tools are mostly wrappers around the core concepts of Git itself, never reimagining what source code management could be or if Git itself is actually good at helping them with the tasks they face on a daily basis. I've never personally used one because they do little that Git itself doesn't and honestly it's generally easier to just do those tasks on the command line, where it's quick and efficient and I don't have to take my hands off the keyboard.
+
+But what if we broke down everything that you try to accomplish with Git, with source code management tools in general, reduce them down to first principles and imagine a tool that does all of those things better? Are you using Git because it's the best way you can imagine accomplishing those tasks, or are you using it because it's what is there, it's what works with GitHub, it's the only real option?
+
+The reality is that source code management tools have changed very little on a fundamental level in the last 40 years. If you look at the tools and commands and interface that RCS had in the 80s, or Subversion had in the 90s, is it really massively different than how you use Git today on a daily basis?
+
+Yes, Git has easy branching, acceptable merging, a nice network transport method to move your code around, but you're still making manual checkins, you're still trying to remember obscure arguments, you're still losing work when things get complicated.
+
+GitButler is rethinking everything between when you write code in your editor of choice and when you push that code to GitHub for review. Why are you making 'wip' commits when your SCM should be recording everything for you? Why are everyone's commit messages close to useless? Why is `git blame` the best way to get context on the code your team has written? Why can't you seamlessly transition work between computers?
+
+We are creating not only a new kind of Git client, but an entirely new way of thinking about managing the code that you work on. A tool that helps you at every step of the software development process. A code concierge, hard at work for you to ensure that you'll never lose a moment of work again. That you'll have all the context and support you'll need around every line of code you work on.
+
+Managing your source code can be different, smarter, leaps ahead of the 40 year old concepts that we're using today.
+
+Our goal is to make sure that nobody ever has to read Scott's book again. That you don't have to learn how to manage your source code management tool.
+
+
+
+
# workspace-branch.mdx
If you run some normal Git commands (like `git log`) while in GitButler mode, you'll see a few special branches that GitButler maintains behind the scenes. The one that most people get confused by is the `gitbutler/workspace` commit.
@@ -616,97 +702,6 @@ Note that if `extraCsp` is the only entry in the JSON file, you may want to encl
The changes will take effect the next time you start GitButler.
-# fetch-push.mdx
-
-
-If you are having trouble pushing or fetching from a remote, this is likely related to git authentication. Here are a few configuration options you can try out, found in the project settings.
-
-## Configuring the auto-fetch frequency
-
-GitButler will periodically fetch from your configured remotes in order to display new branches etc. By default, this happens every every 15 minutes.
-
-You can configure the interval or completely disable this behavior by editing the application's `settings.json` file:
-
-
- ```bash ~/Library/Application\ Support/gitbutler/settings.json ```
- ```bash C:\Users\[username]\AppData\Roaming\gitbutler\settings.json ```
- ```bash ~/.config/gitbutler/settings.json ```
-
-
-The file is in JSONC format and follows the [following schema](https://github.com/gitbutlerapp/gitbutler/blob/master/crates/but-settings/assets/defaults.jsonc)
-
-```json
- "fetch": {
- "autoFetchIntervalMinutes": 15
- }
-```
-
-A negative value (e.g. -1) disables auto fetching. Note that if `fetch` is the only entry in the JSON file, you may want to enclose it in a top-level object.
-
-## Available authentication methods
-
-GitButler can be configured to use several different git authentication methods. You can switch between them in your project settings. You can try multiple different options and see if any of them are appropriate for your setup. Note that if you are on Windows, the only applicable method is the "Git executable", therefore the application will now show this as a configuration option.
-
-
-
-### Use a Git executable (default)
-
-The default way to push and fetch is for GitButler to use an existing system Git executable. This should use whatever authentication mechanism that Git uses for the remote that you're trying to push to or fetch from.
-
-### Use an existing SSH key
-
-If already have an SSH key set up (eg. `~/.ssh/id_rsa`), you can instruct GitButler to use it. In case the key is password protected, you can also provide the password to it (which will be stored locally).
-
-### Use locally generated SSH key
-
-This option generates a new SSH key which will be stored locally in the application [data dir](https://docs.gitbutler.com/development/debugging#data-files). For this to work you will need to add the new public key to your Git remote provider.
-
-### Use a git credential helper
-
-If your system is set up with a credential helper, GitButler can use that. For more info on git credential helpers, see this [article](https://git-scm.com/doc/credential-helpers).
-
-### FIDO security keys (YubiKey, etc.)
-
-If you're using a FIDO key, check out this issue to see how people have set it up with the Git executable method: [#2661](https://github.com/gitbutlerapp/gitbutler/issues/2661)
-
-### Keys managed by 1Password
-
-Keys stored in 1Password should properly use it as an SSH agent for authentication and signing commits if you use the Git executable option. (Previously tracked in [#2779](https://github.com/gitbutlerapp/gitbutler/issues/2779))
-
-### Host certificate checks
-
-There is an option to ignore host certificate checks when authenticating with ssh. This may be a helpful option to enable in some cases.
-
-## Other known issues
-
-### Git remote servers with a non-standard SSH port
-In some cases, the git remote may be setup on a port number other than 22. If the port is set in your `~/.ssh/config` file, GitButler will not be able to recognize that - tracked in GitHub issue [#2700](https://github.com/gitbutlerapp/gitbutler/issues/2700).
-
-As a workaround you may set your remote in the [SSH format](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) (eg. `ssh://git@example.com:3022/foo/bar.git`)
-
-Updating parallel branches when the respective remote has new commits
-If you have added a remote branch to your active workspace in GitButler, or pushed a virtual branch to the remote, and new commits are added to the remote branch, there is currently no way to sync those new commits into the existing virtual branch in GitButler. This is being tracked in the GitHub issue [#2649](https://github.com/gitbutlerapp/gitbutler/issues/2649).
-
-The current workaround is to undo any local commits and then stash your local changes manually using [git stash](https://git-scm.com/docs/git-stash) and then delete the virtual branch that has upstream changes. Then you can update the trunk by clicking the update button next to the word "Trunk" in the sidebar on the left to make sure all new upstream changes are synced, then select the remote branch that has the new changes and click the "Apply +" button above the list of commits for the branch. Once the updated branch is applied to your working directory, you can manually `git stash pop` your stashed changes and then resolve any merge conflicts.
-
-### OAuth app access restrictions on your GitHub organization
-
-If you're submitting code and PRs to a repository under an organization on GitHub, you may receive an error that, despite having correct authorization credentials, your organization has enabled OAuth app access restrictions. These restrictions are an organization-level security feature designed to prevent unauthorized third-party applications from accessing organization resources.
-
-To solve this, go to Applications. Select the "Authorized OAuth Apps" tab, and look for "GitButler Client". If you don't find "GitButler Client", it's possible you haven't yet set GitButler up for personal use. If so, try creating a test commit on a test branch for a personal repository using GitButler, which you can delete after, then check the same tab as before.
-
-If you see "GitButler Client", click on it and, under "Organization Access", across from the organization you wish to enable GitButler for, click either the "Request" or "Grant" button, depending on whether you are a contributor or owner, respectively. If you're a contributor clicking "Request", note that you'll need to wait for an organization owner to approve your access request before you can proceed.
-
-Note for organization owners: To streamline this process for your team members, you can pre-approve GitButler for all organization members. This eliminates the need for individual access requests and approvals. This can be managed through your organization's OAuth app access settings.
-
-### Help on Discord
-If none of the available options helps, feel free to hop on our [Discord](https://discord.gg/MmFkmaJ42D) and we will be happy to help you out.
-
-
-
# fixing-conflicts-outside-gitbutler.mdx
If you have ended up with conflicted commits and GitButler is completely
@@ -913,249 +908,95 @@ Once you have finished bringing all of your commits into your reconstruction
branch, you can then push it to your remote via `git push`.
-# why-gitbutler.mdx
+# fetch-push.mdx
-The GitButler manifesto, as it were.
-Everyone loves a good manifesto. So, why is there a need for a new Git client in the world? Don't we have enough? Isn't the command line just fine?
+If you are having trouble pushing or fetching from a remote, this is likely related to git authentication. Here are a few configuration options you can try out, found in the project settings.
-Having cofounded GitHub, trained dozens of corporate teams on distributed version control tools and literally written the book on Git, we have spent a lot of time and energy over the last decade thinking about the source code management tools that software developers use every day.
+## Configuring the auto-fetch frequency
-GitHub has changed the way that millions of developers across the world collaborate and work with their source code, but as sophisticated and user friendly as that tool is in our daily coding lives, using GitHub or GitLab or Bitbucket still requires all of those developers to work with a command line tool that is confusing, difficult to use, error prone and not originally designed or built for the workflows and processes that most developers today use. That tool is Git.
+GitButler will periodically fetch from your configured remotes in order to display new branches etc. By default, this happens every every 15 minutes.
-Sure, some small minority will use a GUI of some sort, but even those tools are mostly wrappers around the core concepts of Git itself, never reimagining what source code management could be or if Git itself is actually good at helping them with the tasks they face on a daily basis. I've never personally used one because they do little that Git itself doesn't and honestly it's generally easier to just do those tasks on the command line, where it's quick and efficient and I don't have to take my hands off the keyboard.
+You can configure the interval or completely disable this behavior by editing the application's `settings.json` file:
-But what if we broke down everything that you try to accomplish with Git, with source code management tools in general, reduce them down to first principles and imagine a tool that does all of those things better? Are you using Git because it's the best way you can imagine accomplishing those tasks, or are you using it because it's what is there, it's what works with GitHub, it's the only real option?
+
+ ```bash ~/Library/Application\ Support/gitbutler/settings.json ```
+ ```bash C:\Users\[username]\AppData\Roaming\gitbutler\settings.json ```
+ ```bash ~/.config/gitbutler/settings.json ```
+
-The reality is that source code management tools have changed very little on a fundamental level in the last 40 years. If you look at the tools and commands and interface that RCS had in the 80s, or Subversion had in the 90s, is it really massively different than how you use Git today on a daily basis?
+The file is in JSONC format and follows the [following schema](https://github.com/gitbutlerapp/gitbutler/blob/master/crates/but-settings/assets/defaults.jsonc)
-Yes, Git has easy branching, acceptable merging, a nice network transport method to move your code around, but you're still making manual checkins, you're still trying to remember obscure arguments, you're still losing work when things get complicated.
+```json
+ "fetch": {
+ "autoFetchIntervalMinutes": 15
+ }
+```
-GitButler is rethinking everything between when you write code in your editor of choice and when you push that code to GitHub for review. Why are you making 'wip' commits when your SCM should be recording everything for you? Why are everyone's commit messages close to useless? Why is `git blame` the best way to get context on the code your team has written? Why can't you seamlessly transition work between computers?
+A negative value (e.g. -1) disables auto fetching. Note that if `fetch` is the only entry in the JSON file, you may want to enclose it in a top-level object.
-We are creating not only a new kind of Git client, but an entirely new way of thinking about managing the code that you work on. A tool that helps you at every step of the software development process. A code concierge, hard at work for you to ensure that you'll never lose a moment of work again. That you'll have all the context and support you'll need around every line of code you work on.
+## Available authentication methods
-Managing your source code can be different, smarter, leaps ahead of the 40 year old concepts that we're using today.
+GitButler can be configured to use several different git authentication methods. You can switch between them in your project settings. You can try multiple different options and see if any of them are appropriate for your setup. Note that if you are on Windows, the only applicable method is the "Git executable", therefore the application will now show this as a configuration option.
-Our goal is to make sure that nobody ever has to read Scott's book again. That you don't have to learn how to manage your source code management tool.
+
-
+### Use a Git executable (default)
+The default way to push and fetch is for GitButler to use an existing system Git executable. This should use whatever authentication mechanism that Git uses for the remote that you're trying to push to or fetch from.
-# gerrit-mode.mdx
-
-Not _everyone_ uses GitHub or GitLab to review code and collaborate. If you use the [Gerrit](https://www.gerritcodereview.com/) code review tool, GitButler has a mode for you! In fact, GitButler is the best Gerrit client there is.
-
-## What is Gerrit
-
-If you've never heard of Gerrit, it's used by large teams like the Android or Chrome projects to manage huge numbers of changes and users across large numbers of interdependent repositories.
-
-Here is an example of incoming changesets on the [Android project](https://android-review.googlesource.com/q/status:open+-is:wip,50):
-
-
-
-## How is Gerrit different than Pull/Merge Requests?
-
-Good question. With GitHub or GitLab, when you send a pull/merge request, the review process is branch based. If you add more commits on top of your branch, the changes are squashed into one big unified diff for review. Most teams tend to avoid rebasing anything that was already shared.
-
-Gerrit is a commit based review system. Every review is based on exactly one commit. It's very common to edit shared commits and submit new versions of them to address feedback.
-
-This model works _very well_ with GitButler's easy [commit editing](/features/branch-management/commits) features. With any other Git client, interactive rebasing and amending tends to be quite painful and error prone, making it fairly difficult to work with Gerrit's model. With GitButler, it's ideal. Just drag and drop changes and update your changesets easily.
-
-## How to turn on Gerrit Mode
-
-If you have a Gerrit remote, GitButler will automatically enable Gerrit Mode when the project is being added to GitButler. You can also enable it manually.
-To manually turn on Gerrit Mode in GitButler, you just have to set a Git config option called `gitbutler.gerritMode` in the project you want to act in a Gerrit compatible fashion:
-
-```
-❯ cd my_project
-❯ git config gitbutler.gerritMode 1
-```
-
-## What is Gerrit Mode
-
-Now GitButler will change its behavior in the following ways:
-
-- When you commit, we will automatically inject a `Change-Id` trailer into the commit in the format that Gerrit expects. You do not need to [setup a `commit-msg` hook](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html) like you do with other Git clients.
-- When you push, it will not push to a matching branch name on the remote. Instead it will push to `refs/for/main` (or whatever the name of the target branch is set to be).
-- After a push, we record the change url and show you the link and number for each commit automatically.
-
-
-
-We can also set some extra push options when we push, including:
-
-- [Topics](https://gerrit-review.googlesource.com/Documentation/cross-repository-changes.html)
-- [Hashtags](https://gerrit-review.googlesource.com/Documentation/intro-user.html#hashtags)
-- [WIP status](https://gerrit-review.googlesource.com/Documentation/intro-user.html#wip)
-
-
-
-
-# coding-agents.mdx
-
-
-GitButler can also orchestrate your coding agents and help automatically manage, checkpoint and commit the work that they do for you.
-
-
- Currently the only supported agent is [Claude Code](https://www.anthropic.com/claude-code), but we
- are working on more agent support.
-
-
-You can start a session by clicking the AI stars on a branch header, or use the shortcut for a new branch and AI session in the top right corner of the window.
-
-
-
-Each session is tied to a branch such that you can run them in parallel, and changes are assigned to the respective branch as long as they are mutually exclusive. Information about the branch is also added to the respective context, giving the agent knowledge of the work they contain.
-
-# Setup
-
-There is some basic setup that may need to be done the first time, if you've never used Claude Code before.
-
-### Installing Claude Code
-
-Before you can use the agents integration, you need to have Claude Code installed as we wrap the SDK that it provides. If we can't find the binary, you should see something like this:
+### Use an existing SSH key
-
+If already have an SSH key set up (eg. `~/.ssh/id_rsa`), you can instruct GitButler to use it. In case the key is password protected, you can also provide the password to it (which will be stored locally).
-To install Claude Code, you can read through the docs [here](https://docs.anthropic.com/en/docs/claude-code/quickstart), but the simple version is to use their "Native Install" method:
+### Use locally generated SSH key
-{/* */}
+This option generates a new SSH key which will be stored locally in the application [data dir](https://docs.gitbutler.com/development/debugging#data-files). For this to work you will need to add the new public key to your Git remote provider.
-
-
- ```bash
- curl -fsSL https://claude.ai/install.sh | bash
- ```
-
-
- ```bash
- irm https://claude.ai/install.ps1 | iex
- ```
-
-
- ```bash
- curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del
- install.cmd
- ```
-
-
-{/* */}
+### Use a git credential helper
-You will then need to setup and login to Claude Code, which will require an Anthropic account. You can either connect it to an API key for direct billing or use one of the plans. You can learn more on the [Claude Code](https://www.anthropic.com/claude-code) page.
+If your system is set up with a credential helper, GitButler can use that. For more info on git credential helpers, see this [article](https://git-scm.com/doc/credential-helpers).
-
- GitButler does not charge you for agent use, but Anthropic does. This goes directly through Claude
- Code usage, we simply help manage the agent.
-
+### FIDO security keys (YubiKey, etc.)
-# Generating Code with an Agent
+If you're using a FIDO key, check out this issue to see how people have set it up with the Git executable method: [#2661](https://github.com/gitbutlerapp/gitbutler/issues/2661)
-Once your agent is setup, you can select a branch to work on, type in a prompt and we will run that though Claude Code, same as if you ran it in the terminal.
+### Keys managed by 1Password
-
+Keys stored in 1Password should properly use it as an SSH agent for authentication and signing commits if you use the Git executable option. (Previously tracked in [#2779](https://github.com/gitbutlerapp/gitbutler/issues/2779))
-While this is still running Claude Code, running through the GitButler UI will make sure that each agent works on the branch it is attached to. You can run multiple agents at once, each committing to their attached branches.
+### Host certificate checks
-### Model Selection
+There is an option to ignore host certificate checks when authenticating with ssh. This may be a helpful option to enable in some cases.
-There are a few different models that you can choose from for running your task. You can change your active model in the model selection dialog of the chat box.
+## Other known issues
-
+### Git remote servers with a non-standard SSH port
+In some cases, the git remote may be setup on a port number other than 22. If the port is set in your `~/.ssh/config` file, GitButler will not be able to recognize that - tracked in GitHub issue [#2700](https://github.com/gitbutlerapp/gitbutler/issues/2700).
-### Thinking Modes
+As a workaround you may set your remote in the [SSH format](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) (eg. `ssh://git@example.com:3022/foo/bar.git`)
-Claude Code also allows for selection of a "thinking mode". The lower modes are faster, the higher modes tend to take longer and be more expensive, but can produce better results.
+Updating parallel branches when the respective remote has new commits
+If you have added a remote branch to your active workspace in GitButler, or pushed a virtual branch to the remote, and new commits are added to the remote branch, there is currently no way to sync those new commits into the existing virtual branch in GitButler. This is being tracked in the GitHub issue [#2649](https://github.com/gitbutlerapp/gitbutler/issues/2649).
-
+The current workaround is to undo any local commits and then stash your local changes manually using [git stash](https://git-scm.com/docs/git-stash) and then delete the virtual branch that has upstream changes. Then you can update the trunk by clicking the update button next to the word "Trunk" in the sidebar on the left to make sure all new upstream changes are synced, then select the remote branch that has the new changes and click the "Apply +" button above the list of commits for the branch. Once the updated branch is applied to your working directory, you can manually `git stash pop` your stashed changes and then resolve any merge conflicts.
-### Prompt Templates
+### OAuth app access restrictions on your GitHub organization
-If you find that you're using similar prompts over and over, you can easily setup several prompt templates. Selecting one will seed the prompt with the contents of that template.
+If you're submitting code and PRs to a repository under an organization on GitHub, you may receive an error that, despite having correct authorization credentials, your organization has enabled OAuth app access restrictions. These restrictions are an organization-level security feature designed to prevent unauthorized third-party applications from accessing organization resources.
-
+To solve this, go to Applications. Select the "Authorized OAuth Apps" tab, and look for "GitButler Client". If you don't find "GitButler Client", it's possible you haven't yet set GitButler up for personal use. If so, try creating a test commit on a test branch for a personal repository using GitButler, which you can delete after, then check the same tab as before.
-You can also edit your available templates by selecting the "Edit templates" option, which opens up our JSON file in your editor of choice. The templates look something like this:
+If you see "GitButler Client", click on it and, under "Organization Access", across from the organization you wish to enable GitButler for, click either the "Request" or "Grant" button, depending on whether you are a contributor or owner, respectively. If you're a contributor clicking "Request", note that you'll need to wait for an organization owner to approve your access request before you can proceed.
-````json
-{
- "templates": [
- {
- "label": "Bug Fix",
- "template": "Please fix the bug in this code:\n\n```\n// Your code here\n```\n\nExpected behavior:\nActual behavior:\nSteps to reproduce:"
- },
- {
- "label": "Code Review",
- "template": "Please review this code for:\n- Performance issues\n- Security vulnerabilities\n- Best practices\n- Code style\n\n```\n// Your code here\n```"
- },
- {
- "label": "Refactor",
- "template": "Please refactor this code to improve:\n- Readability\n- Performance\n- Maintainability\n\n```\n// Your code here\n```\n\nRequirements:"
- },
- {
- "label": "Add Tests",
- "template": "Please write comprehensive tests for this code:\n\n```\n// Your code here\n```\n\nTest cases should cover:\n- Happy path\n- Edge cases\n- Error conditions"
- }
- ]
-}
-````
+Note for organization owners: To streamline this process for your team members, you can pre-approve GitButler for all organization members. This eliminates the need for individual access requests and approvals. This can be managed through your organization's OAuth app access settings.
-### Context Clearing
+### Help on Discord
+If none of the available options helps, feel free to hop on our [Discord](https://discord.gg/MmFkmaJ42D) and we will be happy to help you out.
-After a while, your context in a single branch can get long. If you no longer need all the context but want to keep your agent working on the same branch, you can clear it with the "Clear Context" button in the context menu.
# recovering-stuff.mdx
@@ -1400,52 +1241,113 @@ The virtual_branches tree has the actual contents of those computed branches in
This allows you to get contents of any file in any of your virtual branch states as well.
-# gitlab-integration.mdx
+# gerrit-mode.mdx
+Not _everyone_ uses GitHub or GitLab to review code and collaborate. If you use the [Gerrit](https://www.gerritcodereview.com/) code review tool, GitButler has a mode for you! In fact, GitButler is the best Gerrit client there is.
-Create your GitLab Merge requests without leaving GitButler.
+## What is Gerrit
-## Setting up the GitLab Integration
+If you've never heard of Gerrit, it's used by large teams like the Android or Chrome projects to manage huge numbers of changes and users across large numbers of interdependent repositories.
-In order to set up the GitLab integration, you will need two things. Firstly, a GitLab Personal Token and the Project ID for your project.
+Here is an example of incoming changesets on the [Android project](https://android-review.googlesource.com/q/status:open+-is:wip,50):
-### Creating a GitLab Personal Token
+
-To create a GitLab Personal Token, navigate to your GitLab preferences, and then click on the "Access tokens" tab. You will then see an "Add new token" button. Pressing this button will provide you with a form (as captured below) where you can specify the token name, expiration date, and scopes. We currently require the `api` scope. In this example, I've chosen to set the expiration date for the token to a year from now.
+## How is Gerrit different than Pull/Merge Requests?
-
+Good question. With GitHub or GitLab, when you send a pull/merge request, the review process is branch based. If you add more commits on top of your branch, the changes are squashed into one big unified diff for review. Most teams tend to avoid rebasing anything that was already shared.
-On completion, you will be showen the following screen which contains your GitLab Personal token.
+Gerrit is a commit based review system. Every review is based on exactly one commit. It's very common to edit shared commits and submit new versions of them to address feedback.
-
+This model works _very well_ with GitButler's easy [commit editing](/features/branch-management/commits) features. With any other Git client, interactive rebasing and amending tends to be quite painful and error prone, making it fairly difficult to work with Gerrit's model. With GitButler, it's ideal. Just drag and drop changes and update your changesets easily.
-### Finding your GitLab Project ID
+## How to turn on Gerrit Mode
-Navigate to the main page of the repository you want to configure the integration for. On the top left next to the "Fork" button, you will see three dots. Click on those three dots, and click on "Copy project ID". This will copy the GitLab Project ID to your clipboard.
+If you have a Gerrit remote, GitButler will automatically enable Gerrit Mode when the project is being added to GitButler. You can also enable it manually.
+To manually turn on Gerrit Mode in GitButler, you just have to set a Git config option called `gitbutler.gerritMode` in the project you want to act in a Gerrit compatible fashion:
-
+```
+❯ cd my_project
+❯ git config gitbutler.gerritMode 1
+```
-### Configuring GitButler
+## What is Gerrit Mode
-Inside GitButler, navigate to the project settings by clicking on the small cog icon in the bottom left. Scroll down to the bottom of the "Project" tab where you will see a form for entering your GitLab details. The provided GitLab Personal Token will be stored securly in your operating system's keychain.
+Now GitButler will change its behavior in the following ways:
-
+- When you commit, we will automatically inject a `Change-Id` trailer into the commit in the format that Gerrit expects. You do not need to [setup a `commit-msg` hook](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html) like you do with other Git clients.
+- When you push, it will not push to a matching branch name on the remote. Instead it will push to `refs/for/main` (or whatever the name of the target branch is set to be).
+- After a push, we record the change url and show you the link and number for each commit automatically.
-### Custom GitLab Instances
+
-You may also provide a different Instance URL if you are using a self-hosted GitLab instance.
+We can also set some extra push options when we push, including:
-Note that if you use a custom GitLab instance, you will likely need to configure a custom CSP (Content Security Policy) to allow GitButler to connect to it. You can find more information on how to do that in the [Custom Content Security Policy (CSP)](/troubleshooting/custom-csp) section of the documentation.
+- [Topics](https://gerrit-review.googlesource.com/Documentation/cross-repository-changes.html)
+- [Hashtags](https://gerrit-review.googlesource.com/Documentation/intro-user.html#hashtags)
+- [WIP status](https://gerrit-review.googlesource.com/Documentation/intro-user.html#wip)
-## Usage
+
-You will now have a "Submit for Review" button on each branch which you can use to create a Merge Request.
-
+# timeline.mdx
-Once the Merge Request is created you will be able to see the status of it from within the client. Please note that we do not yet integrate with CI status.
-
+Undo nearly any of your actions or go back in time to an earlier state.
+
+## How it works
+
+Before GitButler does any major action, it records the state of everything (your virtual branch state, your uncommitted work, conflict state, etc) and stores it in your Git object database as snapshots. You can hit the 'revert' button on any of the entries and it will restore the state of all of these things to what they looked like when they were recorded, letting you go back in time.
+
+
+
+## Restoring State
+
+If you hover over any of the entries, you will see a button named "Revert" that will restore the state of things to right before you did that action. So if you revert one that says "Create Commit", it will put you where you were right before you made that commit.
+
+
+
+## Recovering Content
+
+Occasionally, GitButler will also take snapshots of files that were changed recently, even if they weren't committed. If this, or any other action, sees changes in files, you can see which ones and view the change by clicking on the file name.
+
+
# github-integration.mdx
@@ -1571,51 +1473,9 @@ Once you have set up GitHub integration, you can open your pull requests directl
When you create a new branch or commit changes, GitButler will automatically check if there are any associated pull requests on GitHub. You can view these pull requests in the "Pull Requests" tab in the sidebar of the Branches page.
-# timeline.mdx
+# ai-assistance.mdx
-
-Undo nearly any of your actions or go back in time to an earlier state.
-
-## How it works
-
-Before GitButler does any major action, it records the state of everything (your virtual branch state, your uncommitted work, conflict state, etc) and stores it in your Git object database as snapshots. You can hit the 'revert' button on any of the entries and it will restore the state of all of these things to what they looked like when they were recorded, letting you go back in time.
-
-
-
-## Restoring State
-
-If you hover over any of the entries, you will see a button named "Revert" that will restore the state of things to right before you did that action. So if you revert one that says "Create Commit", it will put you where you were right before you made that commit.
-
-
-
-## Recovering Content
-
-Occasionally, GitButler will also take snapshots of files that were changed recently, even if they weren't committed. If this, or any other action, sees changes in files, you can see which ones and view the change by clicking on the file name.
-
-
-
-
-# ai-assistance.mdx
-
-## Getting Started
+## Getting Started
### Global AI Setup (One-time)
@@ -1739,6 +1599,54 @@ Generates comprehensive PR descriptions when creating pull requests.
- Review [troubleshooting guide](https://docs.gitbutler.com/troubleshooting/custom-csp) for advanced configurations
+# gitlab-integration.mdx
+
+
+Create your GitLab Merge requests without leaving GitButler.
+
+## Setting up the GitLab Integration
+
+In order to set up the GitLab integration, you will need two things. Firstly, a GitLab Personal Token and the Project ID for your project.
+
+### Creating a GitLab Personal Token
+
+To create a GitLab Personal Token, navigate to your GitLab preferences, and then click on the "Access tokens" tab. You will then see an "Add new token" button. Pressing this button will provide you with a form (as captured below) where you can specify the token name, expiration date, and scopes. We currently require the `api` scope. In this example, I've chosen to set the expiration date for the token to a year from now.
+
+
+
+On completion, you will be showen the following screen which contains your GitLab Personal token.
+
+
+
+### Finding your GitLab Project ID
+
+Navigate to the main page of the repository you want to configure the integration for. On the top left next to the "Fork" button, you will see three dots. Click on those three dots, and click on "Copy project ID". This will copy the GitLab Project ID to your clipboard.
+
+
+
+### Configuring GitButler
+
+Inside GitButler, navigate to the project settings by clicking on the small cog icon in the bottom left. Scroll down to the bottom of the "Project" tab where you will see a form for entering your GitLab details. The provided GitLab Personal Token will be stored securly in your operating system's keychain.
+
+
+
+### Custom GitLab Instances
+
+You may also provide a different Instance URL if you are using a self-hosted GitLab instance.
+
+Note that if you use a custom GitLab instance, you will likely need to configure a custom CSP (Content Security Policy) to allow GitButler to connect to it. You can find more information on how to do that in the [Custom Content Security Policy (CSP)](/troubleshooting/custom-csp) section of the documentation.
+
+## Usage
+
+You will now have a "Submit for Review" button on each branch which you can use to create a Merge Request.
+
+
+
+Once the Merge Request is created you will be able to see the status of it from within the client. Please note that we do not yet integrate with CI status.
+
+
+
+
# branch-lanes.mdx
@@ -2067,168 +1975,8 @@ If you're using GitHub integration and the branch has an associated pull request
- [Parallel Branches](/features/branch-management/virtual-branches) - Core concepts of GitButler's virtual branch system
-# pushing-and-fetching.mdx
-
-
-GitButler can authenticate with an upstream Git server in several different ways.
-
- You can just tell us to use the system Git executable, which you can setup however you want. You can use our built in SSH protocol with your own SSH key (this does not require you to have Git installed), or you can use the default [Git credentials helper](https://git-scm.com/doc/credential-helpers).
-
-You can set your preference (and test if it works) in your project's "Git authentication" section:
-
-
-
-Once that's done, GitButler will be able to automatically fetch upstream work and push new branches to your upstream server.
-
-
-# overview.mdx
-
-
-# Butler Review
-
-
- We have paused work on Butler Review for now to concentrate more on the client experience. Review
- will be coming back in our upcoming server functionality, stay tuned.
-
-
-Butler Review is a new approach to code review that focuses on reviewing code
-as a series of evolving patches rather than a unified diff of a whole branch.
-
-
-
-## Why Butler Review?
-
-Traditional code review tools like GitHub and GitLab show changes as a single
-diff of the entire branch. This makes it hard to review changes in a branch
-incrementally, especially when the branch is large. It also discourages creating
-good commit or commit messages, since they are all sqaushed in review and
-messages are difficult to find and unrelated to the code review UI.
-
-Butler Review approaches the problem differently, by making it easy to review
-individual commits as patches and tracking changes to the series when you rebase
-or amend the branch.
-
-This makes it easier to review changes incrementally and evolve a series rather
-than pushing poor commits to the branch to address feedback.
-
-## Enabling Butler Review
-
-To start using Butler Reviews, you need to enable the feature in your GitButler
-client in the project settings. Click the gear icon in the bottom left corner of
-the GitButler client and go to the Server tab.
-
-
-
-Once you enable Butler Review, you can start creating reviews for your branches.
-
-## Creating a Review
-
-Once you have enabled Butler Review for a project, you can create a review for
-a branch by clicking the new "Create Butler Review" button in the branch header card.
-
-
-
-Once you create a review, you will see a new card in the branch header that
-shows the status of the review.
-
-
-
-If you have GitHub integration enabled, you will see a dropdown to let you choose
-to create a PR or a Butler Review. You can also create both, in either order and
-they will be linked together.
-
-
-
-Once a Review has been opened, you will have a URL that you can share with your
-team to get feedback on your changes.
-
-## Reviewing a Series
-
-When a reviewer opens a review, they will see a list of patches that make up the branch.
-
-
-
-
- Currently, all reviews are "unlisted", meaning that anyone with the URL can see the review.
- In the future, we will implement fully public and fully private reviews, but currently all reviews
- are unlisted.
-
-However, if someone has the URL, they will only be able to see the patch data,
-they will not have access to all of your source code, nor will they be able to make changes,
-only approve or request changes.
-
-
-
-Now the reviewer can hit "Start Review" to start reviewing the patches in the series.
-It will start them at the "bottom", the first patch and they can work their way up.
-The reviewer can also click on a patch to go directly to it.
-
-## Reviewing a Patch
-
-Once a reviewer starts reviewing a patch, they will see the changes in the commit
-and a chat window to leave comments.
-
-
-
-The reviewer can leave comments on the patch, approve the patch, or request changes.
-The chat discussion is real time, so reviewers can discuss the changes with the author
-as they review the patch.
-
-You can also select lines of code to comment on. This will highlight the line in the
-diff and show the comment in the chat window.
-
-Every patch needs to be approved before the branch is considered approved.
-
-## Requesting Changes
-
-A reviewer can either approve a patch or request changes. If they request changes,
-the author can amend that specific commit and publish the changes to the review.
-
-Reviewers will be able to see in the chat that a new version of the patch has been
-published and they can review the changes again.
-
-
- Currently we don't have interdiffs, so reviewers will need to review the entire patch again. We
- plan to add interdiffs in the very near future.
-
-
-## Approving a Patch
-
-Once a reviewer is happy with a patch, they can approve it. This will mark the patch
-as approved and move the reviewer to the next patch in the series.
-
-## Closing a Review
-
-Once the branch has been merged, it will automatically mark the review as closed.
-The author can also manually close the review if they decide to abandon the series.
-
-
# rules.mdx
-
Rules are a powerful automation feature in GitButler that automatically assign file changes to specific branches based on conditions you define. Instead of manually dragging changes between lanes, you can set up rules that automatically route changes where they belong.
## Overview
@@ -2277,7 +2025,7 @@ If you don't add any filters, the rule will match all changes.
## Filter Types
-Rules support several types of filters to match changes:
+Rules support filters that match file paths or changed line content.
### Path Matches Regex
@@ -2313,33 +2061,13 @@ Matches the content of changed lines using a regular expression pattern. This fi
Creating a rule that assigns changes containing "fix" to a specific branch
-### Claude Code Session ID
-
-Matches changes that originated from a specific Claude Code session. This filter is automatically used when GitButler's AI features create branches and rules for you.
-
-**Note**: Rules with Claude Code Session ID filters have lower priority than manually created rules. If a change matches both an AI-generated rule and a manual rule, the manual rule takes precedence.
-
-
-
- AI-generated rules based on Claude Code sessions
-
-
## Managing Rules
### Editing Rules
To edit an existing rule:
-1. Double-click the rule or click the elepsis menu (...) and select "Edit rule"
+1. Double-click the rule or click the ellipsis menu (...) and select "Edit rule"
2. Modify the branch assignment or filters
3. Click **Save rule**
@@ -2347,12 +2075,10 @@ To edit an existing rule:
To delete a rule:
-1. Click the elepsis menu (...) on the rule
+1. Click the ellipsis menu (...) on the rule
2. Select "Delete rule"
3. Confirm the deletion
-**Note**: AI-generated rules and implicit rules cannot be edited.
-
## Understanding Rule Evaluation
### Order Matters
@@ -2383,14 +2109,29 @@ Rules respect hunk dependencies (locks). If a change depends on a commit in a sp
## Limitations
- Rules can only assign changes to branches that exist in your workspace (applied branches)
-- Implicit (AI-determined) rules cannot be edited through the UI
- Rules currently only support the `assign` action for filesystem changes
## Related Features
- [Parallel Branches](/features/branch-management/virtual-branches): Understanding the branch system that rules work with
- [Branch Lanes](/features/branch-management/branch-lanes): How lanes are organized and how rules interact with lane positioning
-- [AI Assistance](/features/branch-management/ai-assistance): How AI can create and manage rules automatically
+
+
+# pushing-and-fetching.mdx
+
+
+GitButler can authenticate with an upstream Git server in several different ways.
+
+ You can just tell us to use the system Git executable, which you can setup however you want. You can use our built in SSH protocol with your own SSH key (this does not require you to have Git installed), or you can use the default [Git credentials helper](https://git-scm.com/doc/credential-helpers).
+
+You can set your preference (and test if it works) in your project's "Git authentication" section:
+
+
+
+Once that's done, GitButler will be able to automatically fetch upstream work and push new branches to your upstream server.
# signing-commits.mdx
@@ -2684,10 +2425,65 @@ In this case it will merged in the parent branch.
In order to recover from this situation you can simply force push the branches and then re-create the PR that was incorrectly merged.
+# upstream-integration.mdx
+
+Sometimes you work on a branch and someone else pushes to the same upstream branch. Often you won't know this until you try to push and Git tells you something like this:
+
+
+
+In this scenario, GitButler gives you some nice tooling to help you know when this happens as early as possible and help you deal with it easily.
+
+If someone else has pushed to a branch that you're working on, you will see the upstream commits without having to integrate them. You can look at the commits without having to merge them into your branch or rebase your work on top of them.
+
+
+
+When you decide that you do want to integrate the changes, you have two options - rebase or interactively integrate.
+
+## Rebase the changes
+
+If you select "Rebase upstream changes", it will do the equivalent of a `git pull --rebase` which rebases the commits you have locally on top of the ones that the other person has pushed, so you end up with a state like this:
+
+
+
+Now you can push your commit back upstream without a force push. Easy peasy.
+
+## Interactively integrate the changes
+
+However, let's say that you want to do something more complex. Maybe the other implemented the same thing that you did and you want to drop one of them or one of yours, or squash commits together or reorder them. In any of these cases, you can choose the "Interactive integration" option and you get something that looks like this:
+
+
+
+Here you can reorder commits however you want, you can choose to skip some of them, you can squash some of them down, etc. Just make the commits look however you prefer and then hit the "Integrate changes" button and push your final result back to the server.
+
+
# virtual-branches.mdx
-Parallel branches are a powerful feature of GitButler that allow you to work on multiple branches at the same time, committing to them independently and simultaneously. This is a key part of the GitButler experience, allowing you to manage your work in a flexible and efficient way that is not possible with traditional Git tooling.
+Parllel branches are a powerful feature of GitButler that allow you to work on multiple branches at the same time, committing to them independently and simultaneously. This is a key part of the GitButler experience, allowing you to manage your work in a flexible and efficient way that is not possible with traditional Git tooling.
## Overview
@@ -2712,342 +2508,42 @@ Let's say that you make changes to two different files and `git status` would li
One of the nice things with this approach is that since you're starting from changes in a single working directory, you can be sure that all branches that you create from it will merge cleanly, as you're essentially starting from the merge product and extracting branches of work from it.
-# ai-overview.mdx
+# supporters.mdx
-If you're using AI agent tools like Cursor, Windsurf, or Claude Code, GitButler can enhance your coding experience by managing commits, saving points, and more. These integrations allow you to focus on coding with your agents while GitButler handles the version control aspects.
-
-https://www.youtube.com/watch?v=J6xV_Wyz9zg
-
-There are currently three main ways to use AI tools with GitButler:
-
-1. **Our Coding Agent**: If you have Claude Code setup, you can use our [Code Agent](/features/coding-agents) as a GUI for running Claude Code directly.
-2. **Using Hooks in Claude Code or Cursor**: This method allows you to use GitButler's CLI as hook commands to manage commits and branches in either Claude Code or Cursor.
-3. **Using the MCP Server**: This method allows you to set up your AI agent to communicate with GitButler's MCP server, enabling features like automatic commits and save points.
-
-## Enabling the experimental feature flag
-
-Note that as of GitButler version `0.15.2` these features have to be enabled via an experimental feature flag. You can find that under `Global Settings` -> `Experimental` -> `GitButler Actions`.
-
-
-# claude-code-hooks.mdx
-
-If you are using Claude Code, you can use the new ["hooks"](https://docs.anthropic.com/en/docs/claude-code/hooks) functionality to manage the output of even multiple simultaneous instances, while isolating all the generated code into virtual or stacked branches automatically. In this case, there is no need to set up the MCP server, as the hooks will handle everything for you.
-
-Here's a short video showing how GitButler works with Claude Code:
-
-https://youtu.be/AwwPwSc9qhA
-
-Ok, let's get it set up.
-
-## Install the GitButler CLI
-
-First, you need to install the GitButler CLI, which can be done in your General settings. See the [MCP Server documentation](./mcp-server) for more details on how to install the CLI.
-
-## Installing GitButler as a Hook
-
-Hooks in Claude Code are defined in one of your settings files.
-
-```
-~/.claude/settings.json - User settings
-.claude/settings.json - Project settings
-.claude/settings.local.json - Local project settings (not committed)
-```
-
-Wherever you want to add GitButler to handle your commits automatically, you can add us as a hook by adding the following to the `hooks` array in whatever settings file you want to use:
-
-```json
-{
- "hooks": {
- "PreToolUse": [
- {
- "matcher": "Edit|MultiEdit|Write",
- "hooks": [
- {
- "type": "command",
- "command": "but claude pre-tool"
- }
- ]
- }
- ],
- "PostToolUse": [
- {
- "matcher": "Edit|MultiEdit|Write",
- "hooks": [
- {
- "type": "command",
- "command": "but claude post-tool"
- }
- ]
- }
- ],
- "Stop": [
- {
- "matcher": "",
- "hooks": [
- {
- "type": "command",
- "command": "but claude stop"
- }
- ]
- }
- ]
- }
-}
-```
-
-Essentially, you want to run the `but claude pre-tool` command before any code generation or editing, and the `but claude post-tool` command after it. The `but claude stop` command will run when you stop the agent, ensuring that all changes are committed and branches are updated accordingly.
-
-You also might want to add to your "memories" to ask Claude not to try commiting using Git as it will be handled by GitButler. You can do something like this:
-
-```
-❯ cat ~/.claude/CLAUDE.md
-## Development Workflow
-- Never use the git commit command after a task is finished.
-```
-
-## Using GitButler with Claude Code
-
-With the hooks setup, Claude will tell GitButler when it has generated code or edited files and in which session, which helps GitButler to try to isolate the changes into a single branch per session.
-
-For example, if you have three sessions of Claude Code running at the same time, each will be communicating with GitButler at each step and GitButler will be assigning each change to the correct branch automatically.
-
-When the agent is done, GitButler will commit all the changes and write a more sophisticated commit message based on what you had prompted your agent.
-
-
-# mcp-server.mdx
-
-
-If you use an AI agent (such as Cursor, Windsurf, Claude Code) to help you with your code, you can easily setup GitButler to manage your commits automatically, keep save points, and more. You know, _vibe_ commit...
-
-## Setting up your Agent to use GitButler
-
-The first step is to let your agent know about GitButler, which is done via MCP - you need to tell your agent to use the GitButler MCP server.
-
-### Installing the CLI
-
-GitButler provides a CLI that can be used to interact with the GitButler platform. Before you can setup AI Agent integration, you will need to install the CLI.
-
-This can be found by opening the GitButler global settings, and then clicking on the "Install CLI" button in the General settings.
-
-
-
-Now that you have the `but` CLI installed, your agent can use the CLI's MCP server to interact with GitButler.
-
-### Cursor
-
-To install the GitButler MCP server in Cursor, first go to the Cursor settings, and then click on the "Extensions" tab, then click on "Tools and Integrations" and click on "New MCP Server".
-
-This will open your `~/.cursor/mcp.json` file.
-
-Add the following to the `mcpServers` object:
-
-```json
-{
- "mcpServers": {
- "gitbutler": {
- "command": "but",
- "args": ["mcp"]
- }
- }
-}
-```
-
-You should see the GitButler MCP server in the list of MCP servers and it should have the tool `gitbutler_update_branches` available.
-
-### VSCode
-
-To install the GitButler MCP server in VSCode, you need to select "MCP: List Servers" from the actions menu. Then select "Add Server". Select "stdio" as the server type.
-
-Now you can type your command (`but mcp`) and name it something. After this, it should open up your settings file and show you something like this:
-
-```json
- "mcp": {
- "servers": {
- Running | Stop | Restart | 1 tools
- "gitbutler-mcp": {
- "type": "stdio",
- "command": "but",
- "args": ["mcp"]
- }
- }
- }
-```
-
-However, if you have Cursor's MCP already setup, VSCode will notice and help you automatically reuse the settings.
-
-
-
-### Claude Code
-
-Adding an MCP server to Claude Code is done by running the `claude mcp add` command.
-
-```
-❯ claude mcp add gitbutler but mcp
-Added stdio MCP server gitbutler with command: but mcp to local config
-
-❯ claude mcp list
-gitbutler: but mcp
-```
-
-## Rules: How to configure auto committing
-
-Once you have installed the MCP server in your editor or agent, you can optionally configure it to automatically commit your changes.
-
-We've found that adding something like this to your rules works well:
-
-```
-If you generate code or modify files, run the gitbutler update branches MCP tool.
-```
-
-## How to add rules
-
-Cursor stores its rules in `~/.cursor/rules` file, but you can also manually set them by going to the Cursor Settings pane, clicking 'Rules' and adding them to the User Rules section.
-
-In VSCode's Copilot Agent Mode, you can use ["custom instructions"](https://code.visualstudio.com/docs/copilot/copilot-customization#_custom-instructions) to accomplish this.
-
-In Claude Code, they are now called "memories" and you can add them by hitting '#' and storing them in user memory (or local if you just want them in one project).
-
-
-
-Or directly in your `~/.claude/CLAUDE.md` rules file:
-
-```
-❯ cat ~/.claude/CLAUDE.md
-## Development Workflow
-- When you're done with a task where code was created or files edited, please run the gitbutler mcp update_branches command.
-```
-
-## Using GitButler with your agent
-
-If you've set up a rule/instruction/memory, then every time a chat session is completed, the agent will send the changes and prompt to GitButler and it will automatically commit the changes.
-
-
-
-If you're using Claude Code, it may look something like this:
-
-
-
-If you don't have the agent setup to automatically call our tool, then you can also just manually type 'update gitbutler branches' in the chat, but that's a little less magical.
-
-## GitButler interface
-
-There are two phases to GitButler's MCP agent interaction. The first is the agent sending the changes and prompt to GitButler, which GitButler will quickly record and then return a success to the agent. The second is GitButler processing that raw recorded change and attempting to process that change into a commit.
-
-### Recording the changes
-
-When your agent calls the `gitbutler_update_branches` tool, GitButler will record the changes and prompt and then immediately return to the agent, so the call should be very fast.
-
-So for instance, let's say that I prompted my coding agent to update my `README.md` file to add a list of contributing authors. When the agent is done, it should call the update branches MCP tool, which will record a commit that looks something like this:
-
-
-
-### Processing the changes
-
-Then, if you have AI tooling setup, GitButler will see that and turn it into a commit message like this:
-
-
-
-You can see all of these steps in the "Actions" section of the GitButler interface, which you can toggle by hitting the "Actions" button in the top right of the interface.
-
-
-
-In the near future, we will also be able to do more interesting things like auto-absorbing changes into existing commits, creating new branches based on the prompt theme, creating stacked branches, and more.
-
-
-# cursor-hooks.mdx
-
-GitButler integrates seamlessly with Cursor through hooks that automatically manage your commits and branches while you're using AI coding features. This allows you to automatically maintain clean git history and organized parallel branches.
-
-Here's a short video showing how GitButler works with Cursor hooks:
-
-https://youtu.be/NOYK7LTFvZM
+Thinking about paying for Beta software? Sounds odd, right?
-Ok, let's get it set up.
+No worries, the main stuff in GitButler stays the same whether you pay or not.
-## Install the GitButler CLI
+But hey, we're all about building a cool gang here. We want to know who really digs our butler. And those early supporters? They're like VIPs to us.
-First, you need to install the GitButler CLI, which can be done in your General settings. See the [MCP Server documentation](mcp-server) for more details on how to install the CLI.
+## Perks for Early Supporters
-## Installing GitButler as a Hook
+- Access to our Early Bird Discord room, for life
+- Invitations to exclusive Berlin parties, when it's warm here
+- Care packages of schwag, sent your way
+- Pricing locked in, no matter how we decide to charge later
+- First look at any new features as we go
+- Whatever else we can think of over time
-Once the command line tool is installed, you can add the `but cursor` commands as hooks.
+Your support helps us grow and make GitButler even better. Join us on this adventure!
-You will need to create or edit your `~/.cursor/hooks.json` file (globally) or `[project]/.cursor/hooks.json` file (single project) to have `afterFileEdit` and `stop` hooks like this:
+## How to Support Us
+You need to have a GitButler account to support us. If you don't have one, sign up first.
-```json
-{
- "version": 1,
- "hooks": {
- "afterFileEdit": [
- {
- "command": "but cursor after-edit"
- }
- ],
- "stop": [
- {
- "command": "but cursor stop"
- }
- ]
- }
-}
-```
+
+ }
+ href="https://gitbutler.com/profile"
+ title="GitButler"
+ description="Support GitButler with a monthly contribution"
+ />
+
-## Using GitButler with Cursor
+Thanks, from the GitButler Crew!
-Once the hooks are setup, Cursor will automatically call GitButler when it edits files and when it's done with a task, which will trigger GitButler to:
+
-- Create a branch if the chat session is new
-- Assign edits to an active branch
-- Commit with a message based on the prompt when a task is done
# debugging.mdx
@@ -3217,61 +2713,6 @@ If you start GitButler from the command line and see a bunch of these or similar
This issue most likely stems from an incompatibility between your version of OpenGL (`mesa`) and `libwebkit2gtk-4.1`.
-# upstream-integration.mdx
-
-Sometimes you work on a branch and someone else pushes to the same upstream branch. Often you won't know this until you try to push and Git tells you something like this:
-
-
-
-In this scenario, GitButler gives you some nice tooling to help you know when this happens as early as possible and help you deal with it easily.
-
-If someone else has pushed to a branch that you're working on, you will see the upstream commits without having to integrate them. You can look at the commits without having to merge them into your branch or rebase your work on top of them.
-
-
-
-When you decide that you do want to integrate the changes, you have two options - rebase or interactively integrate.
-
-## Rebase the changes
-
-If you select "Rebase upstream changes", it will do the equivalent of a `git pull --rebase` which rebases the commits you have locally on top of the ones that the other person has pushed, so you end up with a state like this:
-
-
-
-Now you can push your commit back upstream without a force push. Easy peasy.
-
-## Interactively integrate the changes
-
-However, let's say that you want to do something more complex. Maybe the other implemented the same thing that you did and you want to drop one of them or one of yours, or squash commits together or reorder them. In any of these cases, you can choose the "Interactive integration" option and you get something that looks like this:
-
-
-
-Here you can reorder commits however you want, you can choose to skip some of them, you can squash some of them down, etc. Just make the commits look however you prefer and then hit the "Integrate changes" button and push your final result back to the server.
-
-
# contact-us.mdx
@@ -3302,62 +2743,65 @@ As part of our commitment to open source, we are an early member of the [Open So
You can read more about our reasoning to join the Open Source Pledge in our announcement blog post and 2024 report: [GitButler Joins the Open Source Pledge](https://blog.gitbutler.com/open-source-pledge-2024).
-# supporters.mdx
+# but-absorb.mdx
+The semantic for finding "the appropriate commit" is as follows:
-Thinking about paying for Beta software? Sounds odd, right?
+- If a change has a dependency to a particular commit, it will be amended into that particular commit
+- If a change is staged to a particular lane (branch), it will be amended into a commit there
+- If there are no commits in this branch, a new commit is created
+- Changes are amended into the topmost commit of the leftmost (first) lane (branch)
-No worries, the main stuff in GitButler stays the same whether you pay or not.
+Optionally an identifier to an Uncommitted File or a Branch (stack) may be provided.
-But hey, we're all about building a cool gang here. We want to know who really digs our butler. And those early supporters? They're like VIPs to us.
+- If an Uncommitted File id is provided, absorb will be performed for just that file
+- If a Branch (stack) id is provided, absorb will be performed for all changes staged to that stack
+- If no source is provided, absorb is performed for all uncommitted changes
-## Perks for Early Supporters
+If `--dry-run` is specified, no changes will be made; instead, the absorption plan
+(what changes would be absorbed by which commits) will be shown.
-- Access to our Early Bird Discord room, for life
-- Invitations to exclusive Berlin parties, when it's warm here
-- Care packages of schwag, sent your way
-- Pricing locked in, no matter how we decide to charge later
-- First look at any new features as we go
-- Whatever else we can think of over time
+If `--new` is specified, new commits will be created for absorbed changes
+instead of amending existing commits.
-Your support helps us grow and make GitButler even better. Join us on this adventure!
+**Usage:** `but absorb [SOURCE] [OPTIONS]`
-## How to Support Us
-You need to have a GitButler account to support us. If you don't have one, sign up first.
+## Arguments
-
- }
- href="https://gitbutler.com/profile"
- title="GitButler"
- description="Support GitButler with a monthly contribution"
- />
-
+* `` — If the Source is an uncommitted change - the change will be absorbed. If the Source is a stack - anything staged to the stack will be absorbed accordingly. If not provided, everything that is uncommitted will be absorbed
-Thanks, from the GitButler Crew!
+## Options
-
+* `--dry-run` — Show the absorption plan without making any changes
+* `-n`, `--new` — Create new commits, instead of amending existing ones. This is useful when you want to preserve existing commits and add new ones for the absorbed changes
# but-alias.mdx
-Aliases allow you to create shortcuts for commonly used commands. They are stored in git config under the but.alias.* namespace.
+Aliases allow you to create shortcuts for commonly used commands.
+They are stored in git config under the `but.alias.*` namespace.
-Examples
+## Examples
List all configured aliases:
- but alias
+```text
+but alias
+```
Create a new alias:
- but alias add st status
- but alias add stv "status --verbose"
+```text
+but alias add st status
+but alias add stv "status --verbose"
+```
Remove an alias:
- but alias remove st
+```text
+but alias remove st
+```
**Usage:** `but alias `
@@ -3415,47 +2859,16 @@ Examples
* `-g`, `--global` — Remove from global config (in ~/.gitconfig) instead of local
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-
-# but-amend.mdx
-
-Wrapper for `but rub `.
-
-**Usage:** `but amend `
-
-## Arguments
-
-* `` — File ID to amend (required)
-* `` — Commit ID to amend into (required)
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
# but-branch.mdx
-This includes creating, deleting, listing, showing details about, and applying and unapplying branches.
+This includes creating, deleting, listing, and showing details about branches.
By default without a subcommand, it will list the branches.
+To apply or unapply branches, use `but apply` and `but unapply`.
+
**Usage:** `but branch `
## Subcommands
@@ -3559,125 +2972,83 @@ You can also choose to fetch and display review information, show files modified
* `--ai` — Generate AI summary of the branch changes
* `--check` — Check if the branch merges cleanly into upstream and identify conflicting commits
-### `but branch apply`
-
-Apply a branch to the workspace
-
-If you want to apply an unapplied branch to your workspace so you
-can work on it, you can run `but branch apply `.
-
-This will apply the changes in that branch into your working directory
-as a parallel applied branch.
-
-**Usage:** `but branch apply `
-
-**Arguments:**
-
-* `` — Name of the branch to apply (required)
-
-### `but branch unapply`
-
-Unapply a branch from the workspace
-
-If you want to unapply an applied branch from your workspace
-(effectively stashing it) so you can work on other branches,
-you can run `but branch unapply `.
-
-This will remove the changes in that branch from your working
-directory and you can re-apply it later when needed. You will then
-see the branch as unapplied in `but branch list`.
-
-**Usage:** `but branch unapply [OPTIONS]`
-**Arguments:**
-
-* `` — Name of the branch to unapply (required)
-
-**Options:**
-* `-f`, `--force` — Force unapply without confirmation
-
-## Platform Options
+# but-amend.mdx
-These options are available for all `but` commands:
+Wrapper for `but rub `.
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+**Usage:** `but amend `
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+## Arguments
+* `` — File ID to amend (required)
+* `` — Commit ID to amend into (required)
-# but-absorb.mdx
-The semantic for finding "the appropriate commit" is as follows:
+# but-apply.mdx
-- If a change has a dependency to a particular commit, it will be amended into that particular commit
-- If a change is staged to a particular lane (branch), it will be amended into a commit there
-- If there are no commits in this branch, a new commit is created
-- Changes are amended into the topmost commit of the leftmost (first) lane (branch)
+If you want to apply an unapplied branch to your workspace so you
+can work on it, you can run `but apply `.
-Optionally an identifier to an Uncommitted File or a Branch (stack) may be provided.
+This will apply the changes in that branch into your working directory
+as a parallel applied branch.
-- If an Uncommitted File id is provided, absorb will be performed for just that file
-- If a Branch (stack) id is provided, absorb will be performed for all changes staged to that stack
-- If no source is provided, absorb is performed for all uncommitted changes
+## Examples
-If --dry-run is specified, no changes will be made; instead, the absorption plan (what changes would be absorbed by which commits) will be shown.
+Apply by branch name:
-If --new is specified, new commits will be created for absorbed changes instead of amending existing commits.
+```text
+but apply my-feature-branch
+```
-**Usage:** `but absorb [SOURCE] [OPTIONS]`
+**Usage:** `but apply `
## Arguments
-* `` — If the Source is an uncommitted change - the change will be absorbed. If the Source is a stack - anything staged to the stack will be absorbed accordingly. If not provided, everything that is uncommitted will be absorbed
-
-## Options
-
-* `--dry-run` — Show the absorption plan without making any changes
-* `-n`, `--new` — Create new commits, instead of amending existing ones. This is useful when you want to preserve existing commits and add new ones for the absorbed changes
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+* `` — Name of the branch to apply (required)
# but-config.mdx
-Without a subcommand, displays an overview of important settings including user information, target branch, forge configuration, and AI setup.
+Without a subcommand, displays an overview of important settings including
+user information, target branch, forge configuration, and AI setup.
-Examples
+## Examples
View configuration overview:
- but config
+```text
+but config
+```
View/set user configuration:
- but config user
- but config user set name "John Doe"
- but config user set email john@example.com
+```text
+but config user
+but config user set name "John Doe"
+but config user set email john@example.com
+```
View/set forge configuration:
- but config forge
+```text
+but config forge
+```
View/set target branch:
- but config target
+```text
+but config target
+```
View/set metrics:
- but config metrics
+```text
+but config metrics
+```
**Usage:** `but config `
@@ -3789,16 +3160,6 @@ Disable metrics:
* `` — Whether metrics are enabled
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
# but-commit.mdx
@@ -3878,33 +3239,22 @@ If a target is provided without --before or --after, defaults to --before behavi
* `--before` `` — Insert the blank commit before this commit or branch
* `--after` `` — Insert the blank commit after this commit or branch
-## Arguments
-
-* `` — Branch CLI ID or name to derive the stack to commit to
-
## Options
* `-m`, `--message` `` — Commit message
-* `-f`, `--file` `` — Read commit message from file
+* `--message-file` `` — Read commit message from file
* `-c`, `--create` — Whether to create a new branch for this commit. If the branch name given matches an existing branch, that branch will be used instead. If no branch name is given, a new branch with a generated name will be created
* `-o`, `--only` — Only commit staged files, not unstaged files
* `-n`, `--no-hooks` — Bypass pre-commit hooks
-* `-i`, `--ai` `` — Generate commit message using AI with optional user summary
-* `-F`, `--files` `` — Uncommitted file or hunk CLI IDs to include in the commit. Can be specified multiple times or as comma-separated values. If not specified, all uncommitted changes (or changes staged to the target branch) are committed
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-j`, `--json` — Whether to use JSON output format
+* `-i`, `--ai` `` — Generate commit message using AI with optional user summary. Use --ai by itself or --ai="your instructions" (equals sign required for value)
+* `-p`, `--changes` `` — Uncommitted file or hunk CLI IDs to include in the commit. Can be specified multiple times or as comma-separated values. If not specified, all uncommitted changes (or changes staged to the target branch) are committed
# but-diff.mdx
-Without any arguments, it shows the diff of all uncommitted changes. Optionally, a CLI ID argument can be provided, which chan show the diff specific to
-
+Without any arguments, it shows the diff of all uncommitted changes.
+Optionally, a CLI ID argument can be provided, which chan show the diff specific to
- an uncommitted file
- a branch
- an entire stack
@@ -3917,37 +3267,66 @@ Without any arguments, it shows the diff of all uncommitted changes. Optionally,
* `` — The CLI ID of the entity to show the diff for
-## Platform Options
-These options are available for all `but` commands:
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+# but-gui.mdx
+
+Running `but gui` will launch the GitButler graphical user interface
+in the current directory's GitButler project.
+
+This provides a visual way to manage branches, commits, and uncommitted
+changes, complementing the command-line interface.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+You can also just run `but .` as a shorthand to open the GUI.
+**Usage:** `but gui`
-# but-gui.mdx
-Running but gui will launch the GitButler graphical user interface in the current directory's GitButler project.
+# but-discard.mdx
-This provides a visual way to manage branches, commits, and uncommitted changes, complementing the command-line interface.
+This command permanently discards changes to files, restoring them to their
+state in the HEAD commit. Use this to undo unwanted modifications.
-You can also just run but . as a shorthand to open the GUI.
+The ID parameter should be a file ID as shown in `but status`. You can
+discard a whole file or specific hunks within a file.
-**Usage:** `but gui`
+## Examples
+
+Discard all changes to a file:
+
+```text
+but discard a1
+```
+
+**Usage:** `but discard `
+
+## Arguments
+
+* `` — The ID of the file or hunk to discard (as shown in but status) (required)
+
+
+
+# but-mark.mdx
+
+Creates or removes a rule for auto-staging or auto-committing changes
+to the specified target entity.
+
+If you mark a branch, new unstaged changes that GitButler sees when
+you run any command will be automatically staged to that branch.
-## Platform Options
+If you mark a commit, new uncommitted changes will automatically be
+amended into the marked commit.
-These options are available for all `but` commands:
+**Usage:** `but mark [OPTIONS]`
+
+## Arguments
+
+* `` — The target entity that will be marked (required)
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+## Options
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+* `-d`, `--delete` — Deletes a mark
@@ -3978,75 +3357,45 @@ but merge my-feature-branch
* `` — Branch ID or name to merge (required)
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-
-# but-mark.mdx
-
-Creates or removes a rule for auto-staging or auto-committing changes to the specified target entity.
-
-If you mark a branch, new unstaged changes that GitButler sees when you run any command will be automatically staged to that branch.
-If you mark a commit, new uncommitted changes will automatically be amended into the marked commit.
-**Usage:** `but mark [OPTIONS]`
-
-## Arguments
-
-* `` — The target entity that will be marked (required)
-
-## Options
-
-* `-d`, `--delete` — Deletes a mark
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+# but-move.mdx
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+By default, commits are moved to be before (below) the target.
+Use `--after` to move the commit after (above) the target instead.
+When moving to a branch, the commit is placed at the top of that branch's stack.
+## Examples
-# but-discard.mdx
+Move a commit before another commit:
-This command permanently discards changes to files, restoring them to their state in the HEAD commit. Use this to undo unwanted modifications.
+```text
+but move abc123 def456
+```
-The ID parameter should be a file ID as shown in but status. You can discard a whole file or specific hunks within a file.
+Move a commit after another commit:
-Examples
+```text
+but move abc123 def456 --after
+```
-Discard all changes to a file:
+Move a commit to a different branch (places at top):
- but discard a1
+```text
+but move abc123 my-feature-branch
+```
-**Usage:** `but discard `
+**Usage:** `but move [OPTIONS]`
## Arguments
-* `` — The ID of the file or hunk to discard (as shown in but status) (required)
-
-## Platform Options
-
-These options are available for all `but` commands:
+* `` — Commit ID to move (required)
+* `` — Target commit ID or branch name (required)
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+## Options
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+* `-a`, `--after` — Move the commit after (above) the target instead of before (below)
@@ -4119,58 +3468,49 @@ which you can find by running `but oplog` or `but oplog list`.
* `-f`, `--force` — Skip confirmation prompt
-## Platform Options
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+# but-pick.mdx
+This command allows you to pick individual commits from unapplied branches
+and apply them to your current workspace branches.
-# but-move.mdx
+The source can be:
+- A commit SHA (full or short)
+- A CLI ID (e.g., "c5" from `but status`)
+- An unapplied branch name (shows interactive commit selection)
-By default, commits are moved to be before (below) the target. Use --after to move the commit after (above) the target instead.
+If no target branch is specified:
+- In interactive mode: prompts you to select a target branch
+- If only one branch exists: automatically uses that branch
+- In non-interactive mode: fails with an error
-When moving to a branch, the commit is placed at the top of that branch's stack.
+## Examples
-Examples
+Pick a specific commit into a branch:
-Move a commit before another commit:
+```text
+but pick abc1234 my-feature
+```
- but move abc123 def456
+Pick using a CLI ID:
-Move a commit after another commit:
+```text
+but pick c5 my-feature
+```
- but move abc123 def456 --after
+Interactively select commits from an unapplied branch:
-Move a commit to a different branch (places at top):
-
- but move abc123 my-feature-branch
+```text
+but pick feature-branch
+```
-**Usage:** `but move [OPTIONS]`
+**Usage:** `but pick [TARGET_BRANCH]`
## Arguments
-* `` — Commit ID to move (required)
-* `` — Target commit ID or branch name (required)
-
-## Options
-
-* `-a`, `--after` — Move the commit after (above) the target instead of before (below)
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+* `` — The commit SHA, CLI ID, or unapplied branch name to cherry-pick from (required)
+* `` — The target virtual branch to apply the commit(s) to
@@ -4191,85 +3531,61 @@ merged into the target branch before running the update.
* `-c`, `--check` — Only check the status without updating (equivalent to the old but base check)
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-# but-pick.mdx
-This command allows you to pick individual commits from unapplied branches
-and apply them to your current workspace branches.
+# but-pr.mdx
-The source can be:
-- A commit SHA (full or short)
-- A CLI ID (e.g., "c5" from `but status`)
-- An unapplied branch name (shows interactive commit selection)
+If you are authenticated with a forge using but config forge auth, you can use the but pr commands to create pull requests (or merge requests) on the remote repository for your branches.
-If no target branch is specified:
-- In interactive mode: prompts you to select a target branch
-- If only one branch exists: automatically uses that branch
-- In non-interactive mode: fails with an error
+Running but pr without a subcommand defaults to but pr new, which will prompt you to select a branch to create a PR for.
-## Examples
+**Usage:** `but pr `
-Pick a specific commit into a branch:
+## Subcommands
-```text
-but pick abc1234 my-feature
-```
+### `but pr new`
-Pick using a CLI ID:
+Create a new pull request for a branch. If no branch is specified, you will be prompted to select one. If there is only one branch without a PR, you will be asked to confirm
-```text
-but pick c5 my-feature
-```
+**Usage:** `but pr new [BRANCH] [OPTIONS]`
-Interactively select commits from an unapplied branch:
+**Arguments:**
-```text
-but pick feature-branch
-```
+* `` — The branch to create a PR for
-**Usage:** `but pick [TARGET_BRANCH]`
+**Options:**
-## Arguments
+* `-m`, `--message` `` — PR title and description. The first line is the title, the rest is the description
+* `-F`, `--file` `` — Read PR title and description from file. The first line is the title, the rest is the description
+* `-f`, `--with-force` — Force push even if it's not fast-forward (defaults to true) (default: `true`)
+* `-s`, `--skip-force-push-protection` — Skip force push protection checks
+* `-r`, `--run-hooks` — Run pre-push hooks (defaults to true) (default: `true`)
+* `-t`, `--default` — Use the default content for the PR title and description, skipping any prompts. If the branch contains only a single commit, the commit message will be used (default: `false`)
-* `` — The commit SHA, CLI ID, or unapplied branch name to cherry-pick from (required)
-* `` — The target virtual branch to apply the commit(s) to
+### `but pr template`
-## Platform Options
+Configure the template to use for PR descriptions. This will list all available templates found in the repository and allow you to select one
-These options are available for all `but` commands:
+**Usage:** `but pr template [TEMPLATE_PATH]`
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+**Arguments:**
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+* `` — Path to the PR template file within the repository
# but-push.mdx
-but push will update the remote with the latest commits from the applied branch(es).
+`but push` will update the remote with the latest commits from the
+applied branch(es).
Without a branch ID:
-
- Interactive mode: Lists all branches with unpushed commits and prompts for selection
- Non-interactive mode: Automatically pushes all branches with unpushed commits
With a branch ID:
-
-- but push bu - push the branch with CLI ID "bu"
-- but push feature-branch - push the branch named "feature-branch"
+- `but push bu` - push the branch with CLI ID "bu"
+- `but push feature-branch` - push the branch named "feature-branch"
**Usage:** `but push [BRANCH_ID] [OPTIONS]`
@@ -4284,70 +3600,6 @@ With a branch ID:
* `-r`, `--run-hooks` — Run pre-push hooks (default: `true`)
* `-d`, `--dry-run` — Show what would be pushed without actually pushing
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-
-# but-resolve.mdx
-
-When a commit is in a conflicted state (marked with conflicts during rebase),
-use this command to enter resolution mode, resolve the conflicts, and finalize.
-
-## Workflow
-
-1. Enter resolution mode: `but resolve `
-2. Resolve conflicts in your editor (remove conflict markers)
-3. Check remaining conflicts: `but resolve status`
-4. Finalize resolution: `but resolve finish`
- Or cancel: `but resolve cancel`
-
-When in resolution mode, `but status` will also show that you're resolving conflicts.
-
-**Usage:** `but resolve [COMMIT]`
-
-## Subcommands
-
-### `but resolve status`
-
-Show the status of conflict resolution, listing remaining conflicted files
-
-**Usage:** `but resolve status`
-
-### `but resolve finish`
-
-Finalize conflict resolution and return to workspace mode.
-
-This commits the resolved changes, rebases any commits on top of the resolved commit, and returns to the normal workspace.
-
-**Usage:** `but resolve finish`
-
-### `but resolve cancel`
-
-Cancel conflict resolution and return to workspace mode.
-
-This discards all changes made during resolution and restores the workspace to its pre-resolution state.
-
-**Usage:** `but resolve cancel`
-
-## Arguments
-
-* `` — Commit ID to enter resolution mode for (when no subcommand is provided)
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
# but-reword.mdx
@@ -4372,43 +3624,57 @@ You can also use `but reword ` to rename the branch.
* `-m`, `--message` `` — The new commit message or branch name. If not provided, opens an editor
* `-f`, `--format` — Format the existing commit message to 72-char line wrapping without opening an editor
-## Platform Options
-
-These options are available for all `but` commands:
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-j`, `--json` — Whether to use JSON output format
+# but-rub.mdx
+The `rub` command is a simple verb that helps you do a number of editing
+operations by doing combinations of two things.
-# but-rub.mdx
+For example, you can "rub" a file onto a branch to stage that file to
+the branch. You can also "rub" a commit onto another commit to squash
+them together. You can rub a commit onto a branch to move that commit.
+You can rub a file from one commit to another.
-The rub command is a simple verb that helps you do a number of editing operations by doing combinations of two things.
+## Operations Matrix
-For example, you can "rub" a file onto a branch to stage that file to the branch. You can also "rub" a commit onto another commit to squash them together. You can rub a commit onto a branch to move that commit. You can rub a file from one commit to another.
+Each cell shows what happens when you rub SOURCE → TARGET:
-Non-exhaustive list of operations:
+```text
+SOURCE ↓ / TARGET → │ zz (unassigned) │ Commit │ Branch │ Stack
+─────────────────────┼─────────────────┼────────────┼─────────────┼────────────
+File/Hunk │ Unstage │ Amend │ Stage │ Stage
+Commit │ Undo │ Squash │ Move │ -
+Branch (all changes) │ Unstage all │ Amend all │ Reassign │ Reassign
+Stack (all changes) │ Unstage all │ - │ Reassign │ Reassign
+Unassigned (zz) │ - │ Amend all │ Stage all │ Stage all
+File-in-Commit │ Uncommit │ Move │ Uncommit to │ -
+```
- │Source │Target
- ──────┼───────────┼──────
- Amend │File,Branch│Commit
- Squash│Commit │Commit
- Stage │File,Branch│Branch
- Move │Commit │Branch
+Legend:
+- `zz` is a special target meaning "unassigned" (no branch)
+- `-` means the operation is not supported
+- "all changes" / "all" refers to all uncommitted changes from that source
-Examples
+## Examples
Squashing two commits into one (combining the commit messages):
- but rub 3868155 abe3f53f
+```text
+but rub 3868155 abe3f53f
+```
Amending a commit with the contents of a modified file:
- but rub README.md abe3f53f
+```text
+but rub README.md abe3f53f
+```
Moving a commit from one branch to another:
- but rub 3868155 feature-branch
+```text
+but rub 3868155 feature-branch
+```
**Usage:** `but rub `
@@ -4417,80 +3683,70 @@ Moving a commit from one branch to another:
* `` — The source entity to combine (required)
* `` — The target entity to combine with the source (required)
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+# but-resolve.mdx
+When a commit is in a conflicted state (marked with conflicts during rebase),
+use this command to enter resolution mode, resolve the conflicts, and finalize.
-# but-show.mdx
-
-When given a commit ID, displays the full commit message, author information, committer information (if different from author), and the list of files modified.
-
-When given a branch name, displays the branch name and a list of all commits on that branch. Use --verbose to show full commit messages and files changed.
-
-Examples
-
-Show commit details by short commit ID:
-
- but show a1b2c3d
+## Workflow
-Show commit details by CLI ID:
+1. Enter resolution mode: `but resolve `
+2. Resolve conflicts in your editor (remove conflict markers)
+3. Check remaining conflicts: `but resolve status`
+4. Finalize resolution: `but resolve finish`
+ Or cancel: `but resolve cancel`
- but show c5
+When in resolution mode, `but status` will also show that you're resolving conflicts.
-Show branch commits by branch name:
+**Usage:** `but resolve [COMMIT]`
- but show my-feature-branch
+## Subcommands
-Show branch with full commit details:
+### `but resolve status`
- but show my-feature-branch --verbose
+Show the status of conflict resolution, listing remaining conflicted files
-**Usage:** `but show [OPTIONS]`
+**Usage:** `but resolve status`
-## Arguments
+### `but resolve finish`
-* `` — The commit ID (short or full SHA), branch name, or CLI ID to show details for (required)
+Finalize conflict resolution and return to workspace mode.
-## Options
+This commits the resolved changes, rebases any commits on top of the resolved commit, and returns to the normal workspace.
-* `-v`, `--verbose` — Show full commit messages and files changed for each commit
+**Usage:** `but resolve finish`
-## Platform Options
+### `but resolve cancel`
-These options are available for all `but` commands:
+Cancel conflict resolution and return to workspace mode.
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+This discards all changes made during resolution and restores the workspace to its pre-resolution state.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+**Usage:** `but resolve cancel`
# but-setup.mdx
This command will:
-
- Add the repository to the global GitButler project registry
- Switch to the gitbutler/workspace branch (if not already on it)
- Set up a default target branch (the remote's HEAD)
- Add a gb-local remote if no push remote exists
-If you have an existing Git repository and want to start using GitButler with it, you can run this command to set up the necessary configuration and data structures.
+If you have an existing Git repository and want to start using GitButler
+with it, you can run this command to set up the necessary configuration
+and data structures.
-Examples
+## Examples
Initialize a new git repository and set up GitButler:
- but setup --init
+```text
+but setup --init
+```
**Usage:** `but setup [OPTIONS]`
@@ -4498,24 +3754,15 @@ Initialize a new git repository and set up GitButler:
* `--init` — Initialize a new git repository with an empty commit if one doesn't exist.
-This is useful when running in non-interactive environments (like CI/CD) where you want to ensure a git repository exists before setting up GitButler.
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+This is useful when running in non-interactive environments (like CI/CD)
+where you want to ensure a git repository exists before setting up GitButler.
# but-skill.mdx
-Skills provide enhanced AI capabilities for working with GitButler through
-Claude Code and other AI assistants.
+Skills give coding agents instructions for working with GitButler through the
+`but` CLI.
Use `but skill install` to install the GitButler skill files into your
repository or globally.
@@ -4540,30 +3787,40 @@ but skill install --global
### `but skill install`
-Install the GitButler CLI skill files for Coding agents
+Install the GitButler CLI skill files for coding agents.
-By default, installs the skill into the current repository. The command will prompt you to select a skill folder format (Claude Code, OpenCode, Codex, GitHub Copilot, Cursor, Windsurf) unless you specify a custom path with --path.
+By default, installs the skill into the current repository. The command prompts
+you to select a skill folder format: Claude Code, OpenCode, Codex, GitHub
+Copilot, Cursor, or Windsurf.
-Use --global to install the skill in a global location instead of the current repository.
+Use `--path` to choose a custom location. Use `--global` to install the skill
+in a global location instead of the current repository.
-Examples
+## Examples
Install in current repository (prompts for format):
- but skill install
+```text
+but skill install
+```
Install globally (prompts for format):
- but skill install --global
+```text
+but skill install --global
+```
Install to a custom path:
- but skill install --path .claude/skills/gitbutler
+```text
+but skill install --path .claude/skills/gitbutler
+```
Auto-detect installation location (update existing installation):
- but skill install --detect
-
+```text
+but skill install --detect
+```
**Usage:** `but skill install [OPTIONS]`
@@ -4575,24 +3832,30 @@ Auto-detect installation location (update existing installation):
### `but skill check`
-Check if installed GitButler skills are up to date with the CLI version
+Check if installed GitButler skills are up to date with the CLI version.
-Scans for installed skill files and compares their version with the current CLI version. By default, checks both local (repository) and global installations.
+Scans for installed skill files and compares their version with the current
+CLI version. By default, checks both local (repository) and global installations.
-Examples
+## Examples
Check all installed skills:
- but skill check
+```text
+but skill check
+```
Check and automatically update outdated skills:
- but skill check --update
+```text
+but skill check --update
+```
Check only global installations:
- but skill check --global
-
+```text
+but skill check --global
+```
**Usage:** `but skill check [OPTIONS]`
@@ -4602,194 +3865,215 @@ Check only global installations:
* `-l`, `--local` — Only check local installations (in current repository)
* `-u`, `--update` — Automatically update any outdated skills found
-## Platform Options
-These options are available for all `but` commands:
+# but-show.mdx
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+When given a commit ID, displays the full commit message, author information,
+committer information (if different from author), and the list of files modified.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+When given a branch name, displays the branch name and a list of all commits
+on that branch. Use --verbose to show full commit messages and files changed.
+## Examples
+Show commit details by short commit ID:
-# but-squash.mdx
+```text
+but show a1b2c3d
+```
-Can be invoked in three ways:
-1. Using commit identifiers: `but squash ` or `but squash ...`
- - Squashes all commits except the last into the last commit
-2. Using a commit range: `but squash ..`
- - Squashes all commits in the range into the last commit in the range
-3. Using a branch name: `but squash `
- - Squashes all commits in the branch into the bottom-most commit
+Show commit details by CLI ID:
-**Usage:** `but squash [COMMITS] [OPTIONS]`
+```text
+but show c5
+```
-## Arguments
+Show branch commits by branch name:
-* `` — Commit identifiers, a range (commit1..commit2), or a branch name
+```text
+but show my-feature-branch
+```
-## Options
+Show branch with full commit details:
-* `-d`, `--drop-message` — Drop source commit messages and keep only the target commit's message
-* `-m`, `--message` `` — Provide a new commit message for the resulting commit
-* `-i`, `--ai` `` — Generate commit message using AI with optional user summary or instructions
+```text
+but show my-feature-branch --verbose
+```
-## Platform Options
+**Usage:** `but show [OPTIONS]`
-These options are available for all `but` commands:
+## Arguments
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+* `` — The commit ID (short or full SHA), branch name, or CLI ID to show details for (required)
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+## Options
+* `-v`, `--verbose` — Show full commit messages and files changed for each commit
-# but-pr.mdx
-If you are authenticated with a forge using but config forge auth, you can use the but pr commands to create pull requests (or merge requests) on the remote repository for your branches.
+# but-stage.mdx
-Running but pr without a subcommand defaults to but pr new, which will prompt you to select a branch to create a PR for.
+Wrapper for `but rub `.
-**Usage:** `but pr `
+**Usage:** `but stage `
-## Subcommands
+## Arguments
-### `but pr new`
+* `` — File or hunk ID to stage (required)
+* `` — Branch ID to stage to (required)
-Create a new pull request for a branch. If no branch is specified, you will be prompted to select one. If there is only one branch without a PR, you will be asked to confirm
-**Usage:** `but pr new [BRANCH] [OPTIONS]`
-**Arguments:**
+# but-squash.mdx
-* `` — The branch to create a PR for
+Can be invoked in three ways:
+1. Using commit identifiers: `but squash ` or `but squash ...`
+ - Squashes all commits except the last into the last commit
+2. Using a commit range: `but squash ..`
+ - Squashes all commits in the range into the last commit in the range
+3. Using a branch name: `but squash `
+ - Squashes all commits in the branch into the bottom-most commit
-**Options:**
+**Usage:** `but squash [COMMITS] [OPTIONS]`
-* `-m`, `--message` `` — PR title and description. The first line is the title, the rest is the description
-* `-F`, `--file` `` — Read PR title and description from file. The first line is the title, the rest is the description
-* `-f`, `--with-force` — Force push even if it's not fast-forward (defaults to true) (default: `true`)
-* `-s`, `--skip-force-push-protection` — Skip force push protection checks
-* `-r`, `--run-hooks` — Run pre-push hooks (defaults to true) (default: `true`)
-* `-t`, `--default` — Use the default content for the PR title and description, skipping any prompts. If the branch contains only a single commit, the commit message will be used (default: `false`)
+## Arguments
-### `but pr template`
+* `` — Commit identifiers, a range (commit1..commit2), or a branch name
-Configure the template to use for PR descriptions. This will list all available templates found in the repository and allow you to select one
+## Options
-**Usage:** `but pr template [TEMPLATE_PATH]`
+* `-d`, `--drop-message` — Drop source commit messages and keep only the target commit's message
+* `-m`, `--message` `` — Provide a new commit message for the resulting commit
+* `-i`, `--ai` `` — Generate commit message using AI with optional user summary or instructions. Use --ai by itself or --ai="your instructions" (equals sign required for value)
-**Arguments:**
-* `` — Path to the PR template file within the repository
-## Platform Options
+# but-status.mdx
-These options are available for all `but` commands:
+This shows unstaged files, files staged to stacks, all applied
+branches (stacked or parallel), commits on each of those branches,
+upstream commits that are unintegrated, commit status (pushed or local),
+and base branch information.
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+## Examples
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+Normal usage:
+```text
+but status
+```
+Shorthand with listing files modified
-# but-stage.mdx
+```text
+but status -f
+```
-Wrapper for `but rub `.
+**Usage:** `but status [OPTIONS]`
-**Usage:** `but stage `
+## Options
-## Arguments
+* `-f` — Determines whether the committed files should be shown as well (default: `false`)
+* `-v`, `--verbose` — Show verbose output with commit author and timestamp (default: `false`)
+* `-r`, `--refresh-prs` — Forces a sync of pull requests from the forge before showing status (default: `false`)
+* `-u`, `--upstream` — Show detailed list of upstream commits that haven't been integrated yet (default: `false`)
+* `--no-hint` — Disable hints about available commands at the end of output (default: `false`)
-* `` — File or hunk ID to stage (required)
-* `` — Branch ID to stage to (required)
-## Platform Options
-These options are available for all `but` commands:
+# but-teardown.mdx
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+This command:
+- Creates an oplog snapshot of the current state
+- Finds the first active branch and checks it out
+- Cherry-picks any dangling commits from gitbutler/workspace
+- Provides instructions on how to return to GitButler mode
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+This is useful when you want to temporarily or permanently leave GitButler
+management and work with standard Git commands.
+## Examples
+Exit GitButler mode:
-# but-undo.mdx
+```text
+but teardown
+```
-This is a shorthand for restoring to the last oplog entry before the current one. It allows you to quickly undo the most recent operation.
+**Usage:** `but teardown`
-**Usage:** `but undo`
-## Platform Options
-These options are available for all `but` commands:
+# but-unapply.mdx
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+If you want to unapply an applied branch from your workspace
+(effectively stashing it) so you can work on other branches,
+you can run `but unapply `.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+This will remove the changes in that branch from your working
+directory and you can re-apply it later when needed. You will then
+see the branch as unapplied in `but branch list`.
+The identifier can be:
+- A CLI ID pointing to a stack or branch (e.g., "bu" from `but status`)
+- A branch name
+If a branch name (or an identifier pointing to a branch) is provided,
+the entire stack containing that branch will be unapplied.
-# but-uncommit.mdx
+## Examples
-Wrapper for `but rub zz`.
+Unapply by branch name:
-**Usage:** `but uncommit `
+```text
+but unapply my-feature-branch
+```
+
+Unapply by CLI ID:
+
+```text
+but unapply bu
+```
+
+**Usage:** `but unapply [OPTIONS]`
## Arguments
-* `` — Commit ID or file-in-commit ID to uncommit (required)
+* `` — CLI ID or name of the branch/stack to unapply (required)
-## Platform Options
+## Options
-These options are available for all `but` commands:
+* `-f`, `--force` — Force unapply without confirmation
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+# but-uncommit.mdx
+Wrapper for `but rub zz`.
-# but-teardown.mdx
+**Usage:** `but uncommit `
-This command:
+## Arguments
-- Creates an oplog snapshot of the current state
-- Finds the first active branch and checks it out
-- Cherry-picks any dangling commits from gitbutler/workspace
-- Provides instructions on how to return to GitButler mode
+* `` — Commit ID or file-in-commit ID to uncommit (required)
-This is useful when you want to temporarily or permanently leave GitButler management and work with standard Git commands.
-Examples
-Exit GitButler mode:
+# but-undo.mdx
- but teardown
+This is a shorthand for restoring to the last oplog entry before the
+current one. It allows you to quickly undo the most recent operation.
-**Usage:** `but teardown`
+**Usage:** `but undo`
-## Platform Options
-These options are available for all `but` commands:
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
+# but-unmark.mdx
+
+This will unmark anything that has been marked by the `but mark` command.
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
+**Usage:** `but unmark`
@@ -4837,49 +4121,6 @@ Note: Currently only supported on macOS. For other platforms, download from http
Examples: but update install Auto-detect channel and install latest but update install nightly Install latest nightly build but update install release Install latest stable release but update install 0.18.7 Install specific version
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-
-# but-status.mdx
-
-This shows unstaged files, files staged to stacks, all applied branches (stacked or parallel), commits on each of those branches, upstream commits that are unintegrated, commit status (pushed or local), and base branch information.
-
-Examples
-
-Normal usage:
-
- but status
-
-Shorthand with listing files modified
-
- but status -f
-
-**Usage:** `but status [OPTIONS]`
-
-## Options
-
-* `-f` — Determines whether the committed files should be shown as well (default: `false`)
-* `-v`, `--verbose` — Show verbose output with commit author and timestamp (default: `false`)
-* `-r`, `--refresh-prs` — Forces a sync of pull requests from the forge before showing status (default: `false`)
-* `-u`, `--upstream` — Show detailed list of upstream commits that haven't been integrated yet (default: `false`)
-* `--no-hint` — Disable hints about available commands at the end of output (default: `false`)
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-j`, `--json` — Whether to use JSON output format
-
# commands-overview.mdx
@@ -4934,24 +4175,6 @@ These options are available for all `but` commands:
- [undo](./but-undo): Undo the last operation by reverting to the previous snapshot
-# but-unmark.mdx
-
-This will unmark anything that has been marked by the but mark command.
-
-**Usage:** `but unmark`
-
-## Platform Options
-
-These options are available for all `but` commands:
-
-* `-C`, `--current-dir` `` — Run as if gitbutler-cli was started in PATH instead of the current working directory (default: `.`)
-* `-f`, `--format` `` — Explicitly control how output should be formatted.
-
-If unset and from a terminal, it defaults to human output, when redirected it's for shells. (default: `human`)
-* `-j`, `--json` — Whether to use JSON output format
-
-
-
# installation.mdx
How to install and setup the GitButler CLI.
@@ -4989,6 +4212,68 @@ If you run almost any `but` command in an existing Git repository in an interact
At any time after this, you can run `but teardown` to undo the GitButler changes and go back to being a boring old Git project. It will not remove GitButler metadata, so feel free to go back and forth if you need to.
+# ai-stuff.mdx
+
+Use `--ai` when you want the CLI to generate text for a single command. Use
+`but skill install` when you want a coding agent to use GitButler's
+version-control workflow.
+
+## `--ai` options
+
+Supported commands can take `--ai` to generate text from your current changes.
+
+### `but commit --ai`
+
+Use `but commit --ai` to generate a commit message from the changes you are
+committing.
+
+This commits the selected work with the generated message. You can edit the
+message afterward with `but reword `.
+
+### `but squash --ai`
+
+Use `but squash --ai` to generate a combined commit message when squashing
+commits.
+
+
+
+More commands will gain `--ai` support over time.
+
+
+
+## `but skill install`
+
+If your coding agent can read skills, install the GitButler skill with
+`but skill install`.
+
+```git
+❯ but skill install
+
+Select a skill folder format:
+
+? Which format would you like to use?:
+> Claude Code - Claude Code CLI skill format (./.claude/skills/gitbutler)
+ OpenCode - OpenCode AI skill format (./.opencode/skills/gitbutler)
+ Codex - Codex skill format (./.codex/skills/gitbutler)
+ GitHub Copilot - GitHub Copilot local (repo) skill format (./.github/skills/gitbutler)
+ GitHub Copilot - GitHub Copilot global skill format (./.copilot/skills/gitbutler)
+```
+
+We keep these templates up to date, so if you update GitButler, you may want to
+update the skill too.
+
+## Agent workflow docs
+
+`but skill install` is only the install step. For the full workflow:
+
+- Start with [AI agents overview](/ai-agents/overview).
+- Install and configure the skill with
+ [Getting started with AI agents](/ai-agents/getting-started).
+- Use [Useful requests](/ai-agents/useful-requests) for prompt examples.
+- Use [Tuning agent behavior](/ai-agents/tuning-agent-behavior) for standing
+ instructions.
+
+
# branching-and-commiting.mdx
Now that your project is setup and GitButler is installed and configured, you can start branching and committing.
@@ -5046,7 +4331,7 @@ To do this, you can use the `but branch new ` command.
{/* run git branch -D user-bookmarks */}
-```cli [branching-and-commiting-but-branch-1, 110px]
+```cli [branching-and-commiting-but-branch-1, 88px]
but branch new user-bookmarks
```
@@ -5060,7 +4345,7 @@ but status
Now we can commit our unassigned changes to that branch. You can simply assign your changes to the branch first to commit later (we'll cover that later in [Rubbing](./rubbing)), but for now let's keep it simple and just commit them directly using the `but commit` command.
-```cli [branching-and-commiting-but-commit-1, 110px]
+```cli [branching-and-commiting-but-commit-1, 88px]
but commit -m 'all the user bookmarks'
```
@@ -5097,7 +4382,7 @@ To create a parallel branch, you simply create a new branch the same way we did
{/* run echo 'test' > app/controllers/likes_controller.rb */}
{/* run echo 'test' > app/models/like.rb */}
-```cli [branching-and-commiting-but-branch-2, 110px]
+```cli [branching-and-commiting-but-branch-2, 88px]
but branch new liked-tweets
```
@@ -5109,7 +4394,7 @@ but status
We can see our previous branch and the commit we made, our new empty branch and a couple of modified files. Now we can commit the unassigned changes to that branch with `but commit -m "liked tweets changes" liked-tweets`
-```cli [branching-and-commiting-but-commit-2, 110px]
+```cli [branching-and-commiting-but-commit-2, 88px]
but commit -m "liked tweets changes" liked-tweets
```
@@ -5138,7 +4423,7 @@ To create a new stacked branch in GitButler, you can run `but branch new` with a
{/* run git branch -D liked-tweets-stacked */}
{/* restore [e32713a1f41c] */}
-```cli [branching-and-commiting-but-branch-3, 110px]
+```cli [branching-and-commiting-but-branch-3, 88px]
but branch new -a user-bookmarks liked-tweets-stacked
```
@@ -5148,7 +4433,7 @@ but status
Now we can commit to our stacked branch.
-```cli [branching-and-commiting-but-commit-3, 110px]
+```cli [branching-and-commiting-but-commit-3, 88px]
but commit -m "liked tweets changes" liked-tweets-stacked
```
@@ -5209,7 +4494,7 @@ Now, if we want to create a commit in the `user-bookmarks` branch, we can either
Or, we can make a commit with _only_ the assigned files in `user-bookmarks` by using the `-o` option to `but commit`.
-```cli [branching-and-commiting-but-commit-4, 110px]
+```cli [branching-and-commiting-but-commit-4, 88px]
but commit -o -m "liked tweets view" bo
```
@@ -5221,7 +4506,7 @@ but st
Now let's commit all the rest of the changes (assigned and unassigned) to our other branch:
-```cli [branching-and-commiting-but-commit-5, 110px]
+```cli [branching-and-commiting-but-commit-5, 88px]
but commit -m 'bookmarks stuff' ch
```
@@ -5231,26 +4516,26 @@ but status
### Committing Specific Files or Hunks
-Instead of staging files first and then committing with `-o`, you can also directly specify which files or hunks to include in a commit using the `-F` or `--files` option. This lets you commit only specific changes without having to assign them to a branch first.
+Instead of staging files first and then committing with `-o`, you can also directly specify which files or hunks to include in a commit using the `-p` or `--changes` option. This lets you commit only specific changes without having to assign them to a branch first.
For example, if you have multiple unassigned files and only want to commit some of them:
```bash
-but commit -F h0,i0 -m "only these two files" user-bookmarks
+but commit -p h0,i0 -m "only these two files" user-bookmarks
```
You can specify files in several ways:
- **By CLI ID**: Use the short identifier shown in `but status` (e.g., `h0`, `i0`)
-- **Space-separated**: `--files h0 i0 k0`
-- **Comma-separated**: `-F h0,i0,k0`
-- **By path**: `-F app/models/bookmark.rb`
+- **Space-separated**: `--changes h0 i0 k0`
+- **Comma-separated**: `-p h0,i0,k0`
+- **By path**: `-p app/models/bookmark.rb`
This also works with hunk IDs. When a file has multiple hunks (shown in `but status -f` or `but diff`), you can commit individual hunks rather than the entire file. This is useful when you have changes in the same file that belong to different logical commits.
-If you don't specify `-F`, all uncommitted changes (or changes staged to the target branch) are committed. Use `-F` when you need fine-grained control over what goes into a commit.
+If you don't specify `-p`, all uncommitted changes (or changes staged to the target branch) are committed. Use `-p` when you need fine-grained control over what goes into a commit.
@@ -5276,13 +4561,22 @@ but status
```
+# conclusion.mdx
+
+Ok, that's a short guide to GitButler's command line interface.
+
+Join us in [Discord](https://discord.com/invite/MmFkmaJ42D) if you have any other questions or suggestions for how we can improve the tool.
+
+Thanks!
+
+
# configuration.mdx
We've already covered `but config` a bit in dealing with forges and target branches.
You can also use it for some basic user configuration, such as setting your name and email address for commits and your default editor.
-```cli [configuration-but-config-1, 308px]
+```cli [configuration-but-config-1, 286px]
but config user
```
@@ -5290,7 +4584,7 @@ but config user
GitButler also has a built in aliasing system in case you want to provide some shorthands.
-```cli [configuration-but-alias-1, 308px]
+```cli [configuration-but-alias-1, 286px]
but alias
```
@@ -5299,23 +4593,6 @@ To add a new alias, you can run `but alias add `, which you c
You will notice that there is a `default` alias, which is what runs when you just run `but` with no arguments. If you overwrite the `default` alias, you can set up something other than `status` to run by default.
-# ai-stuff.mdx
-
-## Dash Dash AI
-
-`but squash --ai`
-
-`but commit --ai`
-
-## Skills
-
-`but skill install`
-
-## Hooks and MCP
-
-You can also install explicit hooks or an MCP server if you prefer.
-
-
# conflict-resolution.mdx
In this world nothing can be said to be certain, except death, taxes and merge conflicts.
@@ -5338,13 +4615,13 @@ So, let's take a look at what this looks like and how we can deal with conflicte
{/* restore [e53a4a85d83d] */}
{/* run git push -f origin 96ccca9:main */}
-```cli [conflict-resolution-but-status-1, 308px]
+```cli [conflict-resolution-but-status-1, 396px]
but status
```
Let's say that this is our status and we've decided to pull in from upstream. The changes that have been merged in by someone else upstream conflict with ours. When we run `but pull`, it will result in conflicts in our branch (but it will succeed).
-```cli [conflict-resolution-but-pull-1, 308px]
+```cli [conflict-resolution-but-pull-1, 286px]
but pull
```
@@ -5458,340 +4735,331 @@ Run but status to see all conflicted commits, or but resolve to resolve
```
-# inspecting.mdx
-
-When you're working with projects, sometimes you'll need to inspect things to see what the differences are or summarize work.
+# editing-commits.mdx
-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.
+While you can rub changes in and out of commits, you can also edit the commit
+message of any commit in your workspace quite easily.
-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.
+## Editing Commit Messages
-Let's look at a simple scenario.
+You can edit commit messages with the `but describe` command. So if we have this status:
-{/* restore [bd526ee8c76c] */}
-{/* run but stage h0 us */}
-{/* run git push -f origin 32a2175758f7f649ed7a030a17fd21213a5e400f:refs/heads/main */}
+{/* restore [d69fffa7c6eb] */}
-```cli [inspecting-but-status-1, 396px]
-but status --files
+```cli [editing-commits-but-status-1, 330px]
+but status
```
-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
+Then you can edit the message of any commit by running `but reword `, which will open up your editor of choice with the existing commit message and when you exit the editor, replace that message in the commit and rebase everything above it.
-For most of this, you could use `git diff`. For example, to see everything that is uncommitted, you can just run `git diff`.
+The editor would look something like this:
-```cli [inspecting-git-1, 836px]
-git diff HEAD
```
+add user changes
-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:
-
-```cli [inspecting-but-diff-1, 814px]
-but diff
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+#
+# Changes in this commit:
+# modified: app/models/user.rb
+# modified: config/routes.rb
+#
+~
+~
+~
+~
```
-You can see that this is the same information, but a bit more easily understandable.
+Pretty simple.
-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.
+## Changing Branch Names
-## Listing Branches
+Just like changing commit messages, you can also use `but reword` to change the name of a branch. So, in the above example, if we wanted to change the branch name from `user-bookmarks` to `feature-awesome-thing`, we can do this:
-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.
+```cli [editing-commits-but-reword-1, 88px]
+but reword -m feature-awesome-thing us
+```
-Here is what `git branch` might output (this example repo has over 100 branches, so let's just truncate it):
+Et voila.
-```cli [inspecting-git-2, 286px]
-git branch | head -10
+```cli [editing-commits-but-status-2, 330px]
+but status
```
-
+{/* TODO: Edit Mode */}
-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.
-
+# forges.mdx
-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:
+We've touched on how to update your local branches with `but pull`, but what about when you want to take your awesome new branches of work and put them on a server to get them integrated or collaborate with other people?
+
+The two main commands to get work out are `but push` and `but pr`. Let's start with `but push` as it's a little simpler.
+
+## Pushing
+
+The very simple example would be to simply run `but push `.
-```cli [inspecting-but-branch-1, 660px]
-but branch
```
+❯ but push update-homepage
-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.
+✓ Push completed successfully
-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.
+ update-homepage -> origin/update-homepage ((new branch) -> 1d31833)
+```
-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?
+You can also run `but push` by itself. If there is only one applied branch, it will push that one. If there are several applied branches, you can choose which to push or select 'all' to push all of them.
-There is also a "✓" or "✗" that indicates if this branch is cleanly mergeable with your target branch.
+You can also supply `-d` or `--dry-run` to see what _would_ be pushed up.
-It also shows the last author of a commit on that branch and orders everything by how long ago the last commit was.
+## Pull Requests
-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.
+That's the simple way to push branches to your default remote and update already pushed ones.
-## Filtering your Branches
+The other common thing to do is to open Pull Requests on GitHub. GitButler's CLI has a built in command for opening and updating PRs, called `but pr`.
-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:
+Much like `but push`, if there is only one branch, it will open a PR for that, otherwise it will ask you which branch to open one for. Or you can be explicit with something like `but pr `.
-```cli [inspecting-but-branch-2, 242px]
-but branch list book
```
+❯ but pr
+Do you want to open a new PR on branch 'sc-switch-wording-to-x'? [Y/n]: y
+→ Pushing sc-switch-wording-to-x...
+ ✓ Pushed to origin
+→ Creating PR for sc-switch-wording-to-x → main...
-## Looking at a Branches
+✓ Created PR #69
+ Title: Switch Wording to X
+ Branch: sc-switch-wording-to-x
+ URL: https://github.com/schacon/why/pull/69
+```
-If you want to see what is on a branch, you can inspect a specific branch by running `but branch show `. This will show the commits on this branch ahead of your target.
+Once it's opened, you'll get a URL you can view the pull request on.
-Essentially, it runs the equivalent of `git log origin/main..` with some more introspection.
+## Forge Authentication
-```cli [inspecting-git-3, 308px]
-git log origin/main..feature-awesome-thing
+In order to open a PR on GitHub, you'll need to authenticate to that forge. You can see which authentications you have by running `but config`:
+
+```cli [forges-but-config-1, 572px]
+but config
```
-Now let's look at `but branch show`
+If you have not authenticated to a forge yet, you can run `but config forge auth`, which will ask you which type of authentication you would like to do:
-```cli [inspecting-but-branch-3, 286px]
-but branch show feature-awesome-thing
+```
+❯ but config forge auth
+? Select an authentication method:
+> Device flow (OAuth)
+ Personal Access Token (PAT)
+ GitHub Enterprise
```
-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.
+Selecting one of the options will allow you to provide an authentication token for GitButler to use for opening and modifying PRs.
-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.
+
+ Currently, GitButler only authenticates to GitHub servers, but support for Merge Requests on
+ GitLab and other forges is coming.
+
-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:
+# initializing-a-repository.mdx
-```cli [inspecting-but-branch-4, 704px]
-but branch show sc-branch-28 --ai -r -f
-```
+If you run any `but` command in a repository that has never been seen by GitButler before, it will automatically ask you if you want to setup the repository for GitButler.
-## Showing a Commit
+It will guess most things needed, but everything can be changed later if it got anything wrong. The most important thing is to figure out the target branch - the main branch that you'll want to merge things into and you consider 'production' or 'golden'. Normally this is something like `origin/main`, but GitButler should be pretty good at guessing.
-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.
+You can also run `but setup` manually to set everything up explicitly:
-```cli [inspecting-but-show-1, 286px]
-but show a42580b96ed7b432
+```ansi but-setup-5faf7f36
+but setup
```
-## 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`).
+As the command says, it does a few things to prepare your repository for being managed by GitButler.
+Unlike a tool like [Jujutsu](https://docs.jj-vcs.dev/latest/git-compatibility/) or [Sapling](https://sapling-scm.com/docs/git/git_support_modes/), GitButler mainly operates on normal Git repositories, so nearly all Git commands will work with anything produced or managed by GitButler. You can think of it more like a new porcelain than a different system.
-# editing-commits.mdx
+However, one thing we need to do in order to enable having parallel applied branches is create a "megamerge" commit that automatically merges in the heads of all your applied branches, so that other tools `git status` will correctly show you what you expect.
-While you can rub changes in and out of commits, you can also edit the commit
-message of any commit in your workspace quite easily.
+This means that we do two things:
-## Editing Commit Messages
+- We create a new branch called `gitbutler/workspace` pointing to a constantly rewritten and ephemeral merge commit and check this branch out so HEAD is pointing to it (again, for `git status` reasons in tools like VSCode or whatever)
+- We add custom `pre-commit` and `post-checkout` hooks (moving and continuing to call any existing hooks) to try to prevent you from accidentally committing on top of our managed mega-merge commit.
-You can edit commit messages with the `but describe` command. So if we have this status:
+
-{/* restore [d69fffa7c6eb] */}
+The mega-merge workspace commit will soon only be needed once you actually have more than one branch applied, so at some point we won't automatically do it on setup, but we're working on it.
-```cli [editing-commits-but-status-1, 330px]
-but status
-```
+
-Then you can edit the message of any commit by running `but reword `, which will open up your editor of choice with the existing commit message and when you exit the editor, replace that message in the commit and rebase everything above it.
+Both of these things can be quickly and easily undone by running `but teardown`, doing any Git committing stuff you need to do and then re-running `but setup` to go back to GitButler tooling.
-The editor would look something like this:
+You can also simply checkout a git branch with `git checkout ` and the `post-checkout` hook we installed should clean up after itself.
-```
-add user changes
-# Please enter the commit message for your changes. Lines starting
-# with '#' will be ignored, and an empty message aborts the commit.
-#
-# Changes in this commit:
-# modified: app/models/user.rb
-# modified: config/routes.rb
-#
-~
-~
-~
-~
-```
+# inspecting.mdx
-Pretty simple.
+When you're working with projects, sometimes you'll need to inspect things to see what the differences are or summarize work.
-## Changing Branch Names
+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.
-Just like changing commit messages, you can also use `but reword` to change the name of a branch. So, in the above example, if we wanted to change the branch name from `user-bookmarks` to `feature-awesome-thing`, we can do this:
+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.
-```cli [editing-commits-but-reword-1, 110px]
-but reword -m feature-awesome-thing us
-```
+Let's look at a simple scenario.
-Et voila.
+{/* restore [bd526ee8c76c] */}
+{/* run but stage h0 us */}
+{/* run git push -f origin 32a2175758f7f649ed7a030a17fd21213a5e400f:refs/heads/main */}
-```cli [editing-commits-but-status-2, 330px]
-but status
+```cli [inspecting-but-status-1, 396px]
+but status --files
```
-{/* TODO: Edit Mode */}
-
+Here we have an unstaged file (`Gemfile`), a file staged to the `user-bookmarks` branch (`README.md`), and two commits on our branch.
-# operations-log.mdx
+## Diffing things
-GitButler maintains a detailed log of all operations, making it easy to track what happened and undo changes when needed.
+For most of this, you could use `git diff`. For example, to see everything that is uncommitted, you can just run `git diff`.
-## Viewing the Operations Log
+```cli [inspecting-git-1, 836px]
+git diff HEAD
+```
-See all recent GitButler operations:
+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:
-```cli [operations-log-but-oplog-1, 550px]
-but oplog
+```cli [inspecting-but-diff-1, 814px]
+but diff
```
-## Undoing the last operation
+You can see that this is the same information, but a bit more easily understandable.
-Undo the last operation:
+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.
-```cli [operations-log-but-undo-1, 154px]
-but undo
-```
+## Listing Branches
-## Restoring to a previous point
+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.
-You can easily restore to any point in the operations history by running the `but oplog restore` command. If it will modify your working directory (maybe it's just changes to the commit history or staging stuff), then it will prompt you if you want to continue. If you don't want that, you can pass `-f` or `--force` to make it do it anyhow.
+Here is what `git branch` might output (this example repo has over 100 branches, so let's just truncate it):
-```cli [operations-log-but-oplog-2, 154px]
-but oplog restore -f 6fdd8fb1d547
+```cli [inspecting-git-2, 286px]
+git branch | head -10
```
-Restorations create a new oplog entry before running, so you can always easily undo it in the same manner.
-
-It can be a bit confusing as to what state it restores to. It will restore to what your project looked like _before_ the operation was run. So for example, if there is a `CreateCommit` operation and you restore to that SHA, it will put your state back to the moment before the commit happened.
+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.
-## Creating Snapshots
-
-You can also manually create snapshots of moments that you want to be able to revert to at any point, without some other operation needing to automatically save it.
+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:
-```cli [operations-log-but-oplog-3, 154px]
-but oplog snapshot
+```cli [inspecting-but-branch-1, 638px]
+but branch
```
-Now you can copy that SHA and restore to that exact point at any time in the future.
+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?
-# conclusion.mdx
+There is also a "✓" or "✗" that indicates if this branch is cleanly mergeable with your target branch.
-Ok, that's a short guide to GitButler's command line interface.
+It also shows the last author of a commit on that branch and orders everything by how long ago the last commit was.
-Join us in [Discord](https://discord.com/invite/MmFkmaJ42D) if you have any other questions or suggestions for how we can improve the tool.
+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.
-Thanks!
+## 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:
-# initializing-a-repository.mdx
+```cli [inspecting-but-branch-2, 220px]
+but branch list book
+```
-If you run any `but` command in a repository that has never been seen by GitButler before, it will automatically ask you if you want to setup the repository for GitButler.
+## Looking at a Branches
-It will guess most things needed, but everything can be changed later if it got anything wrong. The most important thing is to figure out the target branch - the main branch that you'll want to merge things into and you consider 'production' or 'golden'. Normally this is something like `origin/main`, but GitButler should be pretty good at guessing.
+If you want to see what is on a branch, you can inspect a specific branch by running `but branch show `. This will show the commits on this branch ahead of your target.
-You can also run `but setup` manually to set everything up explicitly:
+Essentially, it runs the equivalent of `git log origin/main..` with some more introspection.
-```ansi but-setup-5faf7f36
-but setup
+```cli [inspecting-git-3, 308px]
+git log origin/main..feature-awesome-thing
```
-As the command says, it does a few things to prepare your repository for being managed by GitButler.
-
-Unlike a tool like [Jujutsu](https://docs.jj-vcs.dev/latest/git-compatibility/) or [Sapling](https://sapling-scm.com/docs/git/git_support_modes/), GitButler mainly operates on normal Git repositories, so nearly all Git commands will work with anything produced or managed by GitButler. You can think of it more like a new porcelain than a different system.
+Now let's look at `but branch show`
-However, one thing we need to do in order to enable having parallel applied branches is create a "megamerge" commit that automatically merges in the heads of all your applied branches, so that other tools `git status` will correctly show you what you expect.
+```cli [inspecting-but-branch-3, 264px]
+but branch show feature-awesome-thing
+```
-This means that we do two things:
+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.
-- We create a new branch called `gitbutler/workspace` pointing to a constantly rewritten and ephemeral merge commit and check this branch out so HEAD is pointing to it (again, for `git status` reasons in tools like VSCode or whatever)
-- We add custom `pre-commit` and `post-checkout` hooks (moving and continuing to call any existing hooks) to try to prevent you from accidentally committing on top of our managed mega-merge commit.
+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.
-The mega-merge workspace commit will soon only be needed once you actually have more than one branch applied, so at some point we won't automatically do it on setup, but we're working on it.
+Let's run all of them at the same time:
-
+```cli [inspecting-but-branch-4, 682px]
+but branch show sc-branch-28 --ai -r -f
+```
-Both of these things can be quickly and easily undone by running `but teardown`, doing any Git committing stuff you need to do and then re-running `but setup` to go back to GitButler tooling.
+## Showing a Commit
-You can also simply checkout a git branch with `git checkout ` and the `post-checkout` hook we installed should clean up after itself.
+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.
+```cli [inspecting-but-show-1, 264px]
+but show a42580b96ed7b432
+```
-# forges.mdx
+## Deleting Branches
-We've touched on how to update your local branches with `but pull`, but what about when you want to take your awesome new branches of work and put them on a server to get them integrated or collaborate with other people?
+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`).
-The two main commands to get work out are `but push` and `but pr`. Let's start with `but push` as it's a little simpler.
-## Pushing
+# operations-log.mdx
-The very simple example would be to simply run `but push `.
+GitButler maintains a detailed log of all operations, making it easy to track what happened and undo changes when needed.
-```
-❯ but push update-homepage
+## Viewing the Operations Log
-✓ Push completed successfully
+See all recent GitButler operations:
- update-homepage -> origin/update-homepage ((new branch) -> 1d31833)
+```cli [operations-log-but-oplog-1, 550px]
+but oplog
```
-You can also run `but push` by itself. If there is only one applied branch, it will push that one. If there are several applied branches, you can choose which to push or select 'all' to push all of them.
-
-You can also supply `-d` or `--dry-run` to see what _would_ be pushed up.
+## Undoing the last operation
-## Pull Requests
+Undo the last operation:
-That's the simple way to push branches to your default remote and update already pushed ones.
+```cli [operations-log-but-undo-1, 132px]
+but undo
+```
-The other common thing to do is to open Pull Requests on GitHub. GitButler's CLI has a built in command for opening and updating PRs, called `but pr`.
+## Restoring to a previous point
-Much like `but push`, if there is only one branch, it will open a PR for that, otherwise it will ask you which branch to open one for. Or you can be explicit with something like `but pr `.
+You can easily restore to any point in the operations history by running the `but oplog restore` command. If it will modify your working directory (maybe it's just changes to the commit history or staging stuff), then it will prompt you if you want to continue. If you don't want that, you can pass `-f` or `--force` to make it do it anyhow.
+```cli [operations-log-but-oplog-2, 154px]
+but oplog restore -f 6fdd8fb1d547
```
-❯ but pr
-Do you want to open a new PR on branch 'sc-switch-wording-to-x'? [Y/n]: y
-→ Pushing sc-switch-wording-to-x...
- ✓ Pushed to origin
-→ Creating PR for sc-switch-wording-to-x → main...
-✓ Created PR #69
- Title: Switch Wording to X
- Branch: sc-switch-wording-to-x
- URL: https://github.com/schacon/why/pull/69
-```
+Restorations create a new oplog entry before running, so you can always easily undo it in the same manner.
-Once it's opened, you'll get a URL you can view the pull request on.
+
-## Forge Authentication
+It can be a bit confusing as to what state it restores to. It will restore to what your project looked like _before_ the operation was run. So for example, if there is a `CreateCommit` operation and you restore to that SHA, it will put your state back to the moment before the commit happened.
-In order to open a PR on GitHub, you'll need to authenticate to that forge. You can see which authentications you have by running `but config`:
+
-```cli [forges-but-config-1, 484px]
-but config
-```
+## Creating Snapshots
-If you have not authenticated to a forge yet, you can run `but config forge auth`, which will ask you which type of authentication you would like to do:
+You can also manually create snapshots of moments that you want to be able to revert to at any point, without some other operation needing to automatically save it.
+```cli [operations-log-but-oplog-3, 154px]
+but oplog snapshot
```
-❯ but config forge auth
-? Select an authentication method:
-> Device flow (OAuth)
- Personal Access Token (PAT)
- GitHub Enterprise
-```
-
-Selecting one of the options will allow you to provide an authentication token for GitButler to use for opening and modifying PRs.
-
- Currently, GitButler only authenticates to GitHub servers, but support for Merge Requests on
- GitLab and other forges is coming.
-
+Now you can copy that SHA and restore to that exact point at any time in the future.
# rubbing.mdx
@@ -5835,11 +5103,11 @@ but status
If we want to update the first commit (`da42d06`) with the `README-es.md` changes and the last commit (`fdbd753`) with the `app/views/bookmarks/index.html.erb` changes, we can run the following two `rub` commands:
-```cli [rubbing-but-rub-1, 110px]
+```cli [rubbing-but-rub-1, 88px]
but rub h0 da42d06
```
-```cli [rubbing-but-rub-2, 110px]
+```cli [rubbing-but-rub-2, 88px]
but rub app/views/bookmarks/index.html.erb fdbd753
```
@@ -5865,7 +5133,7 @@ but status
We can absorb the top commit into the bottom one by running `but rub `:
-```cli [rubbing-but-rub-3, 110px]
+```cli [rubbing-but-rub-3, 88px]
but rub 0f 08
```
@@ -5891,7 +5159,7 @@ but status
And we want to un-commit the first commit (`0fa2965`) as though we had never made it, you can rub to `zz`:
-```cli [rubbing-but-rub-4, 110px]
+```cli [rubbing-but-rub-4, 88px]
but rub 0f zz
```
@@ -5915,7 +5183,7 @@ but status
We can move the “second commit” commit to the `move-second-commit` branch with `but rub`:
-```cli [rubbing-but-rub-5, 110px]
+```cli [rubbing-but-rub-5, 88px]
but rub 0f mo
```
@@ -5979,7 +5247,7 @@ but commit empty --after 6a
Now we have a blank commit:
-```cli [rubbing-but-status-13, 440px]
+```cli [rubbing-but-status-13, 462px]
but status -f
```
@@ -5988,7 +5256,21 @@ Now we can use the previous method of moving file changes from other commits int
# scripting.mdx
-JSON!
+### JSON Errwhere
+
+All of the commands are designed to be very user friendly when we have an interactive terminal, but you can also very easily script everything by passing the `--json` or `-j` option to anything. For example, here is using `but show` on a commit.
+
+```cli [scripting-but-show-1, 308px]
+but show 2672465
+```
+
+Now with the `--json` option:
+
+```cli [scripting-but-show-2, 682px]
+but show --json 2672465 | jq
+```
+
+You can do this with anything - committing, status, diffing, etc. Just throw a `-j` in there and you get parseable data (or, data your agent can very easily work with).
# tutorial-overview.mdx
@@ -6024,13 +5306,13 @@ When GitButler is first initialized in a project, you are asked to choose a bran
You can always check your target branch setting with `but config`:
-```cli [updating-the-base-but-config-1, 484px]
+```cli [updating-the-base-but-config-1, 572px]
but config
```
Or get more information with `but config target`:
-```cli [updating-the-base-but-config-2, 330px]
+```cli [updating-the-base-but-config-2, 308px]
but config target
```
@@ -6079,7 +5361,7 @@ Technically, there could be more reachable commits, but we only show the first p
Now let's say that we would like to pull in the upstream work and rebase our branches on top of the new upstream to update them. We can check what all would happen with `but pull --check`.
-```cli [updating-the-base-but-pull-1, 330px]
+```cli [updating-the-base-but-pull-1, 308px]
but pull --check
```
@@ -6101,7 +5383,7 @@ When you feel like you want to get your active branches up to date, you can run
Let's run it in our example.
-```cli [updating-the-base-but-pull-2, 418px]
+```cli [updating-the-base-but-pull-2, 396px]
but pull
```
@@ -6110,3 +5392,555 @@ but status
```
OK, now we can see that our integrated branch was removed, our `gemfile-fixes` branch was successfully rebased and our `sc-branch-26` work is marked as conflicted. We'll see how to deal with that state in a minute.
+
+
+# getting-started.mdx
+
+This page is for coding agents that can read local instruction files and run
+commands in your repository. The GitButler skill does not give the agent new
+permissions. It tells the agent how to use `but` instead of driving Git through
+checkout, stash, add, commit, and rebase commands.
+
+## Install the `but` CLI
+
+If you already have GitButler Desktop installed, you can install the CLI from
+the Desktop Client settings. For terminal-only setup, run:
+
+```sh
+curl -fsSL https://gitbutler.com/install.sh | sh
+```
+
+See [Installation and setup](/cli-guides/installation) for the full CLI install
+options.
+
+## Install the GitButler skill
+
+Run the installer from the same repository:
+
+```sh
+but skill install
+```
+
+The installer prompts for scope first: current repository or global home
+directory. It then prompts for the skill format. Current formats include Agent
+Skills (`.agents/skills`), Claude Code, OpenCode, Codex, GitHub Copilot, Cursor,
+and Windsurf.
+
+For custom paths, global installs, non-interactive updates, and skill checks,
+see [`but skill`](/commands/but-skill).
+
+## Set up the repository
+
+GitButler currently needs the repository in workspace mode for its multi-branch
+model: multiple GitButler branches in one working directory.
+
+From the repository where the agent will work, run:
+
+```sh
+but setup
+```
+
+You can also skip this step and let the agent run `but setup` when it first
+needs GitButler. For the full list of setup changes, see
+[`but setup`](/commands/but-setup).
+
+GitButler is working toward a plain Git mode that switches into a workspace only
+when multiple concurrent branches are needed. Follow
+[gitbutlerapp/gitbutler#11866](https://github.com/gitbutlerapp/gitbutler/issues/11866)
+for that work.
+
+## Add optional agent instructions
+
+The GitButler skill tells the agent how to use `but`. Your own instructions
+tell the agent what behavior you want.
+
+Put project defaults in a repository instruction file such as `AGENTS.md` or
+`CLAUDE.md`. Put personal defaults in a global instruction file such as
+`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, Cursor rules, Copilot custom
+instructions, or the equivalent for your tool.
+
+These files steer agent behavior; they are not access controls. Use your usual
+repository permissions and branch protection for hard limits.
+
+Use this baseline to keep agent work isolated:
+
+```md
+## Version control
+
+- Use GitButler (`but`) for version-control write operations, including
+ branching, committing, pushing, and history edits.
+- Assume multiple agents may be working in this repository. Do not move, amend,
+ squash, discard, commit, push, or otherwise modify another agent's work unless
+ the user asks.
+- Use a dedicated GitButler branch for each agent session, unless the user asks
+ for a different branch structure. Commit only changes that belong to that
+ session.
+- Do not push or open pull requests unless the user asks.
+- Keep commit messages and pull request descriptions succinct: explain what
+ changed, why it changed, and any important decision.
+```
+
+You can also tune the agent to:
+
+- amend local fixes into existing commits;
+- create checkpoint commits and tidy them before review;
+- create stacked pull requests for dependent work;
+- follow your branch and commit naming conventions;
+- publish, update from main, or create recovery points only when your policy
+ allows it.
+
+For copyable snippets, see
+[Tuning agent behavior](/ai-agents/tuning-agent-behavior).
+
+For prompt examples that ask for specific branch and commit outcomes, see
+[Useful requests](/ai-agents/useful-requests).
+
+
+# parallel-agents.mdx
+
+Parallel agents do not require separate worktrees or pre-created branches. Once
+agents use GitButler for version-control writes, you can start another coding
+session in the same repository and prompt it like any other task:
+
+```text
+Work on checkout validation.
+```
+
+When either session is ready, ask it to commit:
+
+```text
+Commit your changes.
+```
+
+The agent uses GitButler to commit the changes for its task to its GitButler
+branch. The branch routing is the agent's job; your prompt can stay small.
+
+If two sessions touch the same file or generated output, have the agents call
+out the overlap before committing.
+
+You can also ask an agent to split independent work out of the current session.
+For example, if a feature session also finds a small bug fix, the agent can
+move the relevant changes or commits to a new branch and prepare a separate PR
+instead of stacking the fix on the feature.
+
+For more background on the branch model, see
+[Parallel branches](/features/branch-management/virtual-branches).
+
+The baseline `Version control` instructions from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions)
+are useful if you want to steer commit behavior, but they are not a separate
+parallel-agent setup step.
+
+## How this differs from worktrees
+
+Git has one checked-out branch per worktree. If you want two agents to work on
+two branches at the same time, the usual Git answer is multiple worktrees.
+
+GitButler gives you a different option: multiple active branches in one
+worktree, with each agent's commits organized onto the branch for its session.
+
+| | Multiple worktrees | GitButler parallel branches |
+| --- | --- | --- |
+| Workspace | One directory per agent | One shared working directory |
+| Branches | One checked-out branch per worktree | Multiple active branches in one worktree |
+| Isolation | Separate checkout | Shared filesystem and runtime state |
+| Setup cost | Usually more directories, dependency installs, build outputs, and dev servers | Reuse one install and dev server when tasks can share runtime state |
+| Version-control shape | Branches stay separate because work happens in separate directories | GitButler can commit the right subset of changes to each branch |
+| Best fit | Competing attempts, incompatible checkout states, isolated runtimes | Unrelated features or fixes that can share one workspace |
+
+Use multiple worktrees when agents need incompatible checkout states, separate
+runtime state, or competing attempts at the same task. Use GitButler parallel
+branches when the tasks are independent enough to share one workspace and you
+want less local overhead.
+
+## Handle dependencies explicitly
+
+Parallel agents work best when sessions start independent. If one session
+starts depending on another, make that relationship explicit by stacking the
+branches:
+
+```text
+The notification settings work now depends on checkout validation. Stack your
+branch on top of the checkout validation branch.
+```
+
+If an unrelated fix shows up inside a feature session, tell the agent to extract
+it instead:
+
+```text
+The cache invalidation fix is independent. Move it to a separate GitButler
+branch and prepare a separate PR for it.
+```
+
+If the feature depends on the fix, put the fix on the lower branch and stack the
+feature above it instead. For stacked PR policy, see
+[Create stacked pull requests](/ai-agents/tuning-agent-behavior#create-stacked-pull-requests).
+
+## Know what is shared
+
+Parallel GitButler branches are not runtime isolation. The agents share one
+filesystem, dependency install, generated files, and app state. That can surface
+overlap and broken builds earlier, but it can also hide accidental
+dependencies.
+
+Before shipping a branch independently, check whether it depends on another
+active branch. If two agents start editing the same files or generated output,
+decide whether to keep the work parallel, stack one branch on the other, or use
+separate worktrees.
+
+For more request examples, see [Useful requests](/ai-agents/useful-requests).
+
+
+# review-agent-work.mdx
+
+
+When your coding agent uses GitButler, it can do the version-control work for
+you: create branches, commit changes, move work between commits, and reshape
+local history. The agent usually does this through the GitButler CLI.
+
+You may still want to preview what it created or manually adjust the branch and
+commit history before anything is pushed or turned into a PR. GitButler gives
+you three ways to inspect and adjust that state: the TUI, the CLI, and the
+Desktop Client GUI. Use this page to pick the surface you want. The detailed
+CLI and Desktop workflows live in their own docs.
+
+## GitButler TUI
+
+Use the TUI when you want a terminal view of the workspace without switching to
+the Desktop Client. It is useful for checking branch state, looking at what is
+on a branch or still unassigned, and making small manual adjustments to branch
+assignment, commit membership, or history shape.
+
+```sh
+but tui
+```
+
+
+
+## GitButler CLI
+
+Use the CLI when you want exact output, scriptable commands, or the same view of
+the repository state that the agent uses.
+
+For command details, start with the [CLI overview](/cli-overview).
+
+## GitButler Desktop Client
+
+Use the Desktop Client when you want a visual overview of branches, commits,
+assigned changes, unassigned changes, parallel work, and stacked work. It is
+also the visual surface for moving changes between branches and adjusting
+commit history.
+
+```sh
+but gui
+```
+
+For details, see the [Desktop Overview](/overview),
+[Branch lanes](/features/branch-management/branch-lanes), and
+[Commits](/features/branch-management/commits).
+
+## Operations history
+
+GitButler records version-control operations so you can inspect or undo local
+history edits. If a branch reorganization does not look right, inspect the
+operation history before making more changes. See
+[Timeline](/features/timeline), [`but oplog`](/commands/but-oplog), and
+[`but undo`](/commands/but-undo).
+
+
+# tuning-agent-behavior.mdx
+
+Add these optional bullets under the same `## Version control` section as the
+baseline from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions).
+Use this page as a menu: copy only the policies you want for the repository and
+agent you are using.
+
+## Amend local fixes into the right commits
+
+Use this when you want the agent to fold follow-up fixes into unpublished local
+commits when the new change clearly belongs with that commit's intent. With
+GitButler, the agent can move the relevant change into the commit where it
+belongs.
+
+```md
+- For small cleanup or follow-up fixes, amend an unpublished local commit when
+ the change clearly belongs with that commit's intent.
+- Do not create tiny fixup commits unless I ask.
+- Use GitButler to move the relevant changes into the commit where they belong.
+- Ask before rewriting pushed, reviewed, shared, or ambiguous history.
+```
+
+You do not need to tell the agent which command to use. The GitButler skill
+gives it the relevant operations. For background, see
+[`but absorb`](/commands/but-absorb) and [`but amend`](/commands/but-amend).
+
+## Commit checkpoints after each completed turn
+
+Use this when you want local savepoints while the agent works. The checkpoints
+do not need to be the final review history. Before review, you can ask the
+agent to tidy unpublished local history.
+
+```md
+- Commit after a working checkpoint, when the requested change is complete and
+ relevant checks have passed or been reported.
+- Treat checkpoint commits as local savepoints, not final review history.
+- When I ask you to tidy the history, use GitButler to squash commits, reword
+ commits, and move changes between commits where appropriate.
+- Only tidy unpublished local history unless I explicitly authorize changing
+ pushed or shared history.
+```
+
+## Create stacked pull requests
+
+Use this when you want dependent work reviewed as stacked pull requests. This is
+useful when one agent session depends on another session's branch, or when an
+agent is working on a branch that sits at the bottom of a stack.
+
+```md
+- If this session depends on another in-flight branch, stack its branch on top
+ of that dependency instead of mixing the changes.
+- If this session is working in a stack, put commits on the branch where they
+ belong.
+- Ask before moving commits onto lower, pushed, reviewed, or shared branches.
+- Use `but move` for branch stacking and restacking. Do not recreate branches
+ to simulate stacking.
+- For stacked branches, create pull requests with `but pr`, not `gh`, so
+ GitButler keeps the right PR base branches and stack metadata.
+```
+
+For background, see [Stacked branches](/features/branch-management/stacked-branches),
+[`but move`](/commands/but-move), and [`but pr`](/commands/but-pr).
+
+## Customize branch names
+
+Use this when your team has a naming convention for branches the agent creates.
+This is only an example; replace the prefix and shape with your convention.
+
+```md
+- When creating a GitButler branch for an agent session, use
+ `feature/-` when a ticket ID is available.
+```
+
+## Customize commit messages
+
+Use this when your team has a commit-message convention. This is only an
+example; replace it with your preferred style.
+
+```md
+- Use Conventional Commits, such as `feat: add branch naming policy` or
+ `fix: handle empty branch names`.
+```
+
+## Publish when you say "ship it"
+
+Use this when you want a short phrase to authorize the agent to finish the
+version-control work for its session. This commits, pushes, and creates or
+updates a pull request, so use it only when the agent is allowed to publish.
+
+```md
+- When I say "ship it", commit this session's changes on its dedicated
+ GitButler branch, creating one if needed.
+- Push the branch and open or update its pull request with GitButler.
+- Reuse the existing branch or pull request for this session when one already
+ exists.
+```
+
+For background, see [`but push`](/commands/but-push) and
+[`but pr`](/commands/but-pr).
+
+## Update from main automatically
+
+Use this when your project moves quickly and you want the agent to keep its
+workspace current with the target branch, usually `main` or `master`. The
+GitButler command for this is `but pull`, which fetches the target branch and
+rebases applied branches onto the new target commit. This is a preference: in
+some repositories, you may want the agent to ask before updating.
+
+Add the last bullet only if you want the agent to handle update conflicts.
+
+```md
+- When GitButler status shows new changes on the target branch, run
+ `but pull --check`.
+- If the check is clean and the update affects only this session's branches,
+ update the workspace with `but pull`.
+- If the check reports conflicts or the update would affect another agent's
+ branch, ask before updating.
+- If I ask you to handle update conflicts, use GitButler's conflict tools. Ask
+ before resolving semantic conflicts, dependency updates, generated files, or
+ conflicts involving another person's work.
+```
+
+You do not need to tell the agent which command to use. For background, see
+[`but pull`](/commands/but-pull) and [`but resolve`](/commands/but-resolve).
+
+## Open draft pull requests by default
+
+Use this when the agent is allowed to publish work, but you still want review to
+start in draft. Creating a draft pull request still publishes the branch.
+
+```md
+- When I ask you to open a pull request, create it as a draft with GitButler
+ unless I say it is ready for review.
+```
+
+## Create a recovery point before large history edits
+
+Use this when you want the agent to be more cautious before reorganizing several
+commits or branches.
+
+```md
+- Before squashing, splitting, moving commits between branches, or reorganizing
+ multiple branches, run `but oplog snapshot -m ""`.
+- Use GitButler history-edit commands such as `but move`, `but squash`,
+ `but reword`, `but absorb`, and `but amend` instead of raw Git rebases.
+- If an operation makes the branch or history layout worse, stop and inspect the
+ operation log before attempting another fix.
+- Prefer `but undo` or `but oplog restore` over trying to repair a bad state
+ with more history edits.
+```
+
+For command details, see [`but oplog`](/commands/but-oplog) and
+[`but undo`](/commands/but-undo).
+
+## Split unrelated hunks
+
+Use this when agents tend to commit whole files even when one file contains
+separate changes.
+
+```md
+- If one file contains unrelated changes, split them by hunk instead of
+ committing the whole file.
+- Keep tests with the behavior they verify.
+- Split generated output, docs-only edits, or mechanical cleanup into separate
+ commits when each commit remains coherent on its own.
+- If the split is ambiguous, summarize the options before committing.
+```
+
+
+# useful-requests.mdx
+
+Once the GitButler skill is installed and your baseline version-control
+instructions are in place, ask for the branch, commit, or pull request outcome
+you want. You do not need to know the `but` commands or CLI IDs; the agent uses
+those to build the structure you describe.
+
+Use these examples as one-off requests you can mix with normal coding prompts.
+They are intentionally short; add whatever constraints matter in your repo. For
+standing rules that always apply, see
+[Tuning agent behavior](/ai-agents/tuning-agent-behavior).
+
+## Commit changes
+
+With the baseline instructions from
+[Getting started](/ai-agents/getting-started#add-optional-agent-instructions),
+the agent commits on the dedicated GitButler branch for its session. It commits
+that session's changes there, not unrelated user or agent work.
+
+You can tell your agent:
+
+```text
+Commit your changes.
+```
+
+Relevant command: [`but commit`](/commands/but-commit).
+
+## Clean up history
+
+GitButler gives the agent direct tools for moving commits, squashing commits,
+rewording commits, and moving changes between commits. Describe the end result
+you want instead of writing out an interactive rebase plan.
+
+Keep history cleanup to unpublished local work unless you explicitly authorize
+rewriting pushed or shared branches.
+
+```text
+Clean up the history. Squash WIP commits, split unrelated work, and reword
+messages based on intent. Show me the plan before changing history or pushing.
+```
+
+Relevant commands: [`but move`](/commands/but-move),
+[`but squash`](/commands/but-squash), [`but reword`](/commands/but-reword),
+and [`but rub`](/commands/but-rub).
+
+## Split a large commit into smaller commits
+
+Use this when a commit is too large to review as one unit. Say how you want the
+work grouped; the agent can create the intermediate commits and move the right
+changes into them.
+
+This prompt is an example; replace the grouping rules with whatever matters for
+your project.
+
+```text
+Split this into smaller commits by concern. Keep tests with the behavior they
+verify.
+```
+
+## Put uncommitted fixes into existing commits
+
+Use this after review feedback, test fixes, or a small follow-up edit that
+belongs with an earlier local commit.
+
+```text
+Amend your follow-up fixes into the appropriate local commits.
+```
+
+Relevant commands: [`but absorb`](/commands/but-absorb) and
+[`but amend`](/commands/but-amend).
+
+## Take changes out of a commit
+
+Use this when something was committed by mistake, or when one commit contains a
+change that belongs somewhere else.
+
+```text
+Take the debug logging out of the commit and leave it uncommitted.
+```
+
+```text
+Move the docs changes out of the feature commit and into a separate docs commit.
+```
+
+Relevant commands: [`but uncommit`](/commands/but-uncommit) and
+[`but rub`](/commands/but-rub).
+
+## Create stacked pull requests
+
+Stacked pull requests help when one change depends on another, but reviewers can
+still review the lower branch first. Creating draft PRs still pushes branches,
+so use this only when the agent is allowed to publish.
+
+```text
+Make the API work the base branch and stack the UI work on top. Create draft
+PRs.
+```
+
+The agent can also stack or restack existing branches when the dependency
+structure changes. If branches have already been pushed or reviewed, ask the
+agent to show which PRs will change before restacking. If something in a stack
+turns out to be independent, ask the agent to move it out into a separate
+branch.
+
+For more background, see
+[Stacked branches](/features/branch-management/stacked-branches),
+[`but move`](/commands/but-move), and [`but pr`](/commands/but-pr).
+
+## Work in parallel
+
+Use parallel branches when the work does not depend on another branch.
+GitButler lets multiple branches be active in the same workspace, so different
+agents can work on their own branches without creating and managing separate
+worktrees.
+
+This works best when the tasks do not depend on each other and are not editing
+the same files.
+
+Stack branches only when one branch depends on another. For the fuller
+multi-agent workflow, see [Parallel agents](/ai-agents/parallel-agents).