Git Keizu
View your Git history as a graph, and do common Git actions directly from it

Git Keizu is a focused Git history graph for VS Code. Explore branches, commits, stashes, tags, and uncommitted changes in one graph. Run common Git actions and manage worktrees without opening a terminal.

Git Keizu is an actively maintained fork of Git Graph, intentionally focused on the core graph experience.
English & Japanese UI / 英語・日本語UI対応
Git Keizu follows VS Code's display language. The interface is in English by default and switches to Japanese automatically when the display language is Japanese — commands, settings, menus, dialogs, error messages, and dates. Other display languages fall back to English.
Git Keizuの表示はVS Codeの表示言語に従います。通常は英語で表示され、表示言語を日本語にすると、コマンド、設定項目、メニュー、ダイアログ、エラーメッセージ、日付表示まで自動的に日本語へ切り替わります。追加の設定は不要です。
Why Git Keizu
- Worktrees live in the graph — create a worktree from a local branch or any commit, then open, reveal, or remove it from its label. Linked and detached-HEAD worktrees stay visible.
- Follow one file through history — Highlight File History traces a file back across renames and merges and highlights its commits without hiding the rest of the graph.
- Decide before you delete — Branch Cleanup lays out the facts for every local branch, and a rejected deletion explains why Git refused, including after squash merges.
- Stays out of your way — Git operations refresh the graph without losing your place, context menus remember your recent actions per repository, and busy commits fold extra labels into a +N badge.
Getting Started
Open a folder or workspace that contains a Git repository. On first use, the Git Keizu Status Bar item may not be visible yet. Open the graph using either of these methods:
- Source Control: Open VS Code's built-in Source Control view and click the Git Keizu graph button in the view title.
- Command Palette: Run
Git Keizu: View Git Keizu (git log).

After Git Keizu has been activated and detects a repository, the Status Bar item appears by default and provides a quick way to reopen the graph.
Once the graph is open, try these first:
- Click a commit to see its files and diffs, then Ctrl/Cmd+click another commit to compare the two.
- Right-click a local branch label that has no worktree yet and choose Create Worktree....
- In the commit details, click the history icon on a file's row to start Highlight File History, then press
↑ / ↓ to step through that file's commits.
- Click the Branch Cleanup button in the toolbar to review every local branch in one panel.
Highlights
Understand your repository at a glance
See branches, commits, tags, stash entries, and uncommitted changes together in one graph.

- Filter the graph by branch or author, and search commit messages with regex and case-sensitive modes.
- Choose date, topological, or author-date ordering. Merge commits and non-ancestor commits can be visually muted.
- Combined local and remote labels, automatic commit loading, and restored scroll position keep long histories manageable.
- When a commit carries more branch, worktree, tag, or stash labels than fit in its row, the rest fold into a +N badge that opens them in a list with the same right-click and double-click actions, and Find highlights +N when a hidden label matches.
- Highlight path, from the context menu of a commit or a branch label, traces how it connects through the graph: direct parents and children, ancestors and descendants, or the first-parent line for a commit, and all ancestors or the first-parent line for a branch. Its lines are drawn thicker and its commits outlined while the other lines fade, until you clear it from the bar above the graph. Where the path reaches history that is not loaded yet, the loaded commit is marked with a square instead of guessing what lies beyond.

Inspect changes and compare commits
Select a commit to inspect its files and diffs, or Ctrl/Cmd+click a second commit to compare the two.

- Switch commit files between a folder tree and a flat list; long file rows scroll sideways, so change counts and row actions stay reachable.
- Open working-tree files directly from commit details; renamed files are resolved through Git rename tracking.
- Navigate commits with the keyboard without opening their details, start a comparison with
CTRL/CMD + ENTER, follow parent links, and keep comparison state when switching tabs.
- Highlight File History, started from the history icon on a file's row or from its context menu, follows a single file backwards from a commit — through renames and the merges that touched it — and highlights its commits on the graph without hiding anything else, with previous/next navigation and the file's row highlighted in each commit's details. While it is active,
↑ / ↓ step through the highlighted commits only and open their details, and ESC leaves the highlight once any open commit details are closed.

Run Git actions from the graph
Right-click commits, branches, tags, stash entries, or uncommitted changes to access the actions available for that item.

- Checkout, cherry-pick, merge, rebase, create branches, manage tags, and apply or pop stashes.
- Pull and push the current branch, including choosing an upstream when one has not been configured. Fetch automatically prunes stale remote-tracking references.
- Common actions appear first, while less-used and destructive actions are grouped under More…. Confirmation dialogs expose relevant Git options before execution.
- Branch Cleanup collects every local branch into one panel with the facts needed to decide whether it can be deleted — ancestry against a comparison branch, ahead/behind counts, tree differences, upstream state, worktree usage, and last commit date — then lets you show a branch in the graph, create a worktree for a branch that is not already checked out in one, or open its delete dialog. Those three actions are icons, and the name appears when you hover. It gives no safe-or-unsafe verdict and deletes nothing on its own.
- When a branch deletion is rejected because Git could not confirm the branch is fully merged, the error dialog explains why — including after squash merges and rebases — and what to check before using Force Delete, with the original Git output preserved in a collapsible section.


Manage worktrees visually
Create and manage Git worktrees without leaving the graph.

- Create a worktree from a branch or any commit. The suggested path comes from
worktreePathTemplate (beside the repository, unless you change it) and can be edited before it is created.
- Open a worktree in VS Code or a terminal, reveal it in the file manager, copy its path, or remove it — from the label of a branch-based or a detached-HEAD worktree alike.
- Linked and detached-HEAD worktrees remain visible in the graph, including detached commits outside the loaded history.
- Removal never forces: a worktree with modified or untracked files is left in place and Git's reason is shown.
- After you confirm a removal, Remove Worktree... appears under Recent in the context menu, so the next worktree can be cleaned up from its label in one click; it always asks for confirmation for the worktree you right-clicked.
Designed for everyday use
- Recent context-menu actions are remembered per repository, making repeated workflows quicker.
- Git operations refresh the graph in the background without blanking the view or discarding its state.
- The view stays alive while its tab is in the background, so switching back to Git Keizu is immediate (
retainContextWhenHidden, on by default).
- Every action in the view can be reached from the keyboard:
TAB reaches the toolbar, the commit table, commit details, and panels, CONTEXT MENU or SHIFT + F10 opens a context menu, and focus returns to where you were when a menu or dialog closes.
- Multiple repositories, configurable keyboard shortcuts, optional avatars, graph colours, date formats, and dialog defaults are supported.
- A workspace folder that holds several repositories side by side works too: repositories one level below the folder are discovered automatically, and each Source Control button opens the graph on its own repository.
Requirements
- Git 2.32 or later is required. Viewing the changes contained in a stash entry uses
git stash show -u, whose -u (--include-untracked) option was added in Git 2.32. Older Git versions are not supported.
Reference
Commands
| Command |
Description |
Git Keizu: View Git Keizu (git log) |
Open the Git Keizu graph view |
Git Keizu: Clear Avatar Cache |
Clear all cached commit author avatars |
Keyboard navigation
The keys below are fixed. The shortcuts that can be changed are listed under Settings.
In the commit table, TAB stops only at the current row, marked with a ▸ at its start, followed by that row's labels and +N badge. Other rows are reached with the arrow keys. These keys work while a commit row or one of its labels has focus.
| Key |
Normally |
Two commits compared |
File history highlighted |
↑ / ↓ |
Previous / next row; open details follow |
Previous / next row; details stay as is |
Previous / next matching commit |
SHIFT + ↑ / SHIFT + ↓ |
Previous / next row; details stay as is |
Previous / next row; details stay as is |
Not used |
CTRL/CMD + ↑ / CTRL/CMD + ↓ |
First child / first parent; open details follow |
Not used |
Disabled |
CTRL/CMD + SHIFT + ↑ / CTRL/CMD + SHIFT + ↓ |
Alternative child / alternative parent; open details follow |
Not used |
Disabled |
ENTER |
Open the row's details |
End the comparison and open the row's details |
Open the row's details |
CTRL/CMD + ENTER |
Same as CTRL/CMD + click |
Same as CTRL/CMD + click |
Same as CTRL/CMD + click |
- The arrow keys move the current row and give it focus. Open details follow only when one commit's details are open, so
SHIFT + ↑ / ↓ followed by CTRL/CMD + ENTER starts a comparison without leaving the details. The keys stop at the first and last loaded rows and never load more commits.
- While Highlight File History is active,
↑ / ↓ move only among the matching commits that are already loaded, and work even when no commit details are open. A move opens the commit details of its destination. The keys stop at the first and last of those commits instead of wrapping around.
- The Previous match and Next match buttons on the file history bar stop at the same ends, but do not open commit details.
- While a file history is loading, the arrow keys do not move between commits.
CONTEXT MENU or SHIFT + F10 opens the same menu as a right-click on a commit, a label, a file, or the table header. ENTER or SPACE on a label also opens its menu, and on a +N badge opens its label list. In menus and lists, ↑ / ↓, HOME, and END move, ENTER or SPACE runs a menu item or opens a listed label's menu, → opens a submenu, and ← closes it.
- Buttons and other controls are reached with
TAB and activated with ENTER or SPACE. Dropdowns open with ENTER, SPACE, or ↓, filter as you type, and apply with ENTER; dialogs keep TAB inside the dialog.
ESC closes one item per key press, in this order: context menu, dialog, dropdown, +N label list, Find, commit details, file history. Closing a menu, list, dropdown, Find, or dialog returns focus to the control that opened it. The file history ends — or, while it is still loading, is cancelled — with the same restore as its Exit button.
- The commit table keys above are ignored while the focus is in an editable element, such as the Find input. In inputs, Find, dropdowns, and dialogs handle their own keys, including
ESC.
- Keys used during IME composition do not run actions, and held-down
ENTER, SPACE, and ESC do not repeat their action.
Settings
All settings are under the git-keizu.* namespace.
General
| Setting |
Default |
Description |
dateFormat |
Date & Time |
Date format: Date & Time, Date Only, or Relative |
dateType |
Author Date |
Date type: Author Date or Commit Date |
fetchAvatars |
false |
Fetch commit author avatars from GitHub, GitLab, or Gravatar |
graphColours |
(12 colours) |
Colours used on the graph (HEX, RGB, or RGBA array) |
graphStyle |
rounded |
Graph line style: rounded or angular |
initialLoadCommits |
300 |
Number of commits to initially load |
loadMoreCommits |
100 |
Number of additional commits to load at a time |
loadMoreCommitsAutomatically |
true |
Automatically load more commits when scrolling to the bottom |
openNewTabEditorGroup |
Active |
Editor group for "Open File" in commit details: Active, Beside, One–Nine |
maxDepthOfRepoSearch |
1 |
Maximum depth of subfolders to search for repositories |
retainContextWhenHidden |
true |
Keep the view alive while its tab is hidden so switching back is immediate |
showCurrentBranchByDefault |
false |
Show only the current branch when the graph is opened |
showStatusBarItem |
true |
Show a Status Bar item to open Git Keizu |
menu.showRecentActions |
true |
Show a "Recent" section at the top of context menus when recent actions are available |
showUncommittedChanges |
true |
Show uncommitted changes row in the graph |
tabIconColourTheme |
colour |
Tab icon theme: colour or grey |
sourceCodeProviderIntegrationLocation |
Inline |
SCM title bar button position: Inline or More Actions |
Keyboard Shortcuts (keyboardShortcut*)
| Setting |
Default |
Description |
...Find |
CTRL/CMD + F |
Keyboard shortcut for Find (UNASSIGNED to disable) |
...Refresh |
CTRL/CMD + R |
Keyboard shortcut for Refresh (UNASSIGNED to disable) |
...ScrollToHead |
CTRL/CMD + H |
Keyboard shortcut for Scroll to HEAD (UNASSIGNED to disable) |
...ScrollToStash |
CTRL/CMD + S |
Keyboard shortcut for Scroll to Stash (UNASSIGNED to disable) |
These shortcuts run while focus is on a commit row, a label, or the graph background. The toolbar, inputs, and panels keep the keys for their own use.
Dialog Defaults (dialog.*)
| Setting |
Default |
Description |
dialog.merge.noFastForward |
true |
Default state of "Create a new commit even if fast-forward is possible" (Merge) |
dialog.merge.squashCommits |
false |
Default state of "Squash Commits" checkbox (Merge) |
dialog.merge.noCommit |
false |
Default state of "No Commit" checkbox (Merge) |
dialog.cherryPick.recordOrigin |
false |
Default state of "Record Origin" checkbox (Cherry-pick) |
dialog.cherryPick.noCommit |
false |
Default state of "No Commit" checkbox (Cherry-pick) |
dialog.stashUncommittedChanges.includeUntracked |
false |
Default state of "Include Untracked" checkbox (Stash Uncommitted Changes) |
dialog.createWorktree.openTerminal |
true |
Default state of "Open Terminal" checkbox (Create Worktree) |
dialog.removeWorktree.deleteBranch |
true |
Default state of "Also delete branch" checkbox (Remove Worktree) |
Worktrees (worktreePathTemplate)
| Setting |
Default |
Description |
worktreePathTemplate |
${repoPath}/../${repoName}-${branch} |
Suggested path for a new worktree (see below). |
worktreePathTemplate accepts three placeholders:
| Placeholder |
Expands to |
${repoPath} |
Absolute path of the main worktree |
${repoName} |
The main worktree's directory name |
${branch} |
The branch as one directory: slashes become hyphens, and leading or trailing -, _, and . are dropped |
${repoPath} is the main checkout, including when the graph is open on a linked worktree. A template such as ${repoPath}/.worktrees/${branch} therefore stays under the main worktree instead of nesting another .worktrees directory inside the linked worktree you have open. A leading ~ expands to the home directory, and a relative template resolves against the main worktree. On Windows, a path that names a drive without a root, such as D:worktrees, becomes an absolute path using that drive's working directory, or the drive root when the drive has none. The default places each worktree beside the main checkout. To collect them under one directory instead:
"git-keizu.worktreePathTemplate": "~/.worktrees/${repoName}/${branch}"
The suggestion is shown in the Create Worktree dialog and can be edited before anything is created. Changing the setting updates an open graph, so the next dialog uses the new template. Create Worktree Here keeps the path in step with the branch name until you edit the path. Characters that are awkward in a directory name (/ \ : * ? " < > |, whitespace, and control characters) become -. Runs of -, _, and . collapse, leading and trailing -, _, and . are dropped (-wip- becomes wip), and a name with nothing left becomes worktree. An unknown placeholder is left as written.
Commit Ordering (repository.commits.order)
| Setting |
Default |
Description |
repository.commits.order |
date |
Commit sort order: date (committer date), topo (topological, same-branch consecutive), or author-date |
Per-repository override is available via the table header right-click context menu.
Commit Muting (repository.commits.mute.*)
| Setting |
Default |
Description |
...mergeCommits |
true |
Display merge commits with reduced opacity |
...commitsThatAreNotAncestorsOfHead |
false |
Display non-ancestor-of-HEAD commits with reduced opacity |
Security
Git Keizu applies the following safeguards around Git execution, repository access, avatar requests, and webview content:
- Shell injection eliminated — all git commands use
child_process.spawn() exclusively; exec() has been removed entirely
- Git binary resolution — the configured
git.path (a single path or, as VS Code allows, a list of candidate paths) is verified by running each candidate with --version and only the first working executable is adopted; unusable values fall back to git on the PATH
- Commit hash validation — every operation that accepts a commit hash validates the format before passing it to git
- Repository path validation — all messages from the webview are checked against the registered repository list, preventing commands from running against arbitrary directories
- Path traversal prevention — file path arguments are checked for
.. sequences
- SSRF protection — avatar fetch requests are restricted to an allowlist of known domains (GitHub, GitLab, Gravatar)
- XSS fixes — commit parent hashes, avatar data URIs, and other dynamic values are properly HTML-escaped before insertion into the webview
Support and Contributing
Support
Bug reports and feedback via GitHub Issues are welcome. This is a personal project maintained in spare time — responses and fixes are not guaranteed, but reports are appreciated.
Contributing
The codebase uses async/await throughout, targets ES2020, and includes a Vitest test suite with oxlint and oxfmt for consistent style.
Pull requests are welcome as well. Fork the repository and open a pull request against main. CI runs pnpm run format, pnpm run lint, pnpm run typecheck, and pnpm run test:ci, so please confirm those pass locally first. For anything larger than a small fix, opening an issue first helps avoid wasted effort. CONTRIBUTING.md covers the development setup, conventions, and what the maintainer takes care of for you.
Supported build environments are Linux, macOS, and WSL. The build scripts rely on Unix shell commands (such as rm and cp), so building on a native Windows shell is not supported — on Windows, please develop inside WSL.
Acknowledgements
A big thank you to the original author, mhutchie, for creating this amazing extension.
Thanks also to asispts for carrying the project forward — stripping it down to the essentials and keeping it focused on what matters most.
License
MIT — see LICENSE. Bundled third-party material and its licenses are listed in ThirdPartyNotices.txt.
Not affiliated with or endorsed by the original Git Graph or neo-git-graph projects.
| |