gitbasher
v5.2.1
Published
Simple bash utility that makes git easy to use
Maintainers
Readme
In 30 seconds
- What it is — a single-binary
bashwrapper forgit. 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 / stashBefore & 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 |
Install in 10 seconds
One-liner
curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bashThe installer drops gitb into ~/.local/bin by default — no sudo, no password prompt. It downloads the latest release, verifies its SHA-256, and prints a PATH hint if needed.
npm (easy to remember)
npm install -g gitbasher60-second 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 branchEvery command has a short alias (gitb c, gitb p, gitb pu, gitb b, gitb s, …) and inline help (gitb commit help).
Table of contents
- Why gitbasher
- All features at a glance
- Common workflows
- AI-powered commits
- Command reference
- Configuration
- Other install paths
- Uninstall
- Troubleshooting
- Contributing
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 aiwrites 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,
undorolls back commit/amend/merge/rebase/stash,resetis interactive with a preview. - Whole workflows, not just commands —
sync,wip,branch newd,merge to-main,squashchain the steps you'd otherwise do by hand. - One file, no deps — pure bash for every git operation; only the AI features need
jqandcurl. Drop the binary anywhere onPATHand go. 940+ BATS tests cover sanitization, git ops, and branch logic.
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 | status (s), diff (d), log (l), reflog (rl), last-commit (lc), last-ref (lr) | Pretty repo status, overview-first diffs with a file picker + AI summary, multi-mode log + search, reflog viewer, quick last-commit / last-ref summary |
| Hooks | hook (ho) | List / create from templates / edit / toggle / remove / test / show — for every git hook |
| Repo setup | init (i), origin (or, o, remote) | git init from gitbasher · add/change/rename/remove the remote origin |
| Config | config (cfg) | User, default branch, separator, editor, ticket prefix, scopes, AI provider/key/model, proxy, completion |
| Lifecycle | update (up), uninstall (uns) | Self-update from latest GitHub release · one-shot uninstall (config + binary) |
Total: 31 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 rebaseSave WIP across machines / branches
gitb wip up # 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 mainRelease
gitb b m
gitb pu
gitb l # review log
gitb t a # annotated tag
gitb t p # push tagRoll 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 stashBranch 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 proxyFor 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 sonnetSelf-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/completionsCommand reference
Tip: every command 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) |
| merge | m me | Merge into current, into main, or from remote |
| rebase | r re base | Rebase onto main / interactive / autosquash / pull-commits |
| squash | sq tidy | AI groups branch commits into clean, changelog-ready history |
| cherry | ch cp | Cherry-pick by hash, range, or interactive picker |
| sync | sy | Fetch main + rebase (or merge) current branch, optional push |
| wip | w | Stash all + backup to remote (up) / restore (down) |
| undo | un | Undo last commit / amend / merge / rebase / stash |
| reset | res | Friendly git reset with preview, approval, and undo support |
| stash | st sta | Full stash menu: select, all, list, pop, apply, show, drop |
| worktree | wt tree | Manage git worktrees: add, list, remove, move, lock, prune |
| hook | ho hk | Manage git hooks: list, create, edit, toggle, remove, test, show |
| origin | or o remote | Add, change, rename, or remove the remote origin |
| init | i | git init + optional origin setup prompt |
| clone | cl clo | Clone a repository and set up gitbasher in it |
| update | up upd | Self-update gitb to the latest release |
| uninstall | uns uni | Remove the binary and gitbasher.* config keys |
| config | cf cfg conf | Configure user, branch, AI, scopes, ticket prefix, etc. |
| log | l lg | Interactive commit browser; also branch, compare, search, and full-dump modes |
| status | s | Repo status and changed files |
| diff | d di | Overview-first diffs: staged, all, branch, commit, AI summary |
| reflog | rl rlg | Pretty reflog |
| last-commit | lc lastc | Show the last commit |
| last-ref | lr lastr | Show the last reference |
| prev | - | Switch to previous branch (cd -) |
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 | nsp nsl | Disable automatic split detection for this commit |
| 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, … fastandstagedare mutually exclusive (one stages all, the other uses what's staged).revertandffonly acceptpush(asrevp/ffp); to rewrite the last commit message usegitb edit.
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 helpModes:
| 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:
pickrequires 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 forceafterwards. branchoffers 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 amendinstead. - To undo the change, use
gitb undo amend(for plain edit) orgitb undo rebase(forpick).
gitb push
| Mode | Aliases | Description |
|------|---------|-------------|
| <empty> | | Show commits, push with conflict handling |
| yes | y | Push without confirmation |
| force | f | Force push (use after rebase/amend) |
| 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).
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 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 | Interactive rebase from picked commit |
| 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 | 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 | Restore from the wip worktree, then remove it |
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 worktreeBy 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/worktreesgitb hook
| Mode | Aliases | Description |
|------|---------|-------------|
| <empty> | | Interactive action menu |
| list | l | All hooks with status |
| 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 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 promptsgitb 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 | 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 remotegitb 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 | 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 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) |
| completion | comp | Install / uninstall bash & zsh tab completion |
| delete | unset del | Remove global config |
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 |
| 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 phrasegitb 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, so they're per-repo by default — use --global for everywhere.
| 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 | git config gitbasher.ai-ollama-host <url> | 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) |
| gitbasher.ai-diff-limit | gitb cfg diff | Diff lines sent to AI (default 300) |
| gitbasher.ai-diff-max-chars | gitb cfg diff | Character cap on the diff sent to AI (default 20000) |
| gitbasher.ai-commit-history-limit | gitb cfg history | Recent commits included in AI prompts (default 10) |
| gitbasher.push-warn-size | gitb cfg push-size | Warn before pushing more than N MB (default 50, 0 disables) |
| gitbasher.worktreebase | git config gitbasher.worktreebase <dir> | Base directory for new worktrees (default .worktree under the repo root) |
| gitbasher.commit-auto-split | git config gitbasher.commit-auto-split <ask\|always\|never> | Offer to split a commit per scope (default ask) |
| gitbasher.commit-max-split-groups | git config gitbasher.commit-max-split-groups <2..20> | Cap on split commits per run (default 7) |
| gitbasher.commit-split-order | git config gitbasher.commit-split-order <auto\|alpha> | Order split commits by dependency (auto, default) or alphabetically (alpha) |
| gitbasher.commit-ai-grouping | git config gitbasher.commit-ai-grouping <never\|auto\|always> | AI feature grouping for commit splits (default auto) |
| gitbasher.log-count | git config gitbasher.log-count <n> | Commits per page in the gitb log browser (default 20) |
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 editorAliases 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"' >> ~/.bashrczsh tip: if zsh autocorrects gitb → git, add alias gitb='nocorrect gitb' to ~/.zshrc.
Other install paths
System-wide install
# system-wide install (sudo, /usr/local/bin)
curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bash -s -- --sudoCustom location
GITB_DIR=/opt/bin curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bashPin a release
GITB_VERSION=v5.0.0 curl -fsSL https://raw.githubusercontent.com/maxbolgarin/gitbasher/main/install.sh | bashUninstall
One command (recommended)
gitb uninstallLists 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 installs and prints the right npm uninstall -g gitbasher command instead of touching node_modules.
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
# 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 repoTroubleshooting
which gitb # check install location
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # if installed to ~/.local/binReinstall via npm (npm install -g gitbasher) or curl (see install).
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 -- --sudogitb cfg # check config
gitb cfg ai # set API key
gitb cfg proxy # in restricted regionsIf gitb commit ai hangs, returns connection refused, or times out:
- jq missing — all AI features require
jq(check withcommand -v jq; install viabrew 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
nto 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 proxyacceptshost:portorprotocol://host:port. Verify withcurl -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 withnpm install -g @anthropic-ai/claude-code. - Stale or rotated key —
gitb cfg aire-prompts; prefer the env-var path (export GITB_AI_API_KEY_OPENAI=...) overgit configso 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 processPer-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 bashonly 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 |
| 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.
npm uninstall -g gitbasher # if installed via npm
sudo rm /usr/local/bin/gitb # if installed system-wide
rm -f ~/.local/bin/gitb # if installed per-userStill 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 all 940+ tests
make test-file FILE=test_sanitization.batsWorkflow:
- 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.
