Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

56 Commits

Repository files navigation

gitool

A lazygit-inspired TUI for managing multiple git repositories.

Built with Rust, ratatui, and libgit2.

┌────────────────────────────────────────────────────────────────┐
│ [1 Repos] 2 Files 3 Branches 4 Commits 5 Stash workspace │
├───────────────────────┬────────────────────────────────────────┤
│ ┌ 1 Repos ──────────┐ │ │
│ │ ▸ repo-alpha ● Δ2 │ │ Preview │
│ │ repo-beta ● │ │ (context-sensitive) │
│ │ repo-gamma ↑1 │ │ │
│ └────────────────────┘ │ Repos → repo summary │
│ ┌ 2 Files ──────────┐ │ Files → syntax-highlighted diff │
│ │ ● M src/main.rs │ │ Branches → recent commits │
│ │ ○ A README.md │ │ Commits → commit diff │
│ └────────────────────┘ │ Stash → stash diff │
│ ┌ 3 Branches ───────┐ │ │
│ │ ● main origin/main │ │ │
│ │ feat/login [↑2] │ │ │
│ └────────────────────┘ │ │
│ ┌ 4 Commits ────────┐ │ │
│ │ abc1234 Fix bug 2m │ │ │
│ └────────────────────┘ │ │
│ ┌ 5 Stash ──────────┐ │ │
│ │ stash@{0}: WIP │ │ │
│ └────────────────────┘ │ │
├───────────────────────┴────────────────────────────────────────┤
│ j/k nav Tab panel 1-5 jump a stage c commit q quit │
└────────────────────────────────────────────────────────────────┘

Features

CategoryFeatures
WorkspaceMulti-repo view, workspace switching (w), repo hiding, search/filter (/), bulk mark (Space/Ctrl+a)
FilesStage (a), unstage (u), discard (x), per-file diff (d/Enter), open in editor (e), blame (b)
BranchesCheckout (Enter), create (n), delete (D), rename (R), merge (m), auto-detect default branch
CommitsBrowse history, cherry-pick (C), revert (X), create tag (t), copy hash (y), commit diff preview
StashStash with message (s), pop (Enter), drop (x), browse stash diffs
Git opsPull (p), push (P), fetch (f), commit (c), amend (A) — all non-blocking via rayon
UI5 stacked panels + context preview, mouse support, syntax-highlighted diffs, <50ms startup
UndoCtrl+z reverses checkout and stash operations

Install

git clone https://github.com/monal94/gitool.git
cd gitool
cargo install --path .

Usage

gitool ~/Projects/my-workspace # open a workspace
gitool # current directory (single repo or workspace)

Key Bindings

Global (any panel)

KeyActionKeyAction
1-5Jump to panelTab/BackTabCycle panels
q/EscQuitrRefresh
/Filter`Command log
wSwitch workspaceCtrl+zUndo

Repos (1)

KeyActionKeyAction
j/kNavigateEnterJump to Files
p/PPull / PushfFetch
SpaceMark repoCtrl+a/Ctrl+dMark / Unmark all

Files (2)

KeyActionKeyAction
aStageuUnstage
xDiscardd/EnterView diff
cCommitAAmend commit
eOpen in editorbBlame view

Branches (3)

KeyActionKeyAction
EnterCheckoutnNew branch
DDeleteRRename
mMergesStash

Commits (4)

KeyActionKeyAction
d/uScroll previewyCopy hash
CCherry-pickXRevert
tCreate tag

Stash (5)

KeyActionKeyAction
s/EnterPop stashxDrop stash

Configuration

Auto-created at ~/.config/ws/config.yaml:

workspaces:
sentry:
path: ~/Projects/sentryhidden_repos: [docs]defaults:
workspace: sentry

Architecture

src/
├── main.rs # Event loop, key/mouse handlers
├── app/
│ ├── mod.rs # App struct, enums, core state
│ ├── navigation.rs # Panel switching, selection
│ ├── dispatch.rs # Async background operations
│ ├── git_ops.rs # Git action methods
│ ├── branch_ops.rs # Branch CRUD, text input
│ ├── state.rs # Refresh, workspace, load data
│ ├── watcher.rs # File system watching
│ └── undo.rs # Undo stack
├── git/
│ ├── mod.rs # Re-exports, test helpers
│ ├── scan.rs # Repo scanning, branch loading
│ ├── status.rs # File status via libgit2
│ ├── diff.rs # Diff generation via libgit2
│ ├── ops.rs # Git mutations (libgit2 + CLI)
│ └── log.rs # Commit log, blame, show files
├── config.rs # YAML workspace config
├── types.rs # Data models
├── highlight.rs # Syntect diff highlighting
└── ui/
├── mod.rs # Layout orchestrator
├── repo_list.rs # Repos panel
├── files.rs # Files panel
├── branches.rs # Branches panel
├── commits.rs # Commits panel
├── stash_panel.rs # Stash panel
├── preview.rs # Context preview (right)
├── diff.rs # Full-screen diff overlay
├── blame.rs # Blame overlay
├── command_log.rs # Command history overlay
├── confirm.rs # Confirmation dialog
└── modal.rs # Workspace switcher

Git reads use libgit2 directly (no subprocess). Mutations use rayon thread pool for non-blocking execution. Diffs are syntax-highlighted with windowed rendering (only visible lines processed). File watching auto-refreshes on .git changes with generation-counter caching.

Testing

cargo test# 166 tests

Tech Stack

ratatui | git2 | syntect | rayon | arboard | notify | crossterm | clap

License

MIT

About

A lazygit-inspired TUI for managing multiple git repositories

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages