gw
git, but readable. gw runs your usual git commands and turns their output into something you can take in at a glance: a live progress bar instead of scrolling counters, server messages in a box with clickable links, colored ref updates, a grouped status with per-file line counts, and a full-screen log browser.
It isn't a new VCS and it doesn't hide git from you. Arguments go to git unchanged, git's exit code comes back unchanged, and when the output isn't a terminal gw is plain git.
Before and after
The same push to GitLab. Plain git:
With gw:
The progress is one animated line (spinner, stage, cur/total, percent) that settles into a ✔ when the push succeeds. The remote: lines turn into a titled box (Merge request, Pull request, or remote) with the URL as a clickable link. The ref update is one colored line under the target.
What you get
gw pull: every line colored, submodules included
- One header per repository. A recursive fetch puts the superproject's updates and each submodule's updates (
-> submodule ui-kit) under their own headers, never mixed together. - A colored summary.
Updating old..new, the fast-forward, merge, or rebase result, conflicts in red, diffstat bars, the insertions and deletions totals, andcreate mode/delete modelines. - A Submodules section. It lists each checked-out submodule with its new commit, instead of git's
Submodule path '…': checked out '<40-char sha>'.
gw status: grouped, counted, no hints
- The header shows the branch, its upstream, and ahead/behind as
↑N ↓M. - The groups are Conflicts, Staged, Changed, Submodules, and Untracked. Each file gets GitHub-style
+N -Mcounts, and a Total line sums them. - Submodules show the recorded and checked-out commits (
db0d316 → 9c75318) and what's going on inside:staged,new commits,modified content,untracked content. - No
(use "git add <file>..." …)advice lines.
gw log: a commit browser in your terminal
- The commit list has the branch graph on the left, with refs and tags inline. The changed files of the selected commit are on the right with line counts. Press
Enteron a file to see its diff. - The view starts on the current branch. Press
afor all branches, orbto pick one,dfor a date range (2 weeks ago,2026-10-01), orufor an author. - Fuzzy search with
/matches hash, subject, author, and refs:
- Actions on any commit with
Space: cherry-pick, revert, checkout, new branch, reset (soft / mixed / hard, always confirmed; a hard reset first lists the files you would lose), copy the hash, or create a tag:
gw branch, gw commit, gw stash list
Safe to drop in
- Same arguments, same exit code.
gwpasses your arguments to git untouched and exits with git's code (128 + signalif git was killed, 127 if git is missing). - Pipes and scripts get plain git. When stdout is not a terminal (pipes, CI,
$(...)),gwbehaves exactly likegit. - Machine formats pass through.
gw status -s/--porcelain/-z,gw log --oneline/--format/-p/--graph,gw commit --dry-run,gw branch <anything>, and everygw stashform exceptlistrun plain git. - Anything else is plain git.
gw diff,gw rebase,gw show, … just run git. - Untrusted text is inert. Control characters in file names, branch names, and server messages are shown as
\xNN, so a hostile remote or file name can't inject terminal escape sequences. NO_COLORis respected. Colors turn off, the layout stays the same, the bar uses#and., and links stay clickable.
Install
The crate is git-gw (the name gw is taken on crates.io); the installed command is gw. You need Rust 1.88 or newer and git 2.41 or newer on PATH.
From source:
If you installed an earlier build from source, remove it first, or cargo refuses because both provide gw:
Usage
Use it from git
Add shell aliases so gw runs behind short git commands:
Alias names can't shadow built-in commands: git ignores an alias named push, pull, status, and so on.
gw log keys
| Keys | Action |
|---|---|
j/k, ↑/↓, PgUp/PgDn, g/G |
Move |
Tab |
Switch between commits and files |
Enter (on a file) |
Show its diff; Esc goes back |
/ or Ctrl-F |
Fuzzy search by hash, subject, author, or ref; Enter keeps it, Esc clears it |
a |
Toggle current branch / all branches |
b |
Pick a branch |
d |
Date range (Since / Until, e.g. 2 weeks ago, 2026-10-01) |
u |
Pick an author, or type any author pattern |
x |
Clear all filters |
Space |
Actions on the selected commit |
q, Ctrl-C |
Quit |
Actions (Space, then a key): p cherry-pick, v revert, o checkout (detached), n new branch here, r reset (soft / mixed / hard), y copy hash, t tag.
Cherry-pick, revert, checkout, and reset hand the terminal to git, so editors and conflict messages work; press Enter to come back.
Copying uses the terminal clipboard (OSC 52); in tmux this needs set -g set-clipboard on.
How it's built
apps/gw binary: dispatch, runs git, live progress line, gw log event loop
crates/gw-parse pure parsers for git output, tested against captured fixtures
crates/gw-render progress bar, static ANSI views, and the gw log UI (ratatui)
gw never reimplements git. It runs git, asks for machine-readable output where git offers it (--porcelain, -z, LC_ALL=C for the network commands), parses the stream as it arrives, and renders. The parsers have no dependencies and are tested against output captured from real git runs.
The screenshots above are real gw output from a demo repository, rendered to SVG.
License
MIT. See LICENSE.