A fast, subcommand-based Git TUI for people who live in the terminal.
Pick from a menu instead of memorizing flags. Every destructive action asks first. Built in Go with Bubble Tea & Lip Gloss.
English Β· νκ΅μ΄
Most everyday Git friction comes from commands and flags you have to remember.
git rebase -i, git reflog, git commit --amend, git push origin --delete <tag> are
powerful, but you have to recall the exact syntax every time β and mistakes are hard to undo.
gito removes that friction:
- Discoverable β choose from a menu and follow on-screen key hints instead of memorizing commands.
- Safe by default β destructive operations (branch delete, remote tag delete, discardβ¦) always confirm first.
- Terminal-native β no separate GUI; works the same over SSH and on remote servers.
- Instant β ships as a single static binary with no runtime dependencies.
- Multilingual β UI auto-detects your locale (English, νκ΅μ΄, ζ₯ζ¬θͺ, δΈζ).
lazygit, tig, and gitui are excellent. gito aims at a different point in the design space:
| gito | lazygit | tig | gitui | |
|---|---|---|---|---|
| Model | Focused subcommands (gito tag, gito commit) |
One big dashboard | Log-centric browser | One big dashboard |
| Enter a task | Jump straight to one screen, then back to the shell | Navigate panels | Navigate views | Navigate tabs |
| Commit conventions | Config-driven (gito.json commit types) |
β | β | β |
| Built-in i18n | en / ko / ja / zh | β | β | β |
| Codebase | Minimal, one Bubble Tea model per command (great to learn from) | Large | C | Rust |
| Language | Go | Go | C | Rust |
In short: gito is a set of small, purpose-built tools rather than a single monolithic UI β enter the exact screen you need, finish, and drop back to your shell. Its small, readable codebase also makes it a friendly place to learn Go + TUI development.
gito commit Interactive commit wizard (5-step, config-driven types)
gito log Scrollable log viewer (/ search, enter: detail; optional [path...])
gito branch Fuzzy branch switcher / create / rename / delete
gito status Interactive stage / unstage / diff / discard
gito stash Stash list (pop / apply / show diff / drop)
gito tag Tag manager (create / delete / push / show diff)
gito remote Remote list (fetch / ahead-behind status)
gito diff Compare two refs (branch/tag) and view the diff
gito reflog Browse reflog and recover commits into a new branch
gito blame Pick a file (or pass one) and view line-by-line blame
gito rebase Safe interactive rebase (reorder / squash / drop / reword)
gito cherry-pick Cherry-pick commits from another branch (auto-abort on conflict)
gito undo Safely undo the last git operation (soft/hard)
gito worktree Manage git worktrees (list / add / remove)
| Command | What it does | Key bindings |
|---|---|---|
commit |
5-step wizard (type β scope β subject β body β confirm); types customizable via gito.json |
y commit, a amend, e edit |
log |
Scrollable commit log with detail diff; filter by subject, author or hash (enter searches the full history); gito log <path>... limits to commits touching those paths |
β/β move, / search, enter detail, g/G top/bottom |
branch |
Fuzzy-filter switch + create / rename / delete | enter switch, ^b create, ^r rename, ^d delete, ^x force-delete |
status |
Stage / unstage files or individual text hunks, diff / discard | space toggle, a stage all, d diff, D discard; in diff: n/p select hunk, space stage/unstage |
stash |
Manage the stash list | p pop, a apply, d diff, D drop |
tag |
Create (lightweight/annotated) / delete / push tags | c create, p push, P delete remote, D delete |
remote |
Remote list, fetch, upstream ahead/behind | f fetch, F fetch all, r refresh |
diff |
Pick two refs (branch/tag) and compare | enter select (base β target) |
reflog |
Browse reflog and recover commits (non-destructive: creates a new branch) | b branch from here |
blame |
Pick a file and view line-by-line blame; gito blame <file> opens it directly |
enter view blame |
rebase |
Safe interactive rebase: reorder / squash / fixup / drop / reword, with a backup ref created before running | p/r/s/f/d actions, K/J move, y run |
cherry-pick |
Visually select commits from another branch and cherry-pick them (auto-abort on conflict) | space select, a all, y run |
undo |
Safely undo the last git operation (soft/hard) | s soft, h hard, y confirm |
worktree |
List / add (existing or new branch) / remove worktrees | a add, n new branch, D delete |
gito undo refuses to reset immediately after a branch switch, since resetting
to the previous HEAD would move the current branch to the other branch's commit.
Use git switch - to switch back, or gito reflog to choose a recovery point.
brew install mrkayhyun/tap/gitogo install github.com/mrkayhyun/gito@latestDownload the archive for your OS/arch from the Releases page,
extract it, and put the gito binary on your PATH.
Builds from source, installs to ~/.local/bin, and wires up your ~/.zshrc PATH automatically.
git clone https://github.com/mrkayhyun/gito && cd gito
./install.sh
source ~/.zshrc # or open a new terminal- Custom location:
INSTALL_DIR=/usr/local/bin ./install.sh - Uninstall:
./install.sh --uninstall(removes the binary + the~/.zshrcblock) - The
~/.zshrcchange is a single marked, idempotent block β safe to re-run.
git clone https://github.com/mrkayhyun/gito && cd gito
go build -o gito .
# stamp a version:
go build -ldflags "-X main.version=v1.1.0" -o gito .The result is a single dependency-free binary.
Run any subcommand from inside a Git repository:
gito status # stage / review changes
gito commit # write a commit interactively
gito log # browse history
gito log src/ # only commits touching src/
gito blame main.go # blame one file directly
gito diff # compare two branches/tags# bash (~/.bashrc)
source <(gito completion bash)
# zsh (~/.zshrc, after compinit)
source <(gito completion zsh)
# fish
gito completion fish > ~/.config/fish/completions/gito.fishIn gito status, select a modified text file and press d. Use n / p to
select the next / previous hunk, then space to stage that hunk. Open a file
under Staged to unstage a hunk using the same keys. The selected hunk is
marked with βΆ; arrow keys scroll without changing the selection.
Only the index is updated; your working file is preserved. After applying a
hunk, the diff refreshes automatically. If the file or index changed since
the preview, gito refuses the stale patch; press r to refresh and review it.
Hunk actions support modifications to regular text files. New/deleted files, staged renames, binary files, mode changes, symlinks, submodules, and conflicts remain view-only in this screen; use file-level staging or Git for those changes.
Don't remember the command names? Just run gito with no arguments to open the interactive launcher.
Move with β/β or jump directly by number (1β9, 0 for the 10th).
gito # open the launcher menu
gito menu # (explicitly) open the launcher menugito help # full command help (same as gito -h / --help)
gito version # print version (same as gito -v / --version)Running a command outside a Git repository prints a friendly hint and exits.
- List screens:
escorctrl+cto quit (screens without a filter also acceptq) - Detail / diff screens:
qorescto go back to the list
Define commit types to match your team's conventions. Config is resolved in this order:
./gito.json(project root, takes precedence)~/.config/gito/config.json
{
"lang": "en",
"theme": "auto",
"commit_types": [
{"key": "feat", "label": "feat A new feature"},
{"key": "fix", "label": "fix A bug fix"},
{"key": "docs", "label": "docs Documentation only"}
]
}Without config, gito uses Conventional Commits defaults (feat/fix/docs/style/refactor/test/chore).
The lang field (en / ko / ja / zh) overrides locale auto-detection; you can also set GITO_LANG.
Colors adapt to light and dark terminal backgrounds automatically. If your terminal does not report its
background (some SSH/tmux setups), force it with "theme": "light" / "dark" or GITO_THEME=light|dark
(the environment variable wins). NO_COLOR=1 disables colors entirely.
gito follows a simple three-layer design:
main.go // subcommand routing + help
βββ internal/
βββ git/ // thin wrappers around the git CLI (isolated side effects, unit-tested)
βββ ui/ // one Bubble Tea model (Model/Update/View) per command
βββ config/ // gito.json / ~/.config/gito loading
βββ i18n/ // localization catalog (en/ko/ja/zh) + locale detection
βββ style/ // shared Lip Gloss palette
Design principle: state lives in the model, side effects live in the git layer, and the UI stays
a pure Update function β easy to test and reason about.
go build ./... # build
go vet ./... # static analysis
go test ./... # tests (the git layer is verified against real temp repos)Issues and pull requests are welcome β see CONTRIBUTING.md.
Security problems should be reported privately; see SECURITY.md.
MIT Β© mrkayhyun