This commit is contained in:
2026-01-21 11:27:51 -05:00
commit f70af9b185
50 changed files with 17166 additions and 0 deletions
+851
View File
@@ -0,0 +1,851 @@
# 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
1. [Core Concepts](#core-concepts)
2. [User Interface](#user-interface)
3. [Panel System](#panel-system)
4. [Keybindings](#keybindings)
5. [Git Operations](#git-operations)
6. [Configuration](#configuration)
7. [CLI Interface](#cli-interface)
8. [Automation with VHS](#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 changes
- `i` - Stash all changes and keep index
- `U` - Stash all changes including untracked files
- `s` - Stash staged changes
- `u` - 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 branch
- `i` - Interactive rebase onto selected branch
- `b` - 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
1. **Stage changes**: `Space` on files or `a` to stage all
2. **Commit**: `c` to commit with inline message
3. **Commit with editor**: `C` to open editor for commit message
4. **Amend**: `A` to amend the last commit with staged changes
5. **Commit without hooks**: `w` to skip pre-commit hooks
### Branching
1. **Create branch**: `n` in branches panel
2. **Checkout**: `Space` on branch
3. **Delete**: `d` on branch
4. **Rename**: `R` on branch
5. **Checkout previous**: `-` in branches panel
### Merging
1. Navigate to branches panel (`3`)
2. Select the branch to merge
3. Press `M` to merge into current branch
**During merge conflicts:**
- Files with `UU` status indicate conflicts
- Enter file to resolve conflicts line-by-line
- Use `b` to pick both sides
- Stage resolved files with `Space`
- Continue merge with `m` -> continue option
### Rebasing
**Simple rebase:**
1. Go to branches panel
2. Select target branch
3. Press `r` to open rebase menu
4. Choose rebase type
**Interactive rebase:**
1. Go to commits panel
2. Navigate to the commit before where you want to start
3. Press `i` to start interactive rebase
4. Use `p` (pick), `s` (squash), `f` (fixup), `d` (drop), `e` (edit)
5. Reorder commits with `Ctrl+j/k`
6. Press `m` to view rebase options and continue/abort
### Cherry-picking
1. Navigate to the commit to cherry-pick
2. Press `C` to copy the commit
3. Switch to the target branch
4. Press `V` to paste (cherry-pick)
5. Use `Ctrl+R` to reset cherry-pick selection
### Stashing
**Quick stash:**
- `s` in 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
1. Go to commits panel
2. Press `b` to open bisect menu
3. Mark a known bad commit with `b`
4. Mark a known good commit with `g`
5. Test each commit lazygit checks out
6. Mark as good/bad until bug is found
7. Reset bisect when done
### Working with Remotes
**Push:**
- `P` globally pushes current branch
- Force push available in push options menu
**Pull:**
- `p` globally pulls current branch
- Configurable pull strategy (merge/rebase)
**Fetch:**
- `f` in files panel fetches from remote
- Auto-fetch configurable in settings
---
## Configuration
### Configuration File Location
```bash
lazygit --print-config-dir # Shows config directory
# Usually: ~/.config/lazygit/config.yml
```
### Key Configuration Options
```yaml
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`:
```yaml
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:
```yaml
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
```bash
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
```bash
# 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](https://github.com/charmbracelet/vhs) can be used to programmatically control lazygit for demos, testing, and documentation.
### VHS Tape Syntax
```tape
# 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
```tape
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
```bash
# 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
1. **Use panel numbers**: Press `1-5` to jump directly to panels
2. **Toggle views**: Press `+` to maximize the current panel
3. **Filter commits**: Use `/` to search in any list
4. **Quick stash**: Press `s` to stash all changes instantly
5. **Undo mistakes**: Press `z` to undo via reflog
6. **Copy commit hash**: Press `y` on a commit for copy options
7. **Open in browser**: Press `o` on a commit to view on GitHub/GitLab
### Advanced Usage
1. **Patch mode**: Use `Ctrl+p` to create partial patches from commits
2. **Custom commands**: Define frequently used git aliases
3. **Multiple configs**: Use `-ucf` for project-specific settings
4. **Filter mode**: Use `-f` to 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.*