In 30 seconds
- What it is — a single-binary
bash wrapper for git. Short interactive commands replace long flag chains.
- Who it's for — developers who want clean conventional commits, smart pull/push/sync, and undo-everything safety without memorizing git plumbing.
- What's different — AI commit messages that can run fully local via Ollama (no key, no network), atomic split, WIP backup across machines, full worktree menu — all in one bash file.
gitb commit push # stage, write a conventional commit, push — in one flow
gitb commit ai # AI-generated commit message
gitb sync # fetch main + rebase your branch
gitb wip up # stash WIP, push backup branch, clean working tree
gitb undo # roll back your last commit / amend / merge / rebase / stash
Install
Pick one — all three install the same single gitb file.
Homebrew (macOS, Linux)
brew install maxbolgarin/tap/gitbasher
Install script — puts gitb in ~/.local/bin, no sudo. Downloads the latest release, verifies its SHA-256, and prints a PATH hint if needed.
curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash
npm — Node is only needed for the install; gitb itself is pure bash.
npm install -g gitbasher
System-wide installs, custom locations and pinned versions: More install options. How to upgrade each one: Updating.
Check what you have: gitb version prints the version, the path of the binary that ran, how it was installed, and the right update command. It also warns when two copies are installed and a different one wins on your PATH. gitb -v prints just the version line, for scripts.
Requirements: bash 3.2+ (the macOS system bash is fine) and git 2.23+. AI features also need jq. On Windows, use WSL.
Quick start
cd your-project
gitb # see all commands
gitb cfg user # set your name/email once
gitb cfg ai # (optional) set up AI for smart commits (provider, key, model)
gitb status # what's changed?
gitb commit # interactive conventional commit
gitb push # safe push with conflict handling
gitb pull # smart pull (rebase / merge / ff)
gitb branch new # create a new conventionally-named branch
Every command has a short alias (gitb c, gitb p, gitb pu, gitb b, gitb s, …) and inline help (gitb commit help).
Before & after
You just write what you want to do, and gitbasher will do it for you. All commands have a short alias, for example gitb c is equivalent to gitb commit.
| Task | Plain git | With gitb |
|---|
| Start a feature off updated main | git fetch && git checkout main && git pull --ff-only && git checkout -b feat/x | gitb branch newd |
| Conventional commit + push | git add -A && git commit -m "feat(x): …" && git push -u origin HEAD | gitb commit ai fast push |
| Sync your branch with main | git fetch && git rebase origin/main && git push --force-with-lease | gitb sync push |
| Save WIP & clean tree across machines | git stash -u && git push origin "HEAD:wip/$(git symbolic-ref --short HEAD)" | gitb wip up |
| Undo last commit (keep changes staged) | git reset --soft HEAD~1 | gitb undo |
| Tidy a messy branch into clean commits | (interactive rebase, fold by hand) | gitb squash |
Table of contents
Why gitbasher
- Zero memorization — no flags to remember, no man pages to grep. Interactive menus where it matters, short aliases where it doesn't.
- Conventional commits, free — type/scope/summary picker built-in, with optional ticket prefixes and a multiline editor mode.
- AI commit messages —
gitb c ai writes the message from your diff. OpenRouter (Gemini/Claude/GPT/…), OpenAI direct, or fully local via Ollama — no key, no network, no data leaves your machine.
- Safer git — push/pull detect conflicts up front,
undo rolls back commit/amend/merge/rebase/stash, reset is interactive with a preview.
- Whole workflows, not just commands —
sync, wip, branch newd, merge to-main, squash chain the steps you'd otherwise do by hand.
- One file, no deps — pure bash for every git operation; only the AI features need
jq and curl. Drop the binary anywhere on PATH and go. 1,000+ BATS tests run on Linux, macOS and bash 3.2 in CI.
All features at a glance
| Group | Commands | What you get |
|---|
| Commit | commit (c), edit (ed) | Interactive conventional commits, fast-mode, AI messages, atomic split, fixup, amend, revert; gitb edit reworks the last commit message, picks any commit to reword, or renames the current branch |
| Sync remote | push (p), pull (pu), fetch (fe), sync (sy) | Safe push (with force/list), smart pull (rebase / merge / ff), fetch-only with prune, one-shot rebase-on-main with optional force-push |
| Branches | branch (b), prev (-) | List / switch / create-from-current / create-from-updated-main / delete (orphaned, merged, gone) / recent / previous / checkout-tag |
| Integration | merge (m), rebase (r), squash (sq), cherry (ch) | Merge into current / into main / from remote · rebase onto main / interactive / autosquash / fastautosquash / pull-commits · AI-driven squash of branch commits into changelog-ready history · cherry-pick by hash, range, or interactive |
| Tags & releases | tag (t) | Lightweight, annotated, from-commit, push, push-all, delete, delete-all, list, fetch-remote |
| Save & rollback | wip (up/down), undo (un), reset (res), stash (st) | Save WIP via stash / branch / worktree (auto-detected on restore) · undo last commit/amend/merge/rebase/stash · interactive reset · full stash menu |
| Worktrees | worktree (wt) | Add / list / remove / move / lock / prune git worktrees, with new branch from current/main or from existing/remote branches |
| Inspect |
Total: 32 top-level commands, 60+ aliases, 100+ modes.
Common workflows
Daily development
gitb status
gitb pull
gitb branch new
# ... code ...
gitb commit ai fast push
Code-review cycle
gitb commit fix
gitb rebase autosquash
gitb push force
Sync with main mid-feature
gitb sync # fetch main + rebase your branch
gitb sync push # …and force-push
gitb sync merge # use merge instead of rebase
Save WIP across machines / branches
gitb wip up stash # stash changes + push backup to origin/wip/<branch>
# … on another machine: fetch the backup branch and restore it manually …
git fetch origin wip/<branch>
git merge --squash --no-commit origin/wip/<branch>
Hotfix
gitb b m # switch to main
gitb pu # latest changes
gitb b n # hotfix branch
gitb c aifp # fast AI commit + push
gitb m tm # merge to main
Release
gitb b m
gitb pu
gitb l # review log
gitb t a # annotated tag
gitb t p # push tag
Roll back a mistake
gitb undo # undo last commit (keeps changes staged)
gitb undo amend # restore pre-amend state via reflog
gitb undo merge # abort or undo last merge
gitb undo rebase # abort or undo last rebase
gitb undo stash # re-stash a popped stash
Branch hygiene
gitb b rc # pick from recently used branches
gitb b g # delete local branches whose remote is gone
gitb b del # interactive delete (orphaned / merged / pick)
gitb b - # back to previous branch (like cd -)
AI-powered commits
Drop in an API key once (or run a local model with no key at all), then let an LLM write conventional commit messages from your diff.
Providers
gitbasher supports four providers. Default is openrouter — existing setups keep working unchanged.
| Provider | Best for | Needs key? |
|---|
openrouter (default) | Trying many models behind one key (Gemini, Claude, GPT, DeepSeek…) | Yes — openrouter.ai/keys |
openai | Direct access to GPT-5.4 family at OpenAI's own pricing | Yes — platform.openai.com/api-keys |
ollama | Fully local, fully private — no key, no network, runs on your machine | No |
claude | You already use Claude Code — reuses the local claude CLI and its login, billed to your Claude account | No |
Setup
# 1. Pick a provider (skip to use the OpenRouter default)
gitb cfg provider # interactive — choose openrouter, openai, ollama, or claude
# 2. For openrouter / openai: paste your key (local repo or global)
gitb cfg ai
# For ollama: just make sure the daemon is running and the default model is pulled
ollama serve &
ollama pull qwen3:8b
# For claude: just have the Claude Code CLI installed and signed in
npm install -g @anthropic-ai/claude-code
# 3. Optional: HTTP proxy (for restricted regions, openrouter/openai only)
gitb cfg proxy
For the security-conscious, prefer the env var to avoid the key landing in ~/.gitconfig:
export GITB_AI_API_KEY='sk-...'
One model per provider, used for every task (message generation, subjects, feature grouping). Defaults (July 2026), picked speed-first:
| Provider | Default model | Why |
|---|
openrouter | google/gemini-3.5-flash | Current flash generation, ~0.8s median on a commit-sized prompt, good prose |
openai | gpt-5.4-mini | As fast as nano (~0.8s) with strictly better quality, ~$0.75 / $4.50 per M |
ollama | qwen3:8b | Best small instruction-follower; most stable structured output; ~5 GB on disk |
claude | haiku | CLI startup dominates latency, so the fastest model wins; alias tracks the current generation |
Other good picks: gpt-5.4-nano (budget, high volume), llama3.3:8b / qwen2.5-coder:7b (local), sonnet (better prose on the claude provider, noticeably slower).
The cloud defaults are hybrid reasoning models that think at "medium" effort out of the box — pure latency for a one-line commit message. gitbasher controls this per request: message generation runs at the provider's reasoning floor (minimal on OpenRouter, none on OpenAI — measured ~2× faster with identical output), while feature grouping and squash planning run at low effort, where a bit of real thinking helps multi-file structure decisions. No configuration needed.
gitb cfg model shows a live menu: the week's most-used and newest text models on OpenRouter (public API, server-side ranking), or the newest chat models visible to your OpenAI key. A typed id is validated against the live catalog (typos die at config time, with an override for brand-new models), and the chosen model is test-driven with one live request before the step completes — a model that can't complete a request never reaches your commits.
The model is remembered per provider — switching providers never carries a model across (an OpenRouter slug means nothing to the claude CLI), and switching back restores your previous choice, same as API keys:
gitb cfg model # interactive, stores for the active provider
git config gitbasher.ai-model-<provider> <model_id> # direct, e.g. gitbasher.ai-model-claude sonnet
Self-hosted gateways and remote Ollama hosts work via a base-URL override:
gitb cfg provider # pick openai or ollama as the closest match
git config gitbasher.ai-base-url http://my-gateway:4000/v1/chat/completions
Command reference
Tip: every command with modes accepts help (h) for inline help: gitb commit help, gitb sync h.
| Command | Aliases | Description |
|---|
commit | c co com | Create commits (interactive, fast, AI, split, fixup, amend, revert, …) |
edit | ed ee | Rewrite the last commit message, reword an older commit, or rename the current branch |
push | p ps pus | Push with conflict handling, force, or list-only |
pull | pu pl pul | Smart pull: rebase / merge / ff / fetch-only / interactive / dry-run |
fetch | fe | Fetch without merging: current branch, all remotes, or prune |
branch | b br bran | Switch / list / create / delete / recent / gone / checkout-tag |
tag | t tg | Create, push, list, delete tags (lightweight & annotated) |
|
gitb commit
A commit invocation is one action plus zero or more modifiers. Words can be combined freely (ai fast push) or written as a single compact token (aifp). Aliases are interchangeable.
gitb commit [<flag> ...] # space-separated, any order
gitb commit <combined> # compact form: ff, aifp, fastsp, ...
Actions — pick one; default is a regular commit.
| Action | Aliases | Description |
|---|
<empty> | | Interactive commit: choose files, type, scope, and summary |
split | sp sl | Split staged changes into one commit per detected scope |
fixup | x fix | Create a --fixup commit against an older commit |
amend | a am | Add changes into the last commit (no message edit) |
revert | rev | Revert a commit (git revert --no-edit) |
ff | | Ultrafast: ai + split + fast with no prompts (use ffp to also push) |
sff | ffst | Like ff but on already-staged files (no git add .); use sffp to also push |
help | h --help -h | Show inline help |
Modifiers — stack with an action, any order.
| Flag | Aliases | Description |
|---|
fast | f | Stage all changes (git add .) before committing |
staged | st | Use already-staged files (skip the add step) |
push | p pu | Push after the commit succeeds |
scope | s | Force a scope: type(scope): message (useful with fast mode) |
no-split | nosplit nos nsp nsl | Don't offer to split this commit (fast modes split by default) |
ai | i llm | Generate the commit message with AI |
msg | m | Open $EDITOR for a multiline message body |
ticket | t j jira | Append ticket info to the header |
Examples
| Command | What it does |
|---|
gitb commit | Interactive commit |
gitb commit fast | git add . then enter a message |
gitb commit ai fast push | AI message + add all + commit + push |
gitb commit aifp | Same as above (compact form) |
gitb commit ai split push | AI groups staged files into commits by feature, then push |
gitb commit fixup push | Pick an older commit, fixup it, then push |
gitb commit amend fast | Add all current changes into the last commit |
gitb commit ff | Full auto: AI splits and writes everything |
gitb commit sffp | Full auto on already-staged files: AI splits, writes, pushes |
How modes combine
- Word order doesn't matter:
ai fast push == push fast ai == aifp.
- Modifiers stack on actions:
ai+fixup, fast+amend, split+push, ai+staged, …
fast and staged are mutually exclusive (one stages all, the other uses what's staged).
- Splitting: a regular commit asks first whether to try a split (before any grouping or AI work), then asks again to confirm the resulting groups. Fast modes (
fast, ff, …) split without asking unless you turn it off with gitb cfg fast-split.
- Press
u at any split prompt to undo the split: commits already made by the split are dropped, staging is restored, and you continue with a single commit. ff never stops, so use the setting or no-split there.
revert and ff only accept push (as revp / ffp); to rewrite the last commit message use gitb edit.
| Token | Aliases | Same as |
|---|
fastp | fp pf | fast push |
fasts | fs sf | fast scope |
fastsp | fsp fps | fast scope push |
splitp | spp slp | split push |
aisplit | isplit aispl ispl | ai split (AI feature grouping + AI messages) |
aisplitp | isplitp aisplp isplp | ai split push |
ff | | ai fast, no prompts at all |
ffp | ffpush | ff + push |
sff | ffst | ff on already-staged files |
sffp | ffstp | sff + push |
fixupp | fixp xp px | fixup push |
fixupst | xst stx | fixup staged |
fastfix | fx xf | fixup fast |
fastfixp | fxp xfp | fixup fast push |
amendst | ast sta | amend staged |
amendf | amf |
gitb edit
Rewrites a commit message or the current branch name without touching the tree.
gitb edit # reword the LAST commit (git commit --amend)
gitb edit pick # choose any recent commit and reword it via rebase
gitb edit branch # rename the current branch (interactive)
gitb edit branch feat/new-name # rename the current branch to feat/new-name
gitb edit help # show inline help
Modes:
| Mode | Aliases | Description |
|---|
<empty> | | Reword the last commit (git commit --amend) |
pick | p c choose | Pick any recent commit, reword via non-interactive rebase |
branch | b br rename ren | Rename the current branch (git branch -m); optional remote sync |
help | h --help -h | Show inline help |
Notes:
pick requires a clean working tree (the rebase replays subsequent commits).
- Merge commits and the root commit cannot be reworded this way.
- If the commit was already pushed, run
gitb push force afterwards.
branch offers to push the new name and delete the old one on the remote when an upstream exists.
- To add staged changes into the last commit, use
gitb commit amend instead.
- To undo the change, use
gitb undo amend (for plain edit) or gitb undo rebase (for pick).
gitb push
| Mode | Aliases | Description |
|---|
<empty> | | Show commits, push with conflict handling |
yes | y | Push without confirmation |
force | f | Push with --force-with-lease (after rebase/amend; refuses if someone else pushed first) |
list | log l | List unpushed commits + estimated push size and large-file warnings |
Quick pushes stay clean — git's live progress bar appears only when a transfer runs long (same for pull/fetch). gitbasher also estimates the transfer size first, warning you before you push a stray non-code object (e.g. a build artifact or dataset). Tune the threshold with gitb cfg push-size (default 50 MB, 0 disables).
SSH keys with a passphrase. When a push, pull or fetch needs an SSH key that is locked and not loaded in ssh-agent, gitbasher asks for the passphrase instead of waiting on a hidden prompt, then keeps the key unlocked — in your ssh-agent for 1h by default. gitb cfg ssh shows which keys are locked and picks where an unlocked key lives (agent, gitb for gitbasher only, command for a single command, or off) and for how long.
gitb pull
| Mode | Aliases | Description |
|---|
<empty> | | Smart pull (strategy picker) |
fetch | fe | Fetch only |
all | fa | Fetch all branches |
upd | u | Update remote refs (git remote update) |
ffonly | ff | Fast-forward only |
merge | m | Always create merge commit |
rebase | r | Rebase current onto remote |
interactive | ri rs | Interactive rebase + autosquash |
dry | d dr | Preview incoming commits without modifying local refs |
gitb fetch
| Mode | Aliases | Description |
|---|
<empty> | | Fetch the current branch without merging |
all | a fa | Fetch every remote branch without merging |
prune | p pr | Fetch and drop branches deleted on the remote |
gitb branch
| Mode | Aliases | Description |
|---|
<empty> | | Pick a local branch to switch |
list | l | List local branches |
remote | re r | Fetch and switch to a remote branch |
main | def m | Quick-switch to default branch |
tag | t | Checkout to a specific tag |
new | n c | Create branch from current (offers to push it to the remote) |
newd | nd cd | Switch to main, pull, branch off (offers to push it to the remote) |
delete | del d | Delete branches (orphaned, merged, or selected) |
prev | p - | Switch to previous branch (cd -) |
recent | rc | Pick from recently checked-out branches |
gone | g | Delete locals whose remote tracking branch is gone |
gitb tag
| Mode | Aliases | Description |
|---|
<empty> | | Lightweight tag from HEAD |
annotated | a an | Annotated tag with message |
commit | c co cm | Tag from a selected commit |
all | al | Annotated tag from selected commit |
push | p ps ph | Push a tag |
push-all | pa | Push all tags |
delete | del d | Delete a local tag |
delete-all | da | Delete all local tags |
list | log l | List local tags |
remote | fetch re r | Fetch and list remote tags |
gitb merge
| Mode | Aliases | Description |
|---|
<empty> | | Pick a branch to merge into current |
main | master m | Merge default branch into current |
to-main | to-master tm | Switch to main, merge current branch in |
remote | r | Fetch + select a remote branch to merge |
push | p | Push the branch after a successful merge (combine with any mode) |
gitb rebase
| Mode | Aliases | Description |
|---|
<empty> | | Pick a base branch |
main | master m | Rebase current onto default |
interactive | i | Pick a base branch and rebase onto it interactively |
autosquash | a s ia | Interactive rebase with --autosquash |
fastautosquash | fast sf f | Autosquash without interaction |
pull | p | Take commits from selected branch into current |
push | | Force-push the branch after a successful rebase (combine with any mode) |
gitb squash
Ask the AI to read commits in the current branch's range and propose a clean,
changelog-ready history (e.g. fold five fix typo/wip commits into the one
feature commit they belong to). Range is auto-detected:
- On the default branch — commits since the last tag.
- On any other branch — commits since the merge-base with the default branch.
The plan is shown for confirmation before any history is rewritten. If you
don't like the result, recover with gitb undo rebase.
| Mode | Aliases | Description |
|---|
<empty> | | Generate plan, confirm, then interactive rebase |
preview | p dry show | Show the AI plan only — don't touch history |
yes | y fast | Apply without the confirmation prompt |
push | ps | After rebase, force-push with --force-with-lease |
help | h | Show usage |
Requires AI to be configured (gitb cfg ai).
gitb cherry
| Mode | Aliases | Description |
|---|
<empty> | | Pick commits from a branch interactively |
<commit-hash> | | Shorthand for cherry-pick by hash |
hash | hs | Cherry-pick a specific hash |
range | r | Cherry-pick a range (A..B) |
abort | a | Abort current cherry-pick |
continue | cont c | Continue after resolving conflicts |
gitb sync
Fetch the default branch and update your current branch. Useful mid-feature.
| Mode | Aliases | Description |
|---|
<empty> | | Fetch main + rebase current onto it |
push | p | …then force-push |
merge | m | Use merge instead of rebase |
mergep | mp pm | Merge + push |
dry | d dr | Preview commits sync would bring in from main without modifying local refs |
gitb wip
Save work-in-progress through one of three backends and restore it later. Pick
the one that fits the situation — wip up prompts when the backend isn't
specified, and wip down auto-detects which backend was used.
| Backend | What it does | When to use |
|---|
stash | git stash --include-untracked + force-push wip/<branch> to remote as backup | Quick context switch, default |
branch | Commits all changes onto a wip/<branch> branch, leaves current branch clean, optionally pushes | Want history / share work / open a draft PR |
worktree | Same as branch, but the WIP lives in a sibling worktree so you can keep working on it side-by-side | Long-running parallel work |
| Command | Aliases | Description |
|---|
gitb wip up | u | Save WIP — prompts which backend to use |
gitb wip up stash | u s | Stash + push backup branch |
gitb wip up branch | u b | Commit onto wip/<branch> + push |
gitb wip up worktree | u w u wt u tree | Move WIP into a sibling worktree |
gitb wip up <mode> nopush | np n | Skip the push step (works with any backend) |
gitb wip up nopush | u np u n | Legacy: stash + no push (same as up stash nopush) |
gitb wip down | d | Restore — auto-detects backend, prompts if ambiguous |
gitb wip down stash | d s | Restore from the stash |
gitb wip down branch | d b | Restore from wip/<branch> (squash-merge into working tree) |
gitb wip down worktree | d w d wt d tree | Restore from the wip worktree, then remove it |
gitb wip help | h | Show inline help (also what bare gitb wip prints) |
For branch and worktree, wip down brings everything (committed + uncommitted) back as plain modifications and deletes the wip branch / worktree (and remote wip/<branch> if present).
gitb undo
| Mode | Aliases | Description |
|---|
<empty> / commit | c | Undo last commit (reset --soft HEAD~1) — keeps changes staged |
amend | a | Restore pre-amend state via reflog |
merge | m | Abort or undo last merge |
rebase | r | Abort or undo last rebase (ORIG_HEAD) |
stash | s | Re-stash a popped/applied stash |
gitb reset
| Mode | Aliases | Description |
|---|
<empty> | | Preview and reset last commit (mixed) |
soft | s | Preview and soft reset last commit |
undo | u | Preview and undo last reset |
interactive | i | Pick commit to reset to, then approve |
ref | r | Reset to a HEAD reference with approval (reflog recovery) |
gitb stash
| Mode | Aliases | Description |
|---|
<empty> | | Interactive stash menu |
select | sel | Stash specific files |
all | | Stash everything including untracked |
list | l | List all stashes |
pop | p | Apply and remove |
show | s | Preview stash |
apply | a | Apply without removing |
drop | d | Delete stash |
gitb worktree
Run multiple branches in parallel without stashing or switching: each worktree
is a real working directory linked to the same .git. Great for hotfixes,
long-running reviews, or comparing branches side-by-side.
| Mode | Aliases | Description |
|---|
<empty> | | Show existing worktrees + interactive menu |
list | l ls | List all worktrees with branch and lock state |
add | a new n c | Create worktree with a new branch from current HEAD |
addd | ad nd | Fetch, then create worktree with new branch from default branch |
addb | ab from b | Create worktree from an existing local branch |
addr | ar remote r | Fetch + create worktree tracking a remote branch |
remove | rm del d | Pick a worktree to remove (force-prompt on dirty trees) |
move | mv | Move a worktree to a new path |
lock | | Lock a worktree (with optional reason) |
unlock | ul | Unlock a worktree |
prune | pr p | Clean up stale worktree records (dry-run preview first) |
manage | m | Pick a worktree, then move / lock / unlock / delete it |
goto | go g cd switch | Open a subshell inside a chosen worktree |
path | sw | Print the path to a chosen worktree (use with cd $(...)) |
gitb wt add # new branch + new worktree from current HEAD
gitb wt addd # new branch + new worktree from updated main
gitb wt addr # check out a remote branch into a fresh worktree
gitb wt remove # interactive removal (with force prompt if dirty)
cd "$(gitb wt path)" # cd into a chosen worktree
By default new worktrees are created at <repo_root>/.worktree/<branch> (slashes
in the branch name become dashes). Override the base directory globally or per-repo:
git config --global gitbasher.worktreebase ~/code/worktrees
gitb hook
| Mode | Aliases | Description |
|---|
<empty> | | Interactive action menu |
list | l | All hooks with status (list samples also shows available samples) |
select | sel | Browse hook types with descriptions |
create | new c | New hook from templates |
edit | e | Edit existing hook |
toggle | t | Enable/disable hook (enable / disable force that state) |
install | samples | Install all available sample hooks |
remove | rm r delete | Delete hook(s) |
test | run check | Test hook execution |
show | cat view s | Display hook contents |
gitb init
Initialize a new git repository and (optionally) add a remote origin.
gitb init # git init + interactive remote prompt
gitb origin set <url> # add origin without prompts
gitb init runs git init in the current directory. If the repo has no
configured remote, gitbasher offers to add one interactively. Use
gitb origin for non-interactive remote management.
gitb origin
Add, change, rename, or remove the remote origin. Useful when you create a repo
without a remote, rename the repo on GitHub/GitLab, or move it to a new host.
| Mode | Aliases | Description |
|---|
<empty> | show info | List configured remotes and their URLs |
set | add new a | Add a new origin (errors if origin already set) |
change | update c u set-url | Change the existing origin URL (after rename/move) |
rename | mv ren | Rename a remote (e.g. origin → upstream) |
remove | rm del d delete | Remove the remote |
help | h | Show help |
The set, change, and rename modes accept an optional URL/name as a second
argument to skip the interactive prompt:
gitb origin # show remotes
gitb origin set [email protected]:me/proj.git # add origin
gitb origin change https://github.com/me/new.git # update URL after rename
gitb origin rename upstream # origin → upstream
gitb origin remove # delete the remote
gitb clone
Clone a repository and set gitbasher up in it — works outside any repo.
gitb clone [email protected]:me/proj.git # into ./proj
gitb clone https://github.com/me/proj.git dir # into ./dir
gitb update
Self-update for install-script installs. Homebrew and npm installs are detected and pointed at brew upgrade gitbasher / npm update -g gitbasher instead (see Updating).
| Mode | Aliases | Description |
|---|
<empty> | | Check for a newer release and install it after confirmation |
check | c ch | Only check, don't install |
force | f fo | Reinstall the latest release even if you're up to date |
gitb config
| Mode | Aliases | Description |
|---|
<empty> | | Show current configuration |
user | u name email | Set name and email |
default | def d b main | Set default branch |
separator | sep | Branch-name separator |
editor | ed e | Commit-message editor |
ticket | ti t jira | Ticket prefix for commits/branches |
scopes | scope sc s | Common scopes |
ai | llm | AI setup wizard: provider, API key, model |
key | | AI API key only |
provider | prov | AI provider (openrouter, openai, ollama, claude) |
model | m | Default AI model |
proxy | prx p | HTTP/SOCKS proxy for AI calls |
history | hist | How many recent commits to include in AI prompts |
diff | payload | AI diff payload size (line and character caps) |
push-size | ps pushsize | Warn before pushing more than N MB (0 disables) |
fast-split | fs fastsplit | Split automatically in fast commit modes (on/off) |
ssh | passphrase unlock | Where and how long a passphrase-protected SSH key stays unlocked |
gitb log
An interactive commit browser instead of a wall of text. Bare gitb log shows a paginated, numbered commit list (with branch/tag decorations and ↑ on unpushed commits) — pick a number to open the commit and act on it: view the diff or stat, copy the hash, revert, cherry-pick, fix up staged changes into it, or restore a single file from it.
| Mode | Aliases | Description |
|---|
| (none) | | Interactive commit browser for the current branch |
all | dump | Classic full log dump through the pager |
branch | b | Pick a branch to log (local/l, remote/r, or all/a, the default) |
compare | comp c | Compare two branches |
search | s | Search commits |
ai | | Summarize a commit range in plain English (needs gitb cfg ai) |
help | h | Show inline help |
Anything else after gitb log is resolved automatically:
gitb log 20 # browse the last 20 commits
gitb log scripts/gitb.sh # browse one file's history (follows renames)
gitb log main..feature # browse a range (plain refs work too)
gitb log broken teapot # search commit messages for the phrase
gitb log ai summarizes what happened since the last tag; gitb log ai 30, gitb log ai unpushed and gitb log ai main..feature narrow the range. Page size is configurable: git config gitbasher.log-count 30.
Search sub-modes: message/msg/m, author/a, file/f, content/pickaxe/p, date/d, hash/commit/h.
gitb diff
Overview-first diffs built for the gitbasher workflow — no flag memorization. Bare gitb diff shows a colorized stat of your uncommitted changes, then lets you pick a file to view its full patch.
| Mode | Aliases | Description |
|---|
| (none) | | Stat overview of uncommitted changes, then pick a file to view its full patch |
staged | s cached | Show staged changes (git diff --cached) |
all | a | Show all uncommitted changes — staged and unstaged (git diff HEAD) |
branch | b | Compare the current branch against another, chosen interactively |
commit | c | Show a chosen commit's diff, chosen interactively |
ai | | Summarize uncommitted changes in plain English (needs gitb cfg ai) |
help | h | Show inline help |
Info commands
| Command | Aliases | Description |
|---|
status | s | Repo info and changed files |
reflog | rl rlg | Pretty reflog |
last-commit | lc lastc | Show the last commit |
last-ref | lr lastr | Show the last reference |
Configuration
gitb cfg (no args) prints the active configuration. Settings live in standard git config. gitb cfg commands save to the current repo and then offer to apply the value globally; with raw git config, add --global for every repo.
| Key | Set via | Purpose |
|---|
user.name / user.email | gitb cfg user | Your identity |
gitbasher.branch | gitb cfg default | Default branch (main, master, …) |
gitbasher.sep | gitb cfg separator | Branch-name separator (/, -, …) |
core.editor | gitb cfg editor | Editor for messages |
gitbasher.ticket | gitb cfg ticket | Ticket prefix (PROJ-) |
gitbasher.scopes | gitb cfg scopes | Suggested commit scopes |
gitbasher.ai-api-key-<provider> | gitb cfg ai | Per-provider AI API key (or GITB_AI_API_KEY_<PROVIDER> env); legacy gitbasher.ai-api-key is read as a fallback |
gitbasher.ai-provider | gitb cfg provider | openrouter (default), openai, ollama, or claude |
gitbasher.ai-base-url | git config | Custom OpenAI-compatible endpoint (LiteLLM, vLLM, remote Ollama) |
gitbasher.ai-model-<provider> | gitb cfg model | Model for that provider (one model for all tasks); legacy gitbasher.ai-model is read as a fallback |
gitbasher.ai-proxy | gitb cfg proxy | HTTP proxy for AI calls |
gitbasher.ai-ollama-host | gitb cfg provider (ollama) or git config | Ollama server URL (default http://localhost:11434) |
gitbasher.ai-timeout | git config gitbasher.ai-timeout <seconds> | AI request timeout in seconds (default 60, 300 for ollama/claude) |
Clear gitbasher config (per-repo settings live with the repo and disappear with it):
git config --global --remove-section gitbasher 2>/dev/null
git config --global --unset core.editor 2>/dev/null # only if you set it via gitb cfg editor
Aliases for shell users:
echo 'alias gc="gitb c"' >> ~/.bashrc
echo 'alias gp="gitb p"' >> ~/.bashrc
echo 'alias gpu="gitb pu"' >> ~/.bashrc
echo 'alias gb="gitb b"' >> ~/.bashrc
zsh tip: if zsh autocorrects gitb → git, add alias gitb='nocorrect gitb' to ~/.zshrc.
More install options
All of these use the install script.
# System-wide, for all users (/usr/local/bin, asks for sudo)
curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash -s -- --sudo
# Any directory on your PATH
GITB_DIR=/opt/bin curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash
# A specific release (CI, locked environments)
GITB_VERSION=v5.0.0 curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash
From source (for development):
git clone https://github.com/maxbolgarin/gitbasher.git && cd gitbasher
make install # builds dist/gitb and copies it to ~/.local/bin
Updating
Update with the same tool you installed with — gitb version tells you which one that was.
| Installed with | Update with |
|---|
| Homebrew | brew upgrade gitbasher |
| Install script | gitb update (gitb update check only checks) |
| npm | npm update -g gitbasher |
gitb update detects Homebrew and npm installs and prints the right command instead of overwriting files the package manager owns.
Uninstall
One command (recommended)
gitb uninstall
Lists every gitbasher.* key it will remove from your local + global git config and the binary path it will delete, then asks for confirmation. Detects npm and Homebrew installs and prints the right npm uninstall -g gitbasher / brew uninstall gitbasher command instead of touching files the package manager owns.
Manual
If gitb is already gone from PATH:
rm -f ~/.local/bin/gitb # default install location
sudo rm -f /usr/local/bin/gitb # if installed with --sudo
npm uninstall -g gitbasher # if installed via npm
brew uninstall gitbasher # if installed via Homebrew
# Wipe leftover gitbasher.* keys from git config
git config --global --remove-section gitbasher 2>/dev/null
git config --local --remove-section gitbasher 2>/dev/null # per repo
Troubleshooting
which gitb # is it on PATH at all?
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # install script's default location
Open a new terminal afterwards, or reinstall with any method from Install.
You probably have two copies — for example one from the install script in ~/.local/bin and one from Homebrew — and the old one comes first on your PATH. Run:
gitb version
If it warns that gitb on your PATH is a different copy, delete the one you don't use (for example rm ~/.local/bin/gitb), then run hash -r or open a new terminal. Don't use gitb uninstall for this — it also removes your gitbasher settings.
The default install goes to ~/.local/bin (no sudo). For a system-wide install pass --sudo:
curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash -s -- --sudo
gitb cfg # check config
gitb cfg ai # set API key
gitb cfg proxy # in restricted regions
If gitb commit ai hangs, returns connection refused, or times out:
- jq missing — all AI features require
jq (check with command -v jq; install via brew install jq / apt install jq). Without it every AI command aborts with an install hint.
- Generation failed mid-commit? gitbasher offers to continue with a manual commit message (staging is preserved) — press Enter to accept and write it yourself, or
n to abort.
- Network reachability — test the provider directly:
curl -fsSL https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" (or the equivalent for OpenRouter/Ollama). If that fails, gitbasher will too.
- Corporate proxy / restricted region —
gitb cfg proxy accepts host:port or protocol://host:port. Verify with curl -x "$proxy" https://api.openai.com.
- Local Ollama — confirm the daemon is running (
curl http://localhost:11434/api/tags). The default model must be pulled first (ollama pull qwen3:8b).
- Claude Code CLI — confirm it responds (
echo hi | claude -p); you may need to sign in first. Install with npm install -g @anthropic-ai/claude-code.
- Stale or rotated key —
gitb cfg ai re-prompts; prefer the env-var path (export GITB_AI_API_KEY_OPENAI=...) over git config so a leaked repo doesn't carry the secret.
git config --global writes to ~/.gitconfig. If gitbasher reports could not lock config file:
ls -la ~/.gitconfig # check ownership and permissions
sudo chown "$USER" ~/.gitconfig
chmod u+w ~/.gitconfig
rm -f ~/.gitconfig.lock # stale lock from a crashed git process
Per-repo settings live in .git/config and need write access to that file (chmod u+w .git/config if mounted read-only).
bash --version must be 3.2+ — the version macOS ships as /bin/bash — so this is rare.
- macOS: already ships bash 3.2; gitbasher runs on it natively (a newer bash via
brew install bash only improves in-place line editing of prefilled prompts)
- Ubuntu/Debian:
sudo apt update && sudo apt install --only-upgrade bash
| OS | Bash | Git | Install |
|---|
| Linux | 3.2+ | 2.23+ | apt install bash git |
| macOS | 3.2+ (system) | 2.23+ | brew install git (or Xcode Command Line Tools) |
| Windows | WSL | WSL | wsl --install then Linux steps |
AI features additionally require jq (brew install jq / apt install jq); core git commands don't.
| git complains | gitbasher path |
|---|
error: failed to push some refs ... non-fast-forward | gitb pull (rebase or merge interactively), then gitb push |
Your branch and 'origin/<branch>' have diverged | gitb sync — rebase onto the remote tip after picking strategy |
error: Your local changes ... would be overwritten | gitb wip up (stash / branch / worktree backend), pull, then gitb wip down |
fatal: refusing to merge unrelated histories | gitb merge and confirm the unrelated-history prompt, or pick a different base |
fatal: Not possible to fast-forward, aborting. | gitb sync and pick rebase, or gitb merge to create a merge commit |
error: cannot rebase: You have unstaged changes | gitb wip up first, rebase, then gitb wip down |
Another git process seems to be running ... index.lock | gitbasher detects this at startup and prompts to remove the stale lock |
error: pathspec '<branch>' did not match any file(s) known to git | gitb pull to fetch, or gitb b new <branch> to create a fresh branch with a conventional name |
fatal: detached HEAD after checkout | gitbasher warns before destructive ops in detached HEAD; use gitb b to switch to a real branch first |
gpg: signing failed on commit | export GPG_TTY=$(tty) or run git config commit.gpgsign false to disable signing per-repo |
If you hit a confusing git error not listed here, run the same flow with git directly first — gitbasher passes git's stderr through unchanged, so the underlying message is the source of truth.
Still stuck? Open an issue or ping @maxbolgarin on Telegram.
Contributing
PRs welcome. See CONTRIBUTING.md for the dev setup, BATS test patterns, and commit-message conventions. Curious how the bundle is built or how scripts get sourced into one process? See ARCHITECTURE.md.
make build # rebuild dist/gitb
make test # run the full BATS suite
make test-file FILE=test_sanitization.bats
Workflow:
- Fork and create a feature branch
- Write tests first (BATS, see tests/README.md)
- Implement
make test — all tests must pass
- Open a PR
Maintainer: @maxbolgarin
License: MIT — see LICENSE.