GitHub - simoarpe/ziggity: ⚡️ Ziggity an ultra fast, keyboard driven terminal UI for Git, written in Zig.
Pangram verdict · v3.3
We believe that this document is a mix of AI-generated, AI-assisted, and human-written content
AI likelihood · overall
MixedArticle text · 1,689 words · 6 segments analyzed
A fast, keyboard-driven terminal UI for Git — a lazygit-style workflow, written in Zig.
ziggity brings the core lazygit workflow — stage, commit, branch, rebase, and inspect history without leaving the terminal — to a small, dependency-light Zig binary. It is not a line-by-line port: it keeps lazygit's feel while leaning on idiomatic Zig, explicit memory ownership, plain git subprocesses (no libgit2), and libvaxis for the UI.
The Status panel's about splash, complete with a rotating ASCII donut.
Status, Files, Branches, Commits and Stash panels with a live diff preview and a context-sensitive footer.
Contents
Installation Highlights Screenshots Features Keybindings Configuration Status & Roadmap Development Sponsor License
Installation Ziggity needs the git command on your PATH at runtime — it drives git as a subprocess. Install via Homebrew, grab a prebuilt binary, or build from source. Homebrew (macOS / Linux) brew install simoarpe/ziggity/ziggity That taps simoarpe/homebrew-ziggity and installs the binary — the short form of: brew tap simoarpe/ziggity brew install ziggity Upgrade with brew upgrade ziggity. Unlike a downloaded binary, a Homebrew install isn't quarantined, so it runs on macOS without a Gatekeeper prompt. Manual Installation Every release ships static binaries for macOS, Linux, and Windows — no Zig toolchain required. macOS / Linux Grab the archive for your platform from the releases page — aarch64-macos or x86_64-macos for macOS, x86_64-linux-musl or aarch64-linux-musl for Linux (the musl builds are fully static and run on any distro) — then: # set VERSION to the latest release and pick your OS/arch — see the releases page VERSION=v0.1.0 curl -LO
https://github.com/simoarpe/ziggity/releases/download/$VERSION/ziggity-$VERSION-aarch64-macos.tar.gz tar -xzf ziggity-$VERSION-aarch64-macos.tar.gz sudo mv ziggity /usr/local/bin/ # or any directory on your PATH command -v ziggity # confirm it's on your PATH On macOS the binary isn't notarized, so Gatekeeper may block it on first run. Clear the quarantine flag once: xattr -d com.apple.quarantine /usr/local/bin/ziggity Windows Download ziggity-<version>-x86_64-windows-gnu.zip, unzip it, and put ziggity.exe in a folder on your PATH. Requires Git for Windows.
Note: Windows builds are cross-compiled and not yet smoke-tested on Windows — treat them as experimental for now.
Verify the Download (Optional) Each release includes a checksums.txt: sha256sum --ignore-missing -c checksums.txt # macOS: shasum -a 256 --ignore-missing -c checksums.txt Compile from Source Requirements: Zig 0.16.0 and git on your PATH. git clone https://github.com/simoarpe/ziggity cd ziggity zig build -Doptimize=ReleaseSafe # binary at ./zig-out/bin/ziggity zig build test # (optional) run the test suite The build leaves the binary at ./zig-out/bin/ziggity. Add it to your PATH so you can run ziggity from anywhere — either copy it into a directory already on your PATH: sudo cp zig-out/bin/ziggity /usr/local/bin/ or add zig-out/bin to your PATH (e.g. in ~/.zshrc or ~/.bashrc): export PATH="$PWD/zig-out/bin:$PATH" Once installed, run ziggity inside any Git repository. Press ? for the in-app keybindings overlay (it opens scrolled to the panel you're on), and q to quit. Highlights
Whole lazygit workflow — status, files, branches, commits, and stash panels with diff previews and a context-sensitive footer.
Hunk and line-level staging — enter a file to stage individual lines or hunks, with an optional side-by-side unstaged/staged split. Full interactive rebase — drop/squash/fixup/edit/reword/move per commit, a plan editor (i), cherry-pick, custom patch building, autosquash, and rebase --onto from a marked base. History & inspection — the real git log --graph DAG (ctrl+l) with first-parent jumps, ref-to-ref diffing (W) with reverse and three-dot (merge-base) modes, GPG signature verification (x), and log filtering (/). Multi-selection — v / shift+arrows select a range in any list to act on many files, commits, branches, or stashes at once; * selects a branch's own commits. Stays in sync — a quiet background git fetch keeps the inbound "commits to pull" arrow current on its own; slow and network operations run off the UI thread with a spinner while navigation stays live. Thoughtful touches — prepare-commit-msg hook prefill, stash naming and a keep-the-working-tree snapshot, per-stash patch export, and bracketed paste so a pasted multi-line message never submits early. Lightweight & explicit — one small binary, plain git subprocesses, no libgit2, fully remappable keys, themeable colours, and custom commands.
Screenshots A visual tour of the main features, captured from a real terminal session (see docs/screenshots). Hunk and Line-Level Staging enter a file to open the staging view — stage or unstage individual lines or whole hunks (space), with an optional side-by-side unstaged/staged split.
Commits & History The Commits panel previews each commit's diff, including its GPG signature status; enter opens the commit's changed files.
ctrl+l opens the real git log --graph DAG in git's own colours. By default it shows the current branch and its upstream, so the commits you're behind by (the remote's lane) are visible right away; a toggles all branches.
Jump to the current commit (HEAD) with @, or to a commit's first parent with p.
Full interactive rebase: press i on a commit to open a plan editor — mark pick / drop / squash / fixup / edit, reorder with ctrl+j/ctrl+k, then run it.
Committing c opens the commit dialog: a summary line plus an optional multi-line body, a live character count nudging the 50/72 rule, and (optionally) a prepare-commit-msg hook prefill.
Branches & Tags The Branches panel shows ahead/behind arrows, upstream tracking and per-ref actions (merge, rebase, reset, checkout…); the Tags tab lists tags with their messages.
Stash A Stash panel with a diff preview. The stash menu (s) offers all / +untracked / staged-only / a single file / keep-changes, each with an optional message — and w writes any stash to a git apply-able patch file.
Diffing & Menus Mark any ref and diff another against it (W), with reverse and three-dot (merge-base) options. Destructive actions route through clear, explicit menus.
Help & the About Screen ? opens the keybindings overlay, scrolled to the panel you're on. Selecting the Status panel shows an about screen with a live animation.
Features
Working tree & staging
Files panel from git status --porcelain -z; stage/unstage a file (space) or everything (a). Hunk and line-level staging: enter opens a staging view to stage/unstage individual lines (v for a range) or whole hunks (tab switches the unstaged/staged side; \ toggles a side-by-side split — see Staging layout). Directory-tree view (`) for working-tree files and a commit's / branch's file list: a / root, collapsible folders (enter), single-child chains compressed to a/b/c. Selecting a folder shows the combined diff beneath it; in the Files panel space stages the whole folder. Live fuzzy path filtering (smart-case subsequence) with recent-filter recall, plus a status filter (staged / unstaged / tracked / untracked).
Discard a file — or a whole folder in tree view (d on a directory) — via a menu (all / unstaged only), or discard everything (D, confirmed). Add to .gitignore (i), copy a path (y). Scoped periodic auto-refresh for external changes, plus a full refresh when the terminal regains focus.
Branches, tags & remotes
Branches panel from git branch --format: a "time ago" column, per-branch tracking status (✓ in sync, ↑/↓ ahead/behind, (gone)), and the upstream ref shown only when it isn't the obvious origin/<same-name>. Branch actions (Local tab): new (n), rename (R), delete (d), merge (M), rebase (r), fast-forward (f), checkout-by-name (c), reset (g), force-checkout (F), tag (T), move commits to a new branch (N), open the pull-request page (G), sort menu (s). Tags tab: checkout (space, detached), create (n, lightweight or annotated; overwrite prompts for --force), push to a remote (P), reset onto it (g), delete (d, local / remote / both). One remote skips the remote prompt. Remotes tab: list remotes, drill into a remote's branches, add (n), edit URL (e), remove (x), set the current branch's upstream (u), delete a remote branch (d). Worktrees & Submodules tabs (Files panel): list, create/add, open, update, remove, a submodule bulk menu (b), and switching repos in place — space/enter on a worktree (or enter on a submodule) re-roots the app onto it, with a parent / current breadcrumb and esc to walk back out.
Commits & history
Recent commits from git log (loaded incrementally — the log grows as you scroll toward the end, so it's never capped), each row showing the author's initials in a stable per-author colour and a highlighted Conventional Commits prefix (type in accent, scope muted, breaking ! in red; highlight_conventional_commits). The short hash is tinted by push state — red for commits not yet on the remote, the usual yellow once pushed.
Three tabs ([ / ] to switch): Commits, a Reflog recovery view (checkout space, reset HEAD g, branch n), and a Divergence view of the current branch versus its upstream — ↑ ahead (your local commits to push) grouped above ↓ behind (incoming commits to pull). The Divergence tab is read-only: checkout, branch-off, copy/paste and diff work; history-editing keys are disabled. Commit (c), commit --no-verify (w), amend (A) in a centered editor with a summary line and optional multi-line body (tab switches fields). The editor nudges you toward the 50/72 rule: the summary shows a live character count (yellow, turning red once it exceeds commit_summary_limit — default 50), and the description shows a soft vertical guide at the body-wrap column (commit_body_guide — default 72, 0 off). When the editor opens, the repo's prepare-commit-msg hook runs (as it would for an interactive commit) and pre-fills the fields — e.g. a branch-derived ticket prefix — editable before you commit (prepare_commit_msg_hook = true, disable to skip it). Per-commit: reset (g, soft/mixed/hard), revert (t), checkout (space, detached), branch from it (n), move commits to a new branch (N), tag (T), change author (a), and a copy-attribute menu (y: hash/subject/author). GPG signatures: a signed commit's diff shows git's verification block (--show-signature), and x verifies the selected commit's signature on demand (result in a dialog) — no per-row cost. A navigable changed-file list per commit (enter); d there discards a file's changes from that commit (rebase + amend). Commit graph viewer (ctrl+l): the real git log --graph DAG in git's colours, loaded off-thread. The default view shows the current branch and its upstream (so incoming commits to pull are visible); a toggles all branches. @ jumps to the current commit (HEAD), p to the first parent, enter jumps the selection; mouse scroll/drag/click supported.