<strong>Multi repo Git workspace dashboard for the terminal</strong>
<a href="https://github.com/affromero/gitpane/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/affromero/gitpane/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI"></a>
<a href="https://github.com/affromero/gitpane/actions/workflows/security.yml"><img src="https://img.shields.io/github/actions/workflow/status/affromero/gitpane/security.yml?branch=main&label=Security&logo=github&style=flat-square" alt="Security"></a>
<a href="https://github.com/affromero/gitpane/actions/workflows/coverage.yml"><img src="https://img.shields.io/github/actions/workflow/status/affromero/gitpane/coverage.yml?branch=main&label=Coverage&logo=github&style=flat-square" alt="Coverage"></a>
<a href="https://github.com/affromero/gitpane/actions/workflows/docs.yml"><img src="https://img.shields.io/github/actions/workflow/status/affromero/gitpane/docs.yml?branch=main&label=Docs&logo=github&style=flat-square" alt="Docs"></a>
<a href="https://github.com/affromero/gitpane/actions/workflows/gitleaks.yml"><img src="https://img.shields.io/github/actions/workflow/status/affromero/gitpane/gitleaks.yml?branch=main&label=gitleaks&logo=github&style=flat-square" alt="Gitleaks secret scan"></a>
<a href="https://crates.io/crates/gitpane"><img src="https://img.shields.io/crates/v/gitpane.svg?logo=rust&style=flat-square&color=blue" alt="crates.io"></a>
<a href="https://docs.rs/gitpane"><img src="https://img.shields.io/docsrs/gitpane?logo=rust&style=flat-square" alt="docs.rs"></a>
<a href="https://deps.rs/repo/github/affromero/gitpane"><img src="https://deps.rs/repo/github/affromero/gitpane/status.svg?style=flat-square" alt="Dependency status"></a>
<a href="https://github.com/affromero/gitpane/blob/main/Cargo.toml"><img src="https://img.shields.io/badge/MSRV-1.88.0-dea584?style=flat-square&logo=rust" alt="MSRV 1.88.0"></a>
<a href="https://crates.io/crates/gitpane"><img src="https://img.shields.io/crates/d/gitpane?label=downloads&style=flat-square&color=blue" alt="Downloads"></a>
<a href="https://github.com/affromero/gitpane/releases/latest"><img src="https://img.shields.io/github/v/tag/affromero/gitpane?label=release&style=flat-square&color=blue" alt="GitHub Release"></a>
<a href="https://github.com/affromero/gitpane/releases"><img src="https://img.shields.io/github/downloads/affromero/gitpane/total?label=release%20downloads&style=flat-square&color=blue" alt="Release downloads"></a>
<a href="https://github.com/affromero/gitpane/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License: MIT"></a>
<img src="https://img.shields.io/badge/platform-linux%20%7C%20macos%20%7C%20windows-lightgrey?style=flat-square" alt="Platform">
<img src="https://img.shields.io/github/languages/top/affromero/gitpane?style=flat-square&color=dea584" alt="Language">
<a href="https://github.com/affromero/gitpane/blob/main/AGENTS.md"><img src="https://img.shields.io/badge/AGENTS.md-7c3aed?style=flat-square" alt="AGENTS.md"></a>
Monitor all your repos at a glance. See branch, dirty state, ahead/behind, active worktrees, changed files, and commit history without leaving the terminal.

cargo install gitpane
That's it. No cloning, no building from source. Runs on Linux, macOS, and Windows.
Don't have Rust? Download a prebuilt binary from GitHub Releases. It is a single static binary with zero dependencies.
```bash
macOS (Apple Silicon)
curl -LO https://github.com/affromero/gitpane/releases/latest/download/gitpane-aarch64-apple-darwin.tar.gz tar xzf gitpane-aarch64-apple-darwin.tar.gz && sudo mv gitpane /usr/local/bin/
macOS (Intel)
curl -LO https://github.com/affromero/gitpane/releases/latest/download/gitpane-x86_64-apple-darwin.tar.gz tar xzf gitpane-x86_64-apple-darwin.tar.gz && sudo mv gitpane /usr/local/bin/
Linux (x86_64, statically linked)
curl -LO https://github.com/affromero/gitpane/releases/latest/download/gitpane-x86_64-unknown-linux-musl.tar.gz tar xzf gitpane-x86_64-unknown-linux-musl.tar.gz && sudo mv gitpane /usr/local/bin/
Linux (ARM64)
curl -LO https://github.com/affromero/gitpane/releases/latest/download/gitpane-aarch64-unknown-linux-gnu.tar.gz tar xzf gitpane-aarch64-unknown-linux-gnu.tar.gz && sudo mv gitpane /usr/local/bin/ ```
On NetBSD? gitpane is available as a community-maintained pkgsrc package in
devel/gitpane, thanks to @0323pin:
sh pkgin install gitpane # prebuilt binary package cd /usr/pkgsrc/devel/gitpane && make install # build from pkgsrc source
Then run:
gitpane # Scans ~/Code by default
gitpane --root ~/projects # Scan a specific directory
gitpane diagnostic # Print config, watcher, and workspace diagnostics
If you installed with cargo, gitpane can update itself:
gitpane update # checks for a newer release, then runs cargo install
cargo install gitpane # the equivalent manual command, overwrites the old binary
If you installed from a GitHub Release, download the latest binary for your platform using the same commands from the install section above.
On NetBSD, update through pkgsrc instead of gitpane update, which shells out to cargo install and would replace the package-managed binary with a cargo-built one.
If you work across multiple repositories, such as microservices, monorepos with submodules, or a mix of projects, you know the pain of checking status one directory at a time. Existing TUI tools focus on one repo at a time:
| Tool | Multi repo | Auto refresh | Worktrees | Mouse | Commit graph | Split diffs | Push/Pull |
|---|---|---|---|---|---|---|---|
| gitpane | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| lazygit | No | No | No | Yes | Yes | Yes | Yes |
| gitui | No | No | No | Yes | Yes | Yes | Yes |
| tig | No | No | No | No | Yes | No | No |
| git-delta | No | No | No | No | No | Yes (pager) | No |
| grv | No | No | No | Yes | Yes | No | No |
| git-summary | Yes (list only) | No | No | No | No | No | No |
| mgitstatus | Yes (list only) | No | No | No | No | No | No |
| gita | Yes (CLI only) | No | No | No | No | No | Yes |
| gitbatch | Yes (TUI) | No | No | No | No | No | Yes (batch) |
| gwq | Yes (CLI) | No | Yes | No | No | No | No |
| Canopy | Yes (CLI) | No | Yes | No | No | No | No |
lazygit and gitui are excellent for deep single repo work like staging hunks, interactive rebase, and conflict resolution. gitpane is the workspace level dashboard. It shows every repo at once, lets you drill into anything, and keeps you in the terminal. They complement each other.
A newer category of worktree dashboards has grown up around parallel AI agents, such as gwq (worktree status list with tmux integration), Canopy, and git-worktree-manager. gitpane overlaps here, it expands each repo into its per worktree branch, ahead/behind, dirty, and submodule state, but pairs that with a full commit graph, split diffs, and remote ops the dashboard-only tools lack. With o to open any repo or worktree in a new tmux pane (or your editor), it is both the overview and the launchpad.
Repos on the left show branch, dirty state (*), ahead/behind arrows (↑↓), worktree count (⎇), dirty submodules (◈), unpushed submodule pointer (⇡), stash count ($), and file count. Changes in the middle. Commit graph on the right.

Click a changed file (or press Enter) to see its diff side by side. File list stays navigable on the left.

Click a commit in the graph to see its files. Click a file to see the commit diff. Layered Esc dismissal: diff → files → graph.

~/Code (configurable) for git repos. It shows branch, dirty indicator (*), ahead/behind arrows (↑↓), worktree count (⎇), dirty submodule (◈), unpushed submodule pointer (⇡), stash count ($), and change count.⎇2). In the agentic AI era, tools like Claude Code create worktrees for parallel development. gitpane lets you see which repos have active parallel work.o (or the Open context menu item) to drop into the selected repo or worktree, a new tmux pane at its directory by default, or any [open] command you configure (cursor {path}, code {path}, ...). Turns the overview into a launchpad instead of a dead end.◉ marks any repo or worktree that has a live tmux pane open inside it, so at a glance you can see which parallel agents are actively working where. tmux only; toggle with [ui] show_liveness.origin <branch> is used for reliability.a to add any repo with tab completing path input. Press d to remove. Press R to rescan.s.y to copy selected item from any panel (OSC 52).| Key | Action |
|---|---|
? |
Toggle keybindings help overlay |
Tab / Shift+Tab |
Cycle focus between panels |
r |
Refresh all repo statuses |
R |
Rescan directories for repos (clears exclusions) |
g |
Reload git graph for selected repo |
o |
Open selected repo/worktree (new tmux pane, or [open] command) |
v |
Review selected repo/worktree's diff vs its base branch (new tmux window) |
G |
Attach the live tmux session(s) for the selected repo/worktree |
a |
Add a repo (opens path input with tab completion) |
d |
Remove selected repo, or worktree if a worktree row is selected (with confirmation) |
s |
Cycle sort order (Alphabetical / Dirty first) |
w |
Toggle worktree subtree for the selected repo |
S |
Toggle stash subtree for the selected repo |
t |
Open the theme picker (live preview, Enter to persist) |
y |
Copy selected item to clipboard |
q |
Quit (or close diff if one is open) |
Esc |
Navigate back through panels, then quit |
| Key | Action |
|---|---|
j / ↓ |
Next repo |
k / ↑ |
Previous repo |
| Key | Action |
|---|---|
j / ↓ |
Next file |
k / ↑ |
Previous file |
Enter |
Open split diff view |
Esc / h / ← |
Close diff view |
| Key | Action |
|---|---|
j / ↓ |
Next commit / file |
k / ↑ |
Previous commit / file |
h / l |
Scroll graph left / right |
Enter |
Open commit files / file diff |
Esc |
Close diff → close files → back |
/ |
Search commits (message, author, short ID) |
n / N |
Next / previous search match |
f |
Toggle first parent mode |
c |
Collapse / expand branch |
H |
Expand all collapsed branches |
| Action | Effect |
|---|---|
| Left click | Select item, switch panel focus |
| Click selected row | Open diff / commit detail |
| Right click (repo list) | Context menu (push, pull, copy path) |
| Scroll wheel | Navigate lists or scroll diffs |
a)| Key | Action |
|---|---|
Tab |
Autocomplete directory path (cycles matches) |
Enter |
Add the repo |
Esc |
Cancel |
Ctrl+A / Home |
Cursor to start |
Ctrl+E / End |
Cursor to end |
Ctrl+U |
Clear line before cursor |
gitpane resolves its config file in this order (first existing file wins):
$GITPANE_CONFIG (if set, treated as the full path; this overrides everything below and is also the save target)$XDG_CONFIG_HOME/gitpane/config.toml (if `$XDG_CONFIG_$ claude mcp add gitpane \
-- python -m otcore.mcp_server <graph>