Git genealogy, untangled. A TUI for navigating commit graphs with color and clarity.
Rust
811
197 commits
updated Oct 12, 2026
See your branches. Follow your changes. Stay in the terminal.
keifu (系譜, /keːɸɯ/, “genealogy”) is a Git TUI for working across branches. Explore a color-coded commit graph, inspect diffs, and stage, commit, and push changes with the keyboard or mouse.

The pane-preserving diff layout and drag-to-copy shown or described below are available in v0.7.0 and later.
cargo install keifu
mise use -g github:trasta298/keifu@latest
brew install trasta298/tap/keifu
git clone https://github.com/trasta298/keifu
cd keifu
cargo install --path .
Run inside a Git repository (or one of its subdirectories):
keifu
↑ / ↓ or j / k, or click a row.Space to select a changed file, then Enter to open its diff.Esc to go back. Use / to find a branch, and ? for help.You need a terminal with Unicode and color support, and git in your PATH
for fetch/push. Cargo installation and source builds also need the Rust toolchain.
See added and removed lines, syntax highlighting, and changes within a line.
Use n / N to move between files and ] / [ to jump between hunks.

File diffs open fullscreen by default. The layout above keeps commit details and the file list visible:
keifu --file-view replace
Select uncommitted changes, press Space, then use s to stage or unstage
a file. a stages everything; u unstages everything. Press c to write a
commit message, then p from the graph to push the current branch to origin.

Staging is per file. A commit includes only staged changes.
Press / and type part of a branch name. Fuzzy search filters the dropdown as
you type; Enter jumps to the selected result in the graph. Press Enter
again from the graph to check it out.

On narrow terminals, the detail panes stack vertically and less essential commit metadata is hidden to leave room for the graph and messages.
Click a commit or file to select it; double-click to open its files or diff. Scroll the pane under the pointer, or click the action hints in the status bar. Drag across visible text within a pane and release to copy it via OSC 52 (requires terminal clipboard support).
Set defaults in ~/.config/keifu/config.toml:
[ui]
file_view = "replace"
By default, keifu refreshes local state every 10 seconds and fetches from origin every 60 seconds. See the configuration guide to adjust or disable automatic updates, or change remote and tag visibility.
Press ? in the app for help.
| Key | Action |
|---|---|
j / ↓ | Move down (scrolls the detail pane when focused) |
k / ↑ | Move up (scrolls the detail pane when focused) |
Tab | Switch pane focus (graph / commit detail) |
] | Jump to next commit that has branch labels |
[ | Jump to previous commit that has branch labels |
h / ← | Select left branch (same commit) |
l / → | Select right branch (same commit) |
Ctrl+d | Page down |
Ctrl+u | Page up |
g / Home | Go to top |
G / End | Go to bottom |
@ | Jump to HEAD (current branch) |
Space | Open changed file list |
| Key | Action |
|---|---|
Enter | Checkout selected branch/commit |
b | Create branch at selected commit |
d | Delete branch (local, non-HEAD) |
f | Fetch from origin |
c | Commit staged changes (opens message dialog) |
p | Push current branch to origin |
Staging keys work when the "uncommitted changes" row is selected.
| Key | Action |
|---|---|
j / k | Select file |
Enter | Open file diff |
s | Stage / unstage selected file |
a | Stage all changes |
u | Unstage all changes |
c | Commit staged changes |
Esc / q | Back |
| Input | Action |
|---|---|
| Click on a commit row | Select commit (double-click opens the file list) |
| Click on a file row | Select file (double-click opens the diff) |
| Click on a pane | Focus the pane |
| Click on a status bar hint | Run that action |
| Wheel scroll | Scrolls the pane under the cursor |
| Left drag | Select visible text within a pane; release to copy (OSC 52) |
Clicks and double-clicks run on release, so dragging does not activate them.
Selection covers visible text only; scrolling or changing the view clears it.
Your terminal's native selection remains available with its modifier
(usually Shift + drag; Fn + drag on iTerm2).
Note: Ghostty currently fans one wheel notch out into multiple scroll events
for mouse-mode apps (ghostty#3955),
which can scroll a few extra lines per notch. Lowering mouse-scroll-multiplier
in the Ghostty config works around it.
| Key | Action |
|---|---|
/ | Search branches (incremental fuzzy search) |
↑ / Ctrl+k | Select previous result |
↓ / Ctrl+j | Select next result |
Enter | Jump to selected branch |
Esc / Backspace on empty | Cancel search |
| Key | Action |
|---|---|
j / k / ↑ / ↓ | Scroll up/down |
h / l / ← / → | Scroll left/right |
Ctrl+d / Ctrl+u | Half-page down/up |
Ctrl+f / Ctrl+b | Full page down/up |
g / G | Go to top/bottom |
0 | Scroll to line start |
] / [ | Jump to next/previous hunk |
n / N | Jump to next/previous file |
Esc / q | Back to file select / close |
| Key | Action |
|---|---|
y | Copy commit hash to clipboard (OSC 52) |
Y | Copy branch name to clipboard (OSC 52) |
R | Refresh repository data |
o | Toggle remote branches |
t | Toggle tags |
? | Toggle help |
q / Esc | Quit (returns focus to the graph first when the detail pane is focused) |
+N count of other branch labels (e.g., [main ↔ origin, origin_2, origin_3 +1]). A local branch and all same-named remote branches at that commit count as one label. Matching remote names are listed alphabetically after ↔ in both the collapsed label and the branch popup, including unselected branches. Remote branches at different commits or without a matching local branch remain separate. Use h/l or ←/→ to switch between labels.origin/xxx creates or updates a local branch. Upstream is set only when creating a new branch. If the local branch exists but points to a different commit, it is force-updated to match the remote.o to hide them; when hidden, commits reachable only from remote branches are excluded from the graph.t to hide them.origin remote to be configured. Staging works per file (no hunk-level staging); commits include only staged changes, like plain git commit.See debugging.md for file logging and the remote-control debug server, and screenshots/README.md to recreate the demo repository and screenshots.
MIT
(top 24 of 28)
419 followers · starred Mar 2026
269 followers · starred Jan 2026
170 followers · starred Jan 2026
138 followers · starred Jan 2026
Git genealogy, untangled. A TUI for navigating commit graphs with color and clarity.
Rust
811
197 commits
updated Oct 12, 2026
See your branches. Follow your changes. Stay in the terminal.
keifu (系譜, /keːɸɯ/, “genealogy”) is a Git TUI for working across branches. Explore a color-coded commit graph, inspect diffs, and stage, commit, and push changes with the keyboard or mouse.

The pane-preserving diff layout and drag-to-copy shown or described below are available in v0.7.0 and later.
cargo install keifu
mise use -g github:trasta298/keifu@latest
brew install trasta298/tap/keifu
git clone https://github.com/trasta298/keifu
cd keifu
cargo install --path .
Run inside a Git repository (or one of its subdirectories):
keifu
↑ / ↓ or j / k, or click a row.Space to select a changed file, then Enter to open its diff.Esc to go back. Use / to find a branch, and ? for help.You need a terminal with Unicode and color support, and git in your PATH
for fetch/push. Cargo installation and source builds also need the Rust toolchain.
See added and removed lines, syntax highlighting, and changes within a line.
Use n / N to move between files and ] / [ to jump between hunks.

File diffs open fullscreen by default. The layout above keeps commit details and the file list visible:
keifu --file-view replace
Select uncommitted changes, press Space, then use s to stage or unstage
a file. a stages everything; u unstages everything. Press c to write a
commit message, then p from the graph to push the current branch to origin.

Staging is per file. A commit includes only staged changes.
Press / and type part of a branch name. Fuzzy search filters the dropdown as
you type; Enter jumps to the selected result in the graph. Press Enter
again from the graph to check it out.

On narrow terminals, the detail panes stack vertically and less essential commit metadata is hidden to leave room for the graph and messages.
Click a commit or file to select it; double-click to open its files or diff. Scroll the pane under the pointer, or click the action hints in the status bar. Drag across visible text within a pane and release to copy it via OSC 52 (requires terminal clipboard support).
Set defaults in ~/.config/keifu/config.toml:
[ui]
file_view = "replace"
By default, keifu refreshes local state every 10 seconds and fetches from origin every 60 seconds. See the configuration guide to adjust or disable automatic updates, or change remote and tag visibility.
Press ? in the app for help.
| Key | Action |
|---|---|
j / ↓ | Move down (scrolls the detail pane when focused) |
k / ↑ | Move up (scrolls the detail pane when focused) |
Tab | Switch pane focus (graph / commit detail) |
] | Jump to next commit that has branch labels |
[ | Jump to previous commit that has branch labels |
h / ← | Select left branch (same commit) |
l / → | Select right branch (same commit) |
Ctrl+d | Page down |
Ctrl+u | Page up |
g / Home | Go to top |
G / End | Go to bottom |
@ | Jump to HEAD (current branch) |
Space | Open changed file list |
| Key | Action |
|---|---|
Enter | Checkout selected branch/commit |
b | Create branch at selected commit |
d | Delete branch (local, non-HEAD) |
f | Fetch from origin |
c | Commit staged changes (opens message dialog) |
p | Push current branch to origin |
Staging keys work when the "uncommitted changes" row is selected.
| Key | Action |
|---|---|
j / k | Select file |
Enter | Open file diff |
s | Stage / unstage selected file |
a | Stage all changes |
u | Unstage all changes |
c | Commit staged changes |
Esc / q | Back |
| Input | Action |
|---|---|
| Click on a commit row | Select commit (double-click opens the file list) |
| Click on a file row | Select file (double-click opens the diff) |
| Click on a pane | Focus the pane |
| Click on a status bar hint | Run that action |
| Wheel scroll | Scrolls the pane under the cursor |
| Left drag | Select visible text within a pane; release to copy (OSC 52) |
Clicks and double-clicks run on release, so dragging does not activate them.
Selection covers visible text only; scrolling or changing the view clears it.
Your terminal's native selection remains available with its modifier
(usually Shift + drag; Fn + drag on iTerm2).
Note: Ghostty currently fans one wheel notch out into multiple scroll events
for mouse-mode apps (ghostty#3955),
which can scroll a few extra lines per notch. Lowering mouse-scroll-multiplier
in the Ghostty config works around it.
| Key | Action |
|---|---|
/ | Search branches (incremental fuzzy search) |
↑ / Ctrl+k | Select previous result |
↓ / Ctrl+j | Select next result |
Enter | Jump to selected branch |
Esc / Backspace on empty | Cancel search |
| Key | Action |
|---|---|
j / k / ↑ / ↓ | Scroll up/down |
h / l / ← / → | Scroll left/right |
Ctrl+d / Ctrl+u | Half-page down/up |
Ctrl+f / Ctrl+b | Full page down/up |
g / G | Go to top/bottom |
0 | Scroll to line start |
] / [ | Jump to next/previous hunk |
n / N | Jump to next/previous file |
Esc / q | Back to file select / close |
| Key | Action |
|---|---|
y | Copy commit hash to clipboard (OSC 52) |
Y | Copy branch name to clipboard (OSC 52) |
R | Refresh repository data |
o | Toggle remote branches |
t | Toggle tags |
? | Toggle help |
q / Esc | Quit (returns focus to the graph first when the detail pane is focused) |
+N count of other branch labels (e.g., [main ↔ origin, origin_2, origin_3 +1]). A local branch and all same-named remote branches at that commit count as one label. Matching remote names are listed alphabetically after ↔ in both the collapsed label and the branch popup, including unselected branches. Remote branches at different commits or without a matching local branch remain separate. Use h/l or ←/→ to switch between labels.origin/xxx creates or updates a local branch. Upstream is set only when creating a new branch. If the local branch exists but points to a different commit, it is force-updated to match the remote.o to hide them; when hidden, commits reachable only from remote branches are excluded from the graph.t to hide them.origin remote to be configured. Staging works per file (no hunk-level staging); commits include only staged changes, like plain git commit.See debugging.md for file logging and the remote-control debug server, and screenshots/README.md to recreate the demo repository and screenshots.
MIT
(top 24 of 28)
419 followers · starred Mar 2026
269 followers · starred Jan 2026
170 followers · starred Jan 2026
138 followers · starred Jan 2026