A GPU-accelerated Git client built in Rust with Vulkan. Designed for power users who want fast, visual interaction with Git repositories, including support for worktrees and submodules.
- GPU-accelerated via Vulkan using vulkano 0.35 with custom retained-mode widget system
- SDF text rendering with font atlas built from Roboto Regular/Bold via fontdue + custom EDT (Euclidean Distance Transform) pipeline
- 4x MSAA antialiasing for smooth edges on text and shapes
- Spline rendering for commit graph connections using CPU-tessellated Bezier curves
- Avatar rendering with a dedicated GPU atlas for Gravatar images
- Three-layer render pipeline: graph layer → chrome layer → overlay layer, each with splines → avatars → text passes
- Dark blue-gray theme (#1a1e24 family) with rounded corners, pill outlines, and drop shadows
- HiDPI/4K aware -- all layouts scale with the display scale factor
- Continuous redraw for smooth cursor blink and toast animations
- Branch topology visualization with colored lane assignments
- Lane reuse algorithm that keeps the graph compact (3-4 lanes typical)
- Smooth S-curve Bezier merge/fork connection lines
- 24-segment circle nodes at each commit
- Each row displays: graph lanes | commit subject | author (dimmed) | relative time (right-aligned)
- Color-coded pill labels at branch tips: local (blue), remote (cyan), tag (amber), HEAD (green) with outlines
- Time-based variable row spacing (log-scaled gaps between commit groups)
- Zebra striping and row hover highlighting
- Graph column shadow on right edge of lane area
- Click to select a commit and view its diff
- Infinite scroll -- loads more commits as you scroll down
- Working directory status row at the top when changes exist
- Right-click context menu: Copy SHA, View Details, Checkout, Create Branch, Create Tag, Cherry-pick, Revert, Reset (Soft/Mixed/Hard)
- Six collapsible sections: LOCAL, REMOTE, TAGS, SUBMODULES, WORKTREES, STASHES
- Rounded section headers with collapse arrows and item count badges
- Current branch highlighted with accent color and left stripe
- Keyboard navigation (j/k, PageUp/PageDown) and selection (Enter to checkout)
- Delete branches with
d, create tags from context menu - Right-click context menus: Checkout, Delete, Push, Merge into Current, Rebase Current onto
- Submodule context menu: Open in Terminal, Update, Delete
- Worktree context menu: Open in Terminal, Jump to Branch, Remove
- Stash context menu: Apply, Pop, Drop
- Scrollbar with proportional thumb and auto-scroll on keyboard navigation
- Split view: commit message editor (subject + body) and file lists
- Subject line input with 72-character limit and placeholder text
- Multi-line body text area
- Separate staged and unstaged file lists with styled headers and colored status indicators
- Stage/unstage individual files (double-click) or all files at once
- Click files to view their diff
- Ctrl+Enter to commit, amend mode (Ctrl+Shift+A) pre-fills from last commit
- Right-click context menu (Stage, Unstage, View Diff, Discard)
- Auto-focus subject input after successful commit
- Color-coded diff display (green additions, red deletions, purple hunk headers)
- Word-level diff highlighting -- changed portions within lines get a brighter background
- Horizontal scrolling with Shift+ScrollWheel or Left/Right arrow keys
- Hunk-level staging -- Stage/Unstage buttons on each hunk header
- Line numbers in the gutter
- Supports both commit diffs and working directory diffs (staged and unstaged)
- Full commit metadata: SHA, author, date, parent commits, full message
- Clickable file list with +/- addition/deletion stats per file
- Select a file to view its individual diff
- Fetch, Pull, and Push buttons in the header bar
- Operations run in background threads (non-blocking UI)
- Button labels show status: "..." while in progress, "Pull (-N)" when behind, "Push (+N)" when ahead
- Toast notifications on success or failure
- Automatic UI refresh after remote operations complete
- Open multiple repositories as tabs (Ctrl+O to open, Ctrl+W to close)
- Tab bar with close buttons, click to switch
- Ctrl+Tab / Ctrl+Shift+Tab to cycle between tabs
- Each tab maintains independent view state (focused panel, scroll positions, selections)
- Toast notification when opening/closing tabs
- Automatic download of Gravatar images based on author email (md5 hash)
- 512x512 GPU atlas with 64 avatar slots (64x64 each)
- Disk cache at
~/.cache/whisper-git/avatars/ - Falls back to colored identicon (first initial with deterministic color) when no Gravatar exists
- Togglable in Settings
- Right-click context menus on commit graph, branch sidebar, and staging area
- Keyboard navigation (j/k or Up/Down, Enter or Space to select)
- Separator support for visual grouping
- Click outside or press Escape to close
- Shadow and border styling
- Color-coded notifications: green (Success), red (Error), blue (Info)
- Auto-dismiss after 4 seconds with 1-second fade-out
- Stacking (up to 3 visible at once)
- Bottom-center overlay positioning
- Activate with Ctrl+F or
/in the commit graph - Matches against commit subject, author name, and SHA
- Non-matching commits are dimmed (not hidden)
- Blinking cursor in search input
- Modal overlay triggered from the header bar Settings button
- Show Avatars: toggle Gravatar avatar display on/off
- Scroll Speed: Normal or Fast (2x)
- Row Size: Normal or Large (1.5x)
- Settings persisted to
~/.config/whisper-git/settings.json - Escape or click outside to close
- Commit: Stage files, write message, Ctrl+Enter to commit
- Amend Commit: Ctrl+Shift+A toggles amend mode, pre-fills subject/body from HEAD
- Revert Commit: Context menu with confirmation dialog
- Reset to Commit: Soft, Mixed, or Hard reset with confirmation (Hard has strong warning)
- Create/Delete Branch: From graph or sidebar context menus with name dialog
- Create/Delete Tag: From graph or sidebar context menus with name dialog
- Merge/Rebase: Sidebar context menu "Merge into Current" / "Rebase Current onto"
- Cherry-pick: Graph context menu with confirmation
- Stash: Ctrl+S push, Ctrl+Shift+S pop, sidebar context menu for Apply/Pop/Drop
- Clipboard: Copy SHA to system clipboard via arboard
- Rounded corners on buttons, pills, inputs, dialogs, context menus, toasts
- Panel backgrounds with 1px borders for depth separation, drag-resizable dividers
- Focused panel indicator (2px accent-colored top border)
- Context-sensitive shortcut bar with key pills below the header (toggleable)
- Header bar with branch name pill, primary Commit button, ghost secondary buttons, drop shadow
- Scrollbars with proportional thumb, drag support, and accent hover color
- Hover highlighting on buttons, sidebar items, file list items, and graph rows
- Cursor blinking in text inputs at approximately 1Hz, accent border on focus
- Empty state messages ("Working tree clean" with a checkmark)
- Colored file status dots (green for Added, yellow for Modified, red for Deleted)
- Confirmation dialogs for all destructive operations
| Key | Action |
|---|---|
Ctrl+O |
Open a new repository tab |
Ctrl+W |
Close the current tab |
Ctrl+Tab |
Switch to the next tab |
Ctrl+Shift+Tab |
Switch to the previous tab |
Tab |
Cycle focus: Graph -> Staging -> Sidebar -> Graph |
Ctrl+S |
Stash push (when text input not focused) |
Ctrl+Shift+S |
Stash pop |
Escape |
Close diff view, then commit detail, then exit |
| Key | Action |
|---|---|
j / k |
Navigate commits up/down |
PageUp / PageDown |
Navigate commits by page |
Enter |
Select commit (view details and diff) |
Ctrl+F or / |
Open search/filter bar |
| Right-click | Context menu: Copy SHA, View Details, Checkout, Create Branch, Create Tag, Cherry-pick, Revert, Reset |
| Key | Action |
|---|---|
j / k |
Navigate items up/down (with auto-scroll) |
PageUp / PageDown |
Navigate by page |
Enter |
Checkout branch / Apply stash / Jump to worktree branch |
d |
Delete the selected branch |
| Right-click | Context menu varies by item type |
| Key | Action |
|---|---|
Tab |
Cycle between subject, body, staged list, unstaged list |
Ctrl+Enter |
Create commit with current message |
Ctrl+Shift+A |
Toggle amend mode |
| Double-click file | Stage/unstage individual file |
| Right-click | Context menu: Stage/Unstage, View Diff, Discard |
| Key | Action |
|---|---|
Shift+ScrollWheel |
Horizontal scroll |
Left / Right |
Horizontal scroll |
ScrollWheel |
Vertical scroll |
| Key | Action |
|---|---|
j / Down |
Move selection down |
k / Up |
Move selection up |
Enter / Space |
Activate selected item |
Escape |
Close menu |
cd main
cargo build --release- Rust 2024 edition
- Vulkan-capable GPU with drivers installed
- System font:
/usr/share/fonts/TTF/Roboto-Regular.ttf - Linux (tested on Arch Linux)
| Crate | Version | Purpose |
|---|---|---|
| vulkano | 0.35 | Vulkan rendering |
| vulkano-shaders | 0.35 | GLSL shader compilation |
| winit | 0.30 | Window creation and event loop |
| git2 | 0.20 | Git operations (libgit2 bindings) |
| fontdue | 0.9 | Font rasterization for SDF atlas |
| image | 0.25 | PNG/JPEG encoding for screenshots and avatars |
| ureq | 2 | HTTP client for Gravatar downloads |
| md5 | 0.7 | MD5 hashing for Gravatar email lookup |
| notify | 8 | Filesystem watching for automatic refresh |
| rfd | 0.15 | Native file picker dialogs |
| bytemuck | 1.21 | Safe transmute for vertex data |
| anyhow | 1.0 | Error handling |
| half | 2.4 | f16 conversion for AMD swapchain formats |
| serde / serde_json | 1 | Settings persistence to JSON |
| arboard | 3 | System clipboard access |
# Open the current directory
cargo run
# Open a specific repository
cargo run -- /path/to/repo
# Open multiple repositories (one tab each)
cargo run -- /path/to/repo1 /path/to/repo2
# Screenshot mode (renders and captures to PNG, then exits)
cargo run -- --screenshot output.png
# Screenshot at specific resolution (offscreen rendering)
cargo run -- --screenshot output.png --size 1920x1080
cargo run -- --screenshot output.png --size 3840x2160
# Screenshot with a specific UI state
cargo run -- --screenshot output.png --screenshot-state search
cargo run -- --screenshot output.png --screenshot-state context-menu
cargo run -- --screenshot output.png --screenshot-state commit-detail
cargo run -- --screenshot output.png --screenshot-state open-dialog
# Specify render scale for screenshots
cargo run -- --screenshot output.png --scale 2.0src/
├── main.rs # App struct, event loop, draw pipeline, CLI (~2,850 lines)
├── git.rs # Git operations (git2 + CLI wrappers, ~1,330 lines)
├── config.rs # Settings persistence (serde_json → ~/.config/whisper-git/)
├── input/
│ ├── mod.rs # InputState, InputEvent types
│ ├── keyboard.rs # Key definitions and modifier tracking
│ └── mouse.rs # Mouse button and position state
├── renderer/
│ ├── mod.rs # Module exports
│ ├── context.rs # VulkanContext: device, queue, allocators
│ ├── surface.rs # Swapchain and framebuffer management
│ ├── screenshot.rs # Screenshot capture to PNG
│ └── offscreen.rs # Offscreen render target for controlled-size captures
├── ui/
│ ├── mod.rs # Module exports, Color, Rect
│ ├── text.rs # Font atlas text renderer (TextVertex, TextRenderer)
│ ├── spline.rs # Bezier curve and line renderer (SplineVertex, SplineRenderer)
│ ├── avatar.rs # Gravatar download, disk cache, GPU atlas (AvatarCache, AvatarRenderer)
│ ├── widget.rs # Widget trait, WidgetState, theme constants
│ ├── layout/
│ │ ├── mod.rs # Rect primitives with rectangle math
│ │ ├── screen.rs # ScreenLayout (header, shortcut bar, sidebar, graph, staging, secondary)
│ │ └── flex.rs # Flex layout system
│ └── widgets/
│ ├── mod.rs # Widget re-exports
│ ├── button.rs # Clickable button with hover/press states
│ ├── context_menu.rs # Right-click popup overlay with keyboard nav
│ ├── file_list.rs # File list with staging toggle and status dots
│ ├── header_bar.rs # Top bar: branch pill, Fetch/Pull/Push/Commit buttons, drop shadow
│ ├── label.rs # Text label
│ ├── panel.rs # Container widget
│ ├── repo_dialog.rs # Modal dialog for opening repositories
│ ├── scrollbar.rs # Proportional scrollbar with drag support
│ ├── search_bar.rs # Search/filter input bar
│ ├── settings_dialog.rs # Settings modal (avatars, scroll speed, row size)
│ ├── shortcut_bar.rs # Context-sensitive keyboard shortcut hints
│ ├── tab_bar.rs # Tab bar for multi-repository support
│ ├── text_area.rs # Multi-line text editor
│ ├── text_input.rs # Single-line text input with cursor
│ ├── branch_name_dialog.rs # Branch/tag creation name input modal
│ ├── confirm_dialog.rs # Confirmation dialog for destructive operations
│ └── toast.rs # Toast notification manager
└── views/
├── mod.rs # View re-exports
├── branch_sidebar.rs # Sidebar: branches/tags/submodules/worktrees/stashes (~1,415 lines)
├── commit_detail.rs # Full commit metadata and file list
├── commit_graph.rs # Commit graph with spline branches and search (~1,504 lines)
├── diff_view.rs # Color-coded diff with word-level highlights
├── secondary_repos.rs # (Legacy) Submodule/worktree cards - data moved to sidebar
└── staging_well.rs # Staging panel with commit message editor + amend mode
The screen is divided into drag-resizable regions by ScreenLayout:
┌──────────────────────────────────────────────────────────┐
│ [Tab Bar] (only visible when multiple tabs are open) │
├──────────────────────────────────────────────────────────┤
│ [Header Bar] branch pill | Fetch Pull Push | Commit ?= │
├──────────────────────────────────────────────────────────┤
│ [Shortcut Bar] context-sensitive key pills (toggleable) │
├─────────┬──────────────────────┬─────────────────────────┤
│ Branch │ │ Staging Well │
│ Sidebar │ Commit Graph │ (subject, body, │
│ LOCAL │ (drag-resizable) │ staged/unstaged) │
│ REMOTE │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤
│ TAGS │ │ Diff / Detail View │
│ SUBMODS │ │ (drag-resizable │
│ WORKTRS │ │ vertical split) │
│ STASHES │ │ │
├─────────┴──────────────────────┴─────────────────────────┤
│ [Toast Notifications] (bottom-center overlay) │
└──────────────────────────────────────────────────────────┘
Panel dividers are drag-resizable with configurable ratios (sidebar 5-30%, graph 30-80%, staging 15-85%).
Each frame generates vertex data through an immediate-mode pattern with three z-ordered layers:
- Views and widgets produce
WidgetOutputcontainingtext_vertices,spline_vertices, andavatar_vertices - Outputs are collected into three layers for correct z-ordering:
- Graph layer: panel backgrounds + commit graph (splines, nodes, pills, text)
- Chrome layer: header bar, shortcut bar, sidebar, staging well, diff viewer
- Overlay layer: context menus, toasts, confirmation dialogs, modal dialogs
- Each layer renders three passes in order:
- Spline pass: backgrounds, borders, shapes, graph lines, rounded rects
- Avatar pass: Gravatar images from the avatar atlas
- Text pass: all text content from the font atlas
- Repository access via
git2(libgit2 Rust bindings) - Remote operations (fetch, pull, push) shell out to the
gitCLI in background threads usingstd::thread+mpsc::channel - Hunk staging/unstaging uses
git apply --cachedvia CLI - File discard uses
git2::Repository::checkout_head()with force
Whisper Git handles the common bare-repo-with-worktrees layout:
whisper-git/
├── .bare/ # Bare git repository
├── .git # File pointing to .bare/
├── main/ # Main branch worktree
└── feature-x/ # Feature branch worktree
The GitRepo::open() function includes fallback logic: if HEAD points to a stale branch (common in bare repos), it walks local branch tips to find valid commits.
This project uses git worktrees for parallel development:
cd whisper-git
git worktree add feature-name -b feature-nameThe --screenshot flag renders the UI and captures it to a PNG file without requiring interactive use. This is useful for CI pipelines and for providing visual context to LLM-assisted development tools.
# Basic screenshot
cargo run -- --screenshot output.png --size 1920x1080
# Screenshot with injected UI state
cargo run -- --screenshot output.png --size 1920x1080 --screenshot-state commit-detailAvailable screenshot states: open-dialog, search, context-menu, commit-detail.
- docs/render_engine.md -- Rendering architecture, Vulkan pipeline, vertex generation
- docs/ux-design-2026-02.md -- UI/UX specification and design rationale
- docs/user_needs.md -- Core user needs and feature priorities
- docs/design_feedback_feb2026.md -- Design review and strategic recommendations
TBD