21 KiB
lazygit - Product Requirements Document
Overview
lazygit is a simple terminal UI for git commands, written in Go. It provides an intuitive, keyboard-driven interface for managing git repositories without memorizing complex git commands.
- Version: 0.58.1
- Author: Jesse Duffield
- Repository: https://github.com/jesseduffield/lazygit
- License: MIT
Table of Contents
- Core Concepts
- User Interface
- Panel System
- Keybindings
- Git Operations
- Configuration
- CLI Interface
- Automation with VHS
Core Concepts
Design Philosophy
- Keyboard-first: All operations accessible via keyboard shortcuts
- Context-aware: Keybindings change based on focused panel and selected item
- Visual feedback: Real-time diff views, color-coded file states
- Non-destructive: Confirmation prompts for dangerous operations
- Discoverable: Built-in help system (
?) shows available actions
File States
| Indicator | Meaning |
|---|---|
M |
Modified (tracked file changed) |
A |
Added (new file staged) |
D |
Deleted |
R |
Renamed |
C |
Copied |
?? |
Untracked (new file not staged) |
UU |
Unmerged (conflict) |
User Interface
Layout Overview
+--[1]-Status---------+--[0]-Main View (Diff/Log/Patch)--------+
| repo-name -> branch | |
+--[2]-Files----------+ |
| Files/Worktrees/ | |
| Submodules | |
+--[3]-Branches-------+ |
| Local/Remotes/Tags | |
+--[4]-Commits--------+-----------------------------------------+
| Commits/Reflog |--Command log---------------------------+|
+--[5]-Stash----------+ ||
| Stash entries | ||
+---------------------+----------------------------------------++
| Status bar: Quick actions | Keybindings: ? | Version 0.58.1|
+------------------------------------------------------------------+
Panel Numbers
| # | Panel | Description |
|---|---|---|
| 0 | Main View | Displays diffs, logs, patches, commit details |
| 1 | Status | Repository name and current branch |
| 2 | Files | Working tree changes, worktrees, submodules |
| 3 | Branches | Local branches, remotes, tags |
| 4 | Commits | Commit history, reflog |
| 5 | Stash | Stash entries |
Navigation Between Panels
| Key | Action |
|---|---|
1-5 |
Jump directly to panel by number |
0 |
Focus main view |
h/l or Left/Right |
Move between panels |
Tab |
Toggle between side panels and main view |
[ / ] |
Switch tabs within a panel |
Screen Modes
| Key | Mode | Description |
|---|---|---|
+ |
Next screen mode | Cycles: normal -> half -> full |
_ |
Previous screen mode | Cycles backwards |
Panel System
Panel 1: Status
Displays the repository name and current branch.
Actions:
| Key | Action |
|---|---|
Enter |
Recent repositories |
a |
All branches log graph |
u |
Check for updates |
Panel 2: Files / Worktrees / Submodules
Tabs: Files | Worktrees | Submodules
Files Tab
File Operations:
| Key | Action |
|---|---|
Space |
Stage/unstage file |
a |
Stage/unstage all files |
Enter |
Enter staging view (line-by-line staging) |
d |
Discard changes |
D |
Reset options menu |
e |
Edit file |
o |
Open file |
i |
Ignore file (.gitignore) |
r |
Refresh files |
` |
Toggle file tree view |
- |
Collapse all directories |
= |
Expand all directories |
Commit Operations:
| Key | Action |
|---|---|
c |
Commit staged changes |
C |
Commit with editor |
w |
Commit without pre-commit hook |
A |
Amend last commit |
Ctrl+f |
Find base commit for fixup |
Stash Operations:
| Key | Action |
|---|---|
s |
Stash all changes |
S |
Stash options menu |
Stash Options Menu:
a- Stash all changesi- Stash all changes and keep indexU- Stash all changes including untracked filess- Stash staged changesu- Stash unstaged changes
Reset Options Menu (D):
u- Discard unstaged changes (git checkout -- .)d- Discard untracked files (git clean -fd)S- Discard staged changes (stash staged and drop stash)s- Soft reset (git reset --soft HEAD)m- Mixed reset (git reset --mixed HEAD)h- Hard reset (git reset --hard HEAD)
Worktrees Tab
| Key | Action |
|---|---|
n |
New worktree |
Space |
Switch to worktree |
d |
Remove worktree |
w |
View worktree options |
Submodules Tab
| Key | Action |
|---|---|
i |
Initialize submodule |
u |
Update submodule |
b |
Bulk menu |
Enter |
Enter submodule |
Panel 3: Local Branches / Remotes / Tags
Tabs: Local branches | Remotes | Tags
Local Branches Tab
| Key | Action |
|---|---|
Space |
Checkout branch |
n |
New branch |
d |
Delete branch |
r |
Rebase current branch onto selected |
R |
Rename branch |
M |
Merge selected into current branch |
f |
Fast-forward branch |
F |
Force checkout |
- |
Checkout previous branch |
u |
Set upstream |
i |
View git-flow options |
o |
Create pull request |
O |
View pull request options |
Ctrl+y |
Copy pull request URL |
T |
Create tag |
s |
Sort order |
Rebase Menu (r):
s- Simple rebase onto selected branchi- Interactive rebase onto selected branchb- Rebase onto base branch
Remotes Tab
| Key | Action |
|---|---|
Enter |
View branches |
n |
New remote |
d |
Remove remote |
e |
Edit remote |
f |
Fetch from remote |
F |
Add fork remote |
Tags Tab
| Key | Action |
|---|---|
Ctrl+o |
Copy tag to clipboard |
Space |
Checkout tag |
n |
New tag |
d |
Delete tag |
P |
Push tag |
g |
Reset to tag |
Enter |
View commits |
w |
View worktree options |
Panel 4: Commits / Reflog
Tabs: Commits | Reflog
Commits Tab
Navigation & Selection:
| Key | Action |
|---|---|
j/k |
Move up/down |
Space |
Checkout commit |
Enter |
View commit files |
v |
Toggle range select |
* |
Select commits of current branch |
Commit Manipulation:
| Key | Action |
|---|---|
r |
Reword commit message |
R |
Reword with editor |
e |
Edit commit (start interactive rebase) |
d |
Drop commit |
s |
Squash down |
S |
Squash all above commits |
f |
Mark as fixup |
F |
Create fixup commit |
p |
Pick commit |
Ctrl+j |
Move commit down |
Ctrl+k |
Move commit up |
i |
Start interactive rebase |
Advanced Operations:
| Key | Action |
|---|---|
A |
Amend commit with staged changes |
a |
Reset commit author |
t |
Revert commit |
T |
Tag commit |
C |
Cherry-pick copy |
V |
Paste (cherry-pick) commits |
Ctrl+R |
Reset cherry-pick selection |
B |
Mark as base for rebase |
b |
View bisect options |
g |
View reset options |
y |
Copy commit attribute to clipboard |
o |
Open commit in browser |
Ctrl+l |
Open log menu |
n |
Create new branch off commit |
Bisect Menu (b):
b- Mark commit as bad (start bisect)g- Mark commit as good (start bisect)t- Choose bisect terms- Cancel
Reflog Tab
Shows the reference log for recovering lost commits.
| Key | Action |
|---|---|
Space |
Checkout reflog entry |
g |
View reset options |
C |
Cherry-pick copy |
V |
Paste commits |
Panel 5: Stash
| Key | Action |
|---|---|
Space |
Apply stash |
g |
Pop stash |
d |
Drop stash |
n |
New branch from stash |
r |
Rename stash |
Enter |
View stash files |
Keybindings
Global Keybindings
Navigation:
| Key | Action |
|---|---|
j/k or Up/Down |
Move up/down in list |
h/l or Left/Right |
Move between panels |
< / > |
Go to top/bottom of list |
Home / End |
Go to top/bottom of list |
, / . |
Page up/down |
PgUp / PgDown |
Scroll main window |
J/K or Ctrl+u/Ctrl+d |
Scroll main window |
H / L |
Scroll left/right |
Actions:
| Key | Action |
|---|---|
? |
Show keybindings help |
Enter |
Confirm / Go into |
Esc |
Return / Cancel |
Space |
Primary action (context-dependent) |
/ |
Start search |
n / N |
Next/previous search match |
q |
Quit |
Q |
Quit without changing directory |
Ctrl+c |
Quit (alternative) |
Ctrl+z |
Suspend application |
Git Operations:
| Key | Action |
|---|---|
P |
Push |
p |
Pull |
f |
Fetch (in files panel) |
R |
Refresh |
z |
Undo (reflog) |
Z |
Redo (reflog) |
m |
View merge/rebase options |
View Options:
| Key | Action |
|---|---|
@ |
View command log options |
+ / _ |
Next/previous screen mode |
| |
Cycle pagers |
W or Ctrl+e |
Diffing menu |
Ctrl+w |
Toggle whitespace in diff |
} / { |
Increase/decrease diff context |
) / ( |
Increase/decrease rename similarity threshold |
Ctrl+t |
Open external diff tool |
Ctrl+s |
Filtering menu |
Other:
| Key | Action |
|---|---|
: |
Execute shell command |
Ctrl+r |
Switch to recent repo |
Ctrl+o |
Copy to clipboard |
Ctrl+p |
View custom patch options |
Staging View Keybindings
When viewing a file's diff (entered via Enter on a file):
| Key | Action |
|---|---|
Space |
Stage/unstage line |
a |
Toggle select hunk |
A |
Stage/unstage all changes |
v |
Toggle range select |
j/k |
Move up/down |
J/K |
Scroll diff up/down |
E |
Edit hunk in editor |
e |
Edit file |
o |
Open file |
Esc |
Return to files panel |
Tab |
Switch to staged/unstaged changes |
b |
Pick both hunks (merge conflicts) |
Git Operations
Committing
- Stage changes:
Spaceon files orato stage all - Commit:
cto commit with inline message - Commit with editor:
Cto open editor for commit message - Amend:
Ato amend the last commit with staged changes - Commit without hooks:
wto skip pre-commit hooks
Branching
- Create branch:
nin branches panel - Checkout:
Spaceon branch - Delete:
don branch - Rename:
Ron branch - Checkout previous:
-in branches panel
Merging
- Navigate to branches panel (
3) - Select the branch to merge
- Press
Mto merge into current branch
During merge conflicts:
- Files with
UUstatus indicate conflicts - Enter file to resolve conflicts line-by-line
- Use
bto pick both sides - Stage resolved files with
Space - Continue merge with
m-> continue option
Rebasing
Simple rebase:
- Go to branches panel
- Select target branch
- Press
rto open rebase menu - Choose rebase type
Interactive rebase:
- Go to commits panel
- Navigate to the commit before where you want to start
- Press
ito start interactive rebase - Use
p(pick),s(squash),f(fixup),d(drop),e(edit) - Reorder commits with
Ctrl+j/k - Press
mto view rebase options and continue/abort
Cherry-picking
- Navigate to the commit to cherry-pick
- Press
Cto copy the commit - Switch to the target branch
- Press
Vto paste (cherry-pick) - Use
Ctrl+Rto reset cherry-pick selection
Stashing
Quick stash:
sin files panel stashes all changes
Stash options (S):
- Stash all changes
- Stash including untracked
- Stash only staged
- Stash only unstaged
- Keep index
Using stashes:
Space- Apply stash (keep stash)g- Pop stash (apply and remove)d- Drop stash
Bisecting
- Go to commits panel
- Press
bto open bisect menu - Mark a known bad commit with
b - Mark a known good commit with
g - Test each commit lazygit checks out
- Mark as good/bad until bug is found
- Reset bisect when done
Working with Remotes
Push:
Pglobally pushes current branch- Force push available in push options menu
Pull:
pglobally pulls current branch- Configurable pull strategy (merge/rebase)
Fetch:
fin files panel fetches from remote- Auto-fetch configurable in settings
Configuration
Configuration File Location
lazygit --print-config-dir # Shows config directory
# Usually: ~/.config/lazygit/config.yml
Key Configuration Options
gui:
# Panel sizing
sidePanelWidth: 0.3333
expandFocusedSidePanel: false
mainPanelSplitMode: flexible # flexible | horizontal | vertical
# Display options
showFileTree: true
showIcons: false
nerdFontsVersion: "" # Set to "3" for nerd fonts v3
showCommandLog: true
showBottomLine: true
showPanelJumps: true
# Behavior
mouseEvents: true
skipDiscardChangeWarning: false
skipStashWarning: false
# Theme colors
theme:
activeBorderColor:
- green
- bold
inactiveBorderColor:
- default
selectedLineBgColor:
- blue
unstagedChangesColor:
- red
git:
# Auto operations
autoFetch: true
autoRefresh: true
fetchAll: true
# Commit settings
commit:
signOff: false
autoWrapCommitMessage: true
autoWrapWidth: 72
# Merge settings
merging:
manualCommit: false
args: ""
# Main branches for rebase targets
mainBranches:
- master
- main
# Log display
log:
order: topo-order # topo-order | date-order | author-date-order
showGraph: always # always | never | when-maximised
# Refresh intervals (seconds)
refresher:
refreshInterval: 10
fetchInterval: 60
# Confirmation settings
confirmOnQuit: false
quitOnTopLevelReturn: false
# Custom commands (advanced)
customCommands: []
Custom Keybindings
Keybindings can be customized in config.yml:
keybinding:
universal:
quit: q
return: <esc>
togglePanel: <tab>
prevItem: <up>
nextItem: <down>
# ... etc
files:
commitChanges: c
amendLastCommit: A
# ... etc
branches:
createPullRequest: o
rebaseBranch: r
# ... etc
Custom Commands
Define custom commands accessible via keybindings:
customCommands:
- key: "C"
command: "git cz" # Commitizen
context: "files"
loadingText: "Opening commitizen"
subprocess: true
- key: "b"
command: "git blame {{.SelectedFile.Name}}"
context: "files"
loadingText: "Blaming file"
CLI Interface
Basic Usage
lazygit # Open in current directory
lazygit -p /path/to/repo # Open specific repository
lazygit status # Focus status panel on open
lazygit branch # Focus branch panel on open
lazygit log # Focus log panel on open
lazygit stash # Focus stash panel on open
Command Line Flags
| Flag | Description |
|---|---|
-h, --help |
Display help |
-v, --version |
Print version |
-p, --path PATH |
Path to git repo |
-f, --filter PATH |
Filter log by path |
-c, --config |
Print default config |
-cd, --print-config-dir |
Print config directory |
-ucd, --use-config-dir DIR |
Override config directory |
-ucf, --use-config-file FILES |
Comma-separated config files |
-w, --work-tree PATH |
Git work-tree argument |
-g, --git-dir PATH |
Git git-dir argument |
-sm, --screen-mode MODE |
Initial screen mode: normal, half, full |
-d, --debug |
Run in debug mode with logging |
-l, --logs |
Tail lazygit logs |
--profile |
Start profiler on port 6060 |
Examples
# Open repo at specific path
lazygit -p ~/projects/myrepo
# Filter commits by file path
lazygit -f src/main.js
# Use custom config
lazygit -ucf ~/.config/lazygit/work-config.yml
# Start in full screen mode
lazygit -sm full
# Debug mode
lazygit -d
# In another terminal:
lazygit -l # Watch logs
Automation with VHS
VHS can be used to programmatically control lazygit for demos, testing, and documentation.
VHS Tape Syntax
# Configure output
Output "demo.gif"
Set Shell "bash"
Set FontSize 14
Set Width 1200
Set Height 800
# Launch lazygit
Type "cd /path/to/repo && lazygit"
Enter
Sleep 2s
# Navigate with keyboard
Type "2" # Go to files panel
Sleep 500ms
Type "j" # Move down
Sleep 500ms
Space # Stage file
Sleep 500ms
Type "c" # Start commit
Sleep 1s
Type "Add new feature"
Enter
Sleep 1s
# Capture screenshots
Screenshot "commit-complete.png"
# Quit
Type "q"
VHS Commands for lazygit
| Command | Usage | Description |
|---|---|---|
Type "x" |
Type "c" |
Type character (triggers keybinding) |
Enter |
Enter |
Press Enter key |
Escape |
Escape |
Press Escape key |
Space |
Space |
Press Space key |
Tab |
Tab |
Press Tab key |
Up/Down/Left/Right |
Down |
Arrow keys |
Sleep Xs |
Sleep 500ms |
Wait for UI |
Screenshot "file.png" |
Screenshot "/tmp/shot.png" |
Capture frame |
Example: Automated Commit Demo
Output "lazygit-commit-demo.gif"
Set Shell "bash"
Set Width 1200
Set Height 800
Set Framerate 10
# Setup
Type "cd /tmp/test-repo && lazygit"
Enter
Sleep 2s
# Show modified files
Type "2"
Sleep 1s
# Stage all changes
Type "a"
Sleep 500ms
# Open commit dialog
Type "c"
Sleep 1s
# Type commit message
Type "feat: add new authentication module"
Enter
Sleep 1s
# Show result
Screenshot "commit-complete.png"
Sleep 2s
# Quit
Type "q"
Running VHS Tapes
# Run tape and generate output
vhs demo.tape
# Validate tape without running
vhs validate demo.tape
# Record a new tape interactively
vhs record
# Publish GIF to share
vhs publish demo.gif
Tips and Tricks
Productivity Tips
- Use panel numbers: Press
1-5to jump directly to panels - Toggle views: Press
+to maximize the current panel - Filter commits: Use
/to search in any list - Quick stash: Press
sto stash all changes instantly - Undo mistakes: Press
zto undo via reflog - Copy commit hash: Press
yon a commit for copy options - Open in browser: Press
oon a commit to view on GitHub/GitLab
Advanced Usage
- Patch mode: Use
Ctrl+pto create partial patches from commits - Custom commands: Define frequently used git aliases
- Multiple configs: Use
-ucffor project-specific settings - Filter mode: Use
-fto focus on specific file history
Keyboard Navigation Summary
┌─────────────────────────────────────────┐
│ PANEL NAVIGATION │
├─────────────────────────────────────────┤
│ 1-5: Jump to panel Tab: Toggle view │
│ h/l: Move left/right [/]: Switch tabs │
│ j/k: Move up/down </> : Top/bottom │
├─────────────────────────────────────────┤
│ COMMON ACTIONS │
├─────────────────────────────────────────┤
│ Space: Primary action Enter: Go into │
│ c: Commit P: Push p: Pull │
│ s: Stash z: Undo ?: Help │
│ /: Search q: Quit │
└─────────────────────────────────────────┘
Comparison with Other Tools
| Feature | lazygit | tig | gitui | git CLI |
|---|---|---|---|---|
| TUI Interface | Yes | Yes | Yes | No |
| Staging View | Line-level | Hunk-level | Line-level | Hunk-level |
| Interactive Rebase | Visual | No | Visual | Editor |
| Merge Conflict UI | Yes | No | Yes | No |
| Customizable | YAML config | Limited | TOML config | Aliases |
| Language | Go | C | Rust | C |
| Cross-platform | Yes | Yes | Yes | Yes |
Resources
- Documentation: https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings
- Configuration: https://github.com/jesseduffield/lazygit/blob/v0.58.1/docs/Config.md
- Tutorial Video: https://youtu.be/VDXvbHZYeKY
- Issues: https://github.com/jesseduffield/lazygit/issues
- Releases: https://github.com/jesseduffield/lazygit/releases
- Sponsor: https://github.com/sponsors/jesseduffield
Document generated through programmatic exploration of lazygit v0.58.1 using VHS automation.