A gitk-style repository browser and commit helper built on the Saudade toolkit.
gitj # browse the repository containing the current directory
gitj /path/repo # browse the repository at (or above) a given path
Git Journey has two screens — the gitk-style browse (history) screen and the
git gui-style commit (staging) screen. Switch between them from the
View menu, by double-clicking a working-tree entry in the log, or
automatically: committing drops you back to the log.
Browse screen — gitk-style history with the DAG graph, ref badges and a
git show-style detail/diff pane:
Commit screen — git gui-style staging with unstaged/staged lists, a per-file
diff and the message editor:
cargo install gitj- Commit history with a colored DAG graph column, branch / tag / HEAD ref badges, and author + date columns.
git show-style detail: selecting a commit shows its SHA, refs, author, date, message and full diff; selecting a file narrows the diff to that file.- Diff view with the usual coloring — green additions, red deletions, blue hunk headers, gray file headers.
- Working-tree entries: when there are local changes, the log leads with
"Uncommitted changes" / "Staged changes" rows (connected into the graph at
HEAD). Selecting one previews its files and diff; double-clicking it opens the commit screen. - Search / filter the history live by message, author, ref or SHA.
- Unstaged and Staged file lists (à la
git gui). Double-click a file to stage / unstage it, or use the Stage / Unstage buttons. - The diff pane shows the selected file's change — working-tree-vs-index
for unstaged files, index-vs-
HEADfor staged ones. - Revert / discard an unstaged change (
git gui's Revert Changes, Ctrl+J): a tracked file is reset to its index copy, while an untracked file — having nothing to revert to — is offered up for deletion instead. Either way a confirm dialog guards the irreversible discard. - A multi-line message editor and a Commit button.
- Amend last commit: ticking the box pre-fills the editor with
HEAD's message and re-bases the staging view onHEAD's parent, so the changes already in the last commit show up as staged. Unstage any of them to drop them from the amended commit; committing then rewritesHEADrather than adding a new commit. - Rescan re-reads the working tree. Committing returns to the log view, which now shows the new commit.
- Keyboard shortcuts mirror
git gui(and are shown next to each Commit menu item): Ctrl+Enter commits, Ctrl+T stages the selected file, Ctrl+I stages everything, Ctrl+J reverts (or deletes) the selected unstaged file, Ctrl+S appends aSigned-off-bytrailer, Ctrl+R rescans, and the message editor takes the usual Ctrl+C / X / V / A. Ctrl+Q quits from either screen.
- Menu bar (File ▸ Reload / Exit, View ▸ switch screen, Help ▸ About) with Alt-accelerators and a modal About / error dialog.
- Keyboard navigation: Tab cycles the panes, arrows/PageUp/Down drive the focused list or scroll the diff.
The UI never touches git2 directly — it goes through a small backend
abstraction, which keeps everything testable without a live repository.
| Module | Contents |
|---|---|
backend |
RepoBackend trait + data types (CommitInfo, FileChange, Diff/DiffLine, RefLabel, WorkingStatus). Browse reads history/diffs; commit mode adds working-tree status, per-file diffs, stage/unstage, revert/delete_untracked, commit (with amend). Implementations: Git2Backend (live, libgit2) and FixtureBackend (deterministic, in-memory, with a simulated working tree). |
widgets |
git-specific widgets — CommitList (graph + badges + columns), DiffView (colored diff), SearchBar, Heading, graph (DAG lane assignment); Shell, a generic flat-focus container, plus a layout module giving the browse and commit screens their rectangles; generic Shared<W> adapter. |
ui |
GitClient, the top-level widget. It owns both screens (a Shell each), switches between them, and — since saudade widgets are callback-free — polls selections and a small command queue after each event to rebuild dependent panes. |
- Pixel snapshots (
tests/snapshots.rs) render the real UI through saudade's offscreenMockBackendat 1.0× against the in-memoryFixtureBackendand bundled DejaVu fonts, comparing PNG bytes withinsta. Regenerate withINSTA_UPDATE=always cargo test --test snapshots, then review withcargo insta review. tests/git2_backend.rsbuilds a throwaway repository with fixed signatures/timestamps and reads it back throughGit2Backend, so the live backend is covered deterministically.tests/commit_backend.rsexercises commit mode end to end: it stages, unstages, reverts, commits and amends in a throwaway repository (and against the fixture), asserting the working-tree status at each step.tests/shortcuts.rsdrives a realGitClientthrough synthetic key events (Ctrl+T / I / J / Enter / Q) and asserts the resulting working-tree and commit state — the runtime path minus the windowing.- Unit tests cover the graph lane algorithm and date formatting.
cargo test # everything
cargo build # the binary

