Lazygit
Installation
# macOS
brew install lazygit
# Arch Linux
pacman -S lazygit
# Ubuntu / Debian (via Go)
go install github.com/jesseduffield/lazygit@latest
# Windows (winget)
winget install -e --id=JesseDuffield.lazygit
# Windows (scoop)
scoop install lazygit
# From source
git clone https://github.com/jesseduffield/lazygit.git
cd lazygit
go install
Verify installation:
lazygit --version
Configuration
The config file lives at:
| Platform | Path |
|---|---|
| macOS / Linux | ~/.config/lazygit/config.yml |
| Windows | %APPDATA%\lazygit\config.yml |
Open config from inside lazygit with e on the config file or run:
lazygit --config
Sample config.yml
gui:
theme:
activeBorderColor:
- green
- bold
selectedLineBgColor:
- blue
showIcons: true
sidePanelWidth: 0.2
expandFocusedSidePanel: true
mouseEvents: true
returnImmediately: false
git:
paging:
colorArg: always
pager: delta --dark --paging=never
commit:
signOff: false
merging:
manualCommit: false
log:
order: topo-order
showGraph: when-maximised
keybinding:
universal:
quit: q
return: <esc>
togglePanel: <tab>
prevItem: <up>
nextItem: <down>
scrollLeft: H
scrollRight: L
commits:
squashDown: s
renameCommit: r
moveUpCommit: K
moveDownCommit: J
Custom Pager (delta)
# Install delta for better diffs
brew install git-delta # macOS
cargo install git-delta # cargo
# Then reference it in config.yml (see above)
Core Commands
Global Navigation
| Key | Description |
|---|---|
1–5 | Switch panels (Status, Files, Branches, Commits, Stash) |
Tab | Cycle between panels |
← → or H L | Scroll diff left / right |
↑ ↓ or j k | Move cursor up / down |
PgUp / PgDn | Scroll diff view |
? | Open keybinding help |
q | Quit lazygit |
+ / _ | Resize main panel larger / smaller |
@ | Open command log |
Files Panel
| Key | Description |
|---|---|
<space> | Stage / unstage file |
a | Stage / unstage all files |
c | Commit staged changes |
C | Commit using git editor |
A | Amend last commit |
d | Discard changes in file |
i | Add file to .gitignore |
e | Open file in editor |
o | Open file in OS default app |
Enter | View file diff |
Branches Panel
| Key | Description |
|---|---|
<space> | Checkout branch |
n | New branch |
d | Delete branch |
D | Force-delete branch |
r | Rebase onto selected branch |
M | Merge into current branch |
f | Fast-forward branch |
g | View reset options |
R | Rename branch |
u | Set / unset upstream |
Commits Panel
| Key | Description |
|---|---|
s | Squash commit down |
f | Fixup commit (squash, discard message) |
r | Rename / reword commit |
R | Reword with editor |
d | Drop commit |
e | Edit commit (stop rebase here) |
p | Pick commit |
K | Move commit up |
J | Move commit down |
c | Copy commit hash |
C | Copy range of commits |
v | Paste (cherry-pick) copied commits |
A | Amend commit with staged changes |
t | Revert commit |
Stash Panel
| Key | Description |
|---|---|
<space> | Apply stash entry |
g | Pop stash entry |
d | Drop stash entry |
n | New branch from stash |
Enter | View stash diff |
Submodule Panel
| Key | Description |
|---|---|
<enter> | Enter submodule |
u | Update submodule |
b | Bulk submodule operations |
Advanced Usage
Interactive Rebase
Start an interactive rebase on the last N commits directly in the Commits panel:
1. Open lazygit in your repo
2. Navigate to the Commits panel (press 4)
3. Move cursor to the oldest commit you want to rebase
4. Press 'e' to start interactive rebase from that point
5. Use s/f/r/d/K/J on individual commits
6. Press 'm' to mark a commit for squash during rebase
7. When done, confirm to apply the rebase
Cherry-Pick Workflow
1. Navigate to source branch in Branches panel
2. Move to Commits panel
3. Press 'c' to copy a single commit (or 'C' to copy range)
4. Switch to destination branch via Branches panel
5. Press 'v' to paste (cherry-pick) the commit(s)
Custom Commands
Add custom commands to config.yml:
customCommands:
- key: '<c-p>'
command: 'git push --force-with-lease origin {{.CheckedOutBranch.Name}}'
context: 'localBranches'
description: 'Force push current branch (safe)'
loadingText: 'Pushing...'
- key: 'P'
command: 'git pull --rebase origin {{.CheckedOutBranch.Name}}'
context: 'localBranches'
description: 'Pull with rebase'
- key: '<c-r>'
command: 'gh pr create --fill --draft'
context: 'files'
description: 'Create draft PR'
loadingText: 'Creating PR...'
- key: 'b'
command: 'git bisect start'
context: 'commits'
description: 'Start git bisect'
Worktree Support
# config.yml — enable worktrees
git:
worktrees:
enabled: true
Then use w in the Branches panel to manage worktrees.
Filtering and Searching
/ — open filter input in any panel (fuzzy search)
Ctrl+f — open commit filter (by author, date, message)
Patching Commits
Lazygit supports staging individual lines / hunks from a file and including them in a specific historical commit:
1. In the Files panel, press Enter on a file to see its diff
2. Use arrow keys to select lines; press <space> to stage a hunk
3. Navigate to Commits panel, find target commit
4. Press 'A' to amend with the staged patch
Common Workflows
Clean Feature Branch Before PR
1. Open lazygit (lazygit)
2. Go to Commits panel
3. Squash WIP commits: select, press 's'
4. Reword the final commit: press 'r'
5. Force push: <c-p> (custom command above)
Resolve Merge Conflicts
1. After a conflicted merge/rebase, open lazygit
2. Files panel highlights conflicted files in red
3. Press 'e' to open in editor (with conflict markers)
4. After resolving, press <space> to stage the file
5. Press 'c' to continue the merge/rebase
Undo Last Commit (Keep Changes)
1. Commits panel → select last commit
2. Press 'g' to see reset options
3. Choose 'Soft reset' — changes return to staging area
Bisect a Bug
1. Custom command or press ':' for shell command
2. Type: git bisect start
3. Mark current as bad: git bisect bad
4. Navigate to known-good commit, mark: git bisect good <hash>
5. Test each step, mark good/bad until done
Tips and Best Practices
- Launch from project root — run
lazygitin the repo directory, not a subdirectory, to see all files correctly. - Use
deltaas your pager — it adds syntax highlighting and diff decoration to the diff view. - Learn panel numbers —
1through5jump you directly to Status, Files, Branches, Commits, Stash without tabbing. ?is your friend — every panel has its own contextual help screen; press?to see all available keys for the current panel.- Custom commands reduce context switching — map
gh pr create,npm test, or any shell command you run after commits to a keybinding. - Don’t force-push main — lazygit won’t stop you; add a pre-push hook or use branch protection rules on GitHub.
- Use
f(fixup) instead ofs(squash) when you want to merge a commit into the one below and discard the message — it keeps history cleaner. - The
:key opens a prompt to run any arbitrary git command without leaving lazygit. Rin the Branches panel renames a branch locally; remember to push the rename if it’s already on the remote.- Scrolling the diff — use
PgUp/PgDnorCtrl+u/Ctrl+dinside the diff view to navigate large diffs quickly. - Amend without editing message — press
Ain the Commits panel on the latest commit to absorb staged changes silently.