Lightweight, Windows-first desktop Git client. Tauri v2 + React UI, Rust core, and system-installed Git. No AI, cloud patches, PR/issue panel, or arbitrary shell/Git commands.
Status: functional MVP.
tauri devworks with real repositories; the standalone Vite development page uses a built-in demo data source.
- Start page when no repository is open: searchable recent repositories with per-entry removal, plus Open, Clone, and Create actions. Create supports a target path, default branch name, and a
.gitignoretemplate; hosted providers are listed but not yet available. - Repository tabs in folders or ungrouped: drag and drop, app-owned context actions, aliases, browser-style switching, automatic restoration, and reopening the most recently closed tab.
- Tabs whose folder moved or is no longer a Git repository open a dedicated unavailable-repository page with retry, locate, and close actions instead of failing silently.
- LOCAL, REMOTE, and TAGS sidebar with filtering, a current-branch marker,
/-segment folders for local branches, remote-grouped remote branches with owner avatars, and a right-click branch menu for pull, push, branch creation, rename, safe deletion, and name copy. - Double-clicking a remote branch checks it out directly as a local tracking branch, with no intermediate name prompt.
- Compact, column-aligned commit DAG with colored lanes, relative time markers behind the lanes, WIP pseudo-node connected to HEAD, initials avatars, arrow-key stepping between the WIP row and history, and loading of older commits.
- Lanes and lane colors follow the order the lines appear in the list, so checking out another branch never moves a branch sideways or repaints it. A branch keeps its color where its first-parent history continues, and lines visible at the same time never share a color.
- Ref labels, row highlight, and the WIP node take the color of the branch they belong to; the default palette is the ten-color GitLens lane set.
- Stash entries collapse into a single graph row each instead of the raw index/untracked helper commits, and are drawn as a dashed line in their own color.
- Double-click a local branch label in the graph to check that branch out.
Ctrl+Fsearch across commit subjects and full description/body text; matches stay highlighted while the rest of the graph dims.- Graph rows show the commit description under the subject; commit details list
Co-authored-bytrailers as separate authors. - Commit details: click-to-copy SHA with full-object tooltip, author, timestamp, parents, statistics, Path/Tree changed files, and in-place commit message editing (reword).
- GitKraken-style structured diff with three view modes - hunk, inline, and split - persisted across restarts, plus line numbers and rename/mode/binary/truncation states. Split panes scroll independently and size to their own content. The diff opens in place of the graph and is closed from its header or with
Esc; there is no separate view tab bar. - Syntax highlighting in diffs (Shiki-based tokenization) and a change map next to whole-file diffs for jumping between modified regions. Highlighting survives silent background reloads without flicker.
- WIP/working tree: separate collapsible staged/unstaged trees, optimistic staging with rollback on failure, per-file or bulk actions, separate summary and description fields with a 72-character counter on the summary, amend, sign-off, and discard-all.
- Changed-file context menu: stage/unstage, discard, ignore the file, extension, or folder, stash a single file, copy the path, and save a patch.
- Push and pull quick actions carrying ahead/behind counts, autostash-backed pull for dirty worktrees, stash push and pop, and explicit pull modes: merge, fast-forward only, or rebase. Fetch and refresh are keybind-driven (
Ctrl+L,F5). - Commit context menu: detached checkout, branch/tag creation, cherry-pick, revert, a reset submenu (soft, mixed, hard), and full SHA copy.
- Continue, skip, or abort an in-progress merge/rebase/cherry-pick/revert from an operation banner that names the commit the operation stopped on and shows the rebase position.
- Read-only merge-conflict preflight plus an operation-aware Base/Ours/Theirs/result editor, guarded side selection, delete/stage actions, and conservative Git
rererereuse. - Bulk conflict resolution: mark every conflicted file resolved or take one side, for all conflicts or for a single folder.
- Automatic refresh: the active repository's worktree and
.gitmetadata are watched on disk, so commits, checkouts, and editor saves made outside GitCat appear without a manual refresh. - Auto-fetch when a repository is opened and then on a timer (1 minute by default,
0disables, 60 maximum) keeps ahead/behind counts and remote branches current. It runs silently in the background: no toasts, no blocked toolbar, and failures stay quiet. Switching back to an already-fetched tab reuses the last result until the interval elapses. - Resizable panels, a persisted Path/Tree changed-files view mode, and customizable semantic UI and diff colors plus all ten graph lane colors, each resettable on its own.
- Hideable side panels, window-centered repository actions, configurable command keybinds, and persistent footer build identity.
- Window size, position, and maximized state are restored on the next launch.
Keyboard shortcuts:
Ctrl+Tab/Ctrl+Shift+Tab: next / previous repositoryCtrl+1…Ctrl+9: select repository by visual orderCtrl+T/Ctrl+W/Ctrl+Shift+T: open a new repository tab / close active repository / reopen the last closed repositoryCtrl+Shift+O: open repositoryAlt+O: open the active repository's folder in the file explorerCtrl+F: search commitsCtrl+,: settingsF5/Ctrl+L: refresh repository / fetchCtrl+J/Ctrl+K: toggle left / right panelCtrl+Shift+S/Ctrl+Shift+U: stage all / unstage allCtrl+Enter: commit from the working-tree panelEsc: close the open diff, then any open context menu- With the graph focused:
↑,↓,Home,End,Enter,Shift+F10
All registered shortcuts, including network, branch, stash, diff, conflict, and operation commands, can be changed or cleared under Preferences → Keybinds. See UX implementation notes for the complete default table.
React 19 + TypeScript + Tailwind CSS 4
|
typed GitCatApi
|
Tauri v2 invoke commands
|
gitcat-core
registry + repository locks
|
GitBackend trait
|
gitcat-git-cli
|
system Git
Workspace:
apps/desktop: Vite/React UI, Tauri v2 adapter, and the single-repository filesystem watcher.crates/gitcat-contracts: Serde DTOs, enums, and stable API errors.crates/gitcat-core: repository registry, operation serialization, DAG layout, and persistent workspace/settings.crates/gitcat-git-cli: safe system Git runner and porcelain/plumbing parsers.
Using system Git is intentional: it preserves Git Credential Manager, SSH agents, hooks, signing, filters, and user Git configuration.
- Git 2.31+
- Rust 1.85+; Tauri Windows/MSVC prerequisites and WebView2 for native Windows builds
- Node.js 22 LTS and npm
Windows 10/11 is the primary target. Other platforms are neither packaged nor verified in this MVP.
Frontend dependencies:
cd .\apps\desktop
npm.cmd installReal native GitCat:
npm.cmd run tauri devUI only, with demo data:
npm.cmd run devThe Vite page does not access the file system or real repositories. Native Git operations always require tauri dev.
scripts/build-all.ps1 runs the whole pipeline in order: frontend dependency install, cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace, TypeScript typecheck, and finally npm run tauri build (which also produces the Vite web build and the native installers). It stops at the first failing step and exits with that step's exit code.
cd .\apps\desktop
npm.cmd run build:allFlags:
-SkipInstall: do not runnpm ci/npm installfirst.-SkipVerify: skip fmt, clippy, tests, and typecheck; build only.-NoBundle: build the release binary without MSI/NSIS installers (faster).
Outputs: apps/desktop/dist (web), target/release/gitcat-desktop.exe (binary), target/release/bundle (installers).
The individual steps are also available separately.
Rust workspace:
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceWindows helper for the same checks:
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\verify.ps1Frontend:
cd .\apps\desktop
npm.cmd run typecheck
npm.cmd run buildNative release and installer packages:
cd .\apps\desktop
npm.cmd run tauri buildThe web build is written to apps/desktop/dist; native artifacts are written under Cargo's target/release directory.
The current version is 1.1.0. .github/workflows/release-windows.yml (workflow_dispatch) builds the Windows release on windows-latest: it enforces the x86_64-pc-windows-msvc host, runs fmt, clippy, tests, and typecheck, then bundles the NSIS installer and uploads the installer plus the binary as an artifact.
The build is verified to be self-contained: the job fails if gitcat-desktop.exe still imports WebView2Loader.dll or if a dynamic loader DLL is left in the release output, and it prints the installer's SHA-256.
- Git runs directly as a
tokio::process::Commandprocess; there is no shell and no general-purposerun_git(args)IPC. - The UI passes a path only when opening a repository. Subsequent calls use a registered, UUID-based repository ID.
- Ref names are validated by Git; revisions are resolved to full object IDs before mutations.
- Pathspec arguments are passed literally after
--. - Conflict-editor writes reject stale index stages or externally changed worktree content, preserve line endings, and atomically replace files before staging.
- External diff tools and textconv are disabled for read-only diffs.
- Allowed remote protocols:
file,git,http,https,ssh; custom remote helpers are disabled. - Credential prompts are disabled. A preconfigured Git Credential Manager or SSH agent is required.
- Auto-fetch is the only unattended network operation, it only ever runs
git fetchon the active repository, and it is turned off by setting the interval to0. reset --hard, discarding changes, forced branch deletion, and stash drop require explicit confirmation plus a current matching snapshot. The core rejects stale dialogs. Destructive branch deletion is confirmed inline in the top bar instead of a modal.- Discarding a file that another process holds open fails with an explicit "file is in use" message instead of a generic Git error.
- Rewording a commit is guarded by the same snapshot check, so it is rejected if the branch moved underneath the panel.
- The filesystem watcher observes one repository - the active one - ignores
.git/objectsand.git/lfschurn, debounces bursts, and only asks the UI to reload. It never runs Git on its own. - GitCat does not modify the global
safe.directoryvalue or delete.git/index.lock. - The Tauri main window receives only core and directory-open permissions; CSP blocks external object/frame/form content.
- Clone and create are local-only: hosted providers (GitHub, GitLab, Bitbucket, Azure DevOps) are shown in the create dialog but disabled.
- A remote/upstream editor and annotated-tag message UI are not yet available; the core/IPC already partially supports them.
- Stashing is limited to push and popping the latest entry from the toolbar. Applying or dropping an arbitrary stash has core/IPC support but no panel.
- Network operations have no progress or cancel UI; the Tauri adapter currently creates its own cancellation token for each call.
- Diffs are line-level: syntax highlighting is available, word-level diffs are not.
- There is no built-in credential dialog or terminal.
- Hosted provider profile pictures are not fetched without provider authentication; initials are used as the avatar fallback.
Detailed contracts: Core API, Tauri integration, GitKraken UX research, and UX implementation notes.