Lazygit
6 min read

Terminal UI for git. Makes complex git operations (interactive rebase, partial staging, bisect, worktrees, cherry-pick) accessible without leaving the terminal.

Install

sh
# macOS
brew install lazygit

# Arch Linux
sudo pacman -S lazygit

# Debian 13+ / Ubuntu 25.10+
sudo apt install lazygit

# Fedora
sudo dnf copr enable dejan/lazygit && sudo dnf install lazygit

# Windows
scoop install lazygit
winget install JesseDuffield.lazygit

# FreeBSD
pkg install lazygit

# Nix
nix run nixpkgs#lazygit
nix-shell -p lazygit
# NixOS: environment.systemPackages = [ pkgs.lazygit ]

# Go
go install github.com/jesseduffield/lazygit@latest

Usage

sh
lazygit # open in current repo
lazygit -p /path/to/repo # explicit path

Layout

Five side panels (jump with 1–5):

#PanelContents
1StatusRepo status, recent repos
2FilesWorking tree, staging area
3BranchesLocal branches / Remotes / Tags / Worktrees (tabs)
4CommitsCommit log / Reflog (tabs)
5StashStash entries

Navigate tabs within a panel with [ / ]. The main panel (right) shows the diff or content for the selected item.

Keybindings

Global

KeyAction
1–5Jump to panel
[ / ]Previous / next tab
PPush
pPull
RRefresh
z / ZUndo / Redo (via reflog)
+ / _Cycle screen modes (normal / half / full)
|Cycle pagers
mMerge/rebase options
WDiff options
<c-p>Custom patch options
:Execute shell command
?Keybinding help
qQuit

Files Panel

KeyAction
spaceStage / unstage file
aStage all
enterStage individual lines / enter directory
dDiscard changes
DReset (nuke) options
cCommit
AAmend last commit
CCommit using editor
wCommit without pre-commit hook
<c-f>Find base commit for fixup
eEdit file
iIgnore / exclude file
s / SStash / stash options
` Toggle file tree view

Staging View (main panel)

KeyAction
spaceStage / unstage selected line
vToggle range select
aToggle hunk
dDiscard selection
← / →Previous / next hunk
tabSwitch staged ↔ unstaged
EEdit hunk in editor

Commits Panel

KeyAction
iStart interactive rebase
sSquash into commit below
fFixup into commit below
FCreate fixup commit for this commit
SApply all fixup commits above
r / RReword / reword with editor
dDrop commit
eEdit (pause rebase here)
pPick (during rebase)
<c-j> / <c-k>Move commit down / up
BMark as base commit for rebase
AAmend with staged changes
tRevert commit
TTag commit
nNew branch from commit
NMove commits to new branch
C / VCopy (cherry-pick) / Paste
bBisect options
gReset options
<shift-w>Mark for diff comparison
GOpen PR in browser

Branches Panel

KeyAction
spaceCheckout
nNew branch
dDelete branch
rRebase onto selected
MMerge options
fFast-forward
RRename
o / OCreate PR / PR options
GOpen PR in browser
<c-y>Copy PR URL
iGit flow options
wWorktree options
-Checkout previous branch

Other Panels

PanelKeyAction
Stashspace / gApply / Pop
StashdDrop
StashnNew branch from stash
StashrRename stash
WorktreesnNew worktree
WorktreesspaceSwitch to worktree
WorktreesdRemove worktree
Remotesn / d / eNew / Remove / Edit remote
RemotesfFetch from remote

Configuration

File Locations

PlatformPath
Linux~/.config/lazygit/config.yml
macOS~/Library/Application Support/lazygit/config.yml
Windows%LOCALAPPDATA%\lazygit\config.yml
Repo-specific<repo>/.git/lazygit.yml
Hierarchical.lazygit.yml in any parent directory

Merge multiple configs: LG_CONFIG_FILE="$HOME/.base.yml,$HOME/.theme.yml" lazygit

Add JSON schema support to get editor completion:

yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/jesseduffield/lazygit/master/schema/config.json

Key Options

yaml
gui:
nerdFontsVersion: "3" # "" | "2" | "3" — enable icons
showFileIcons: true
border: rounded # rounded | single | double | hidden | bold
filterMode: fuzzy # substring | fuzzy
sidePanelWidth: 0.3333
mainPanelSplitMode: flexible # horizontal | vertical | flexible
showDivergenceFromBaseBranch: arrowAndNumber
statusPanelView: dashboard # dashboard | allBranchesLog
language: auto
theme:
activeBorderColor: ["green", "bold"]
selectedLineBgColor: ["blue"]
unstagedChangesColor: ["red"]
authorColors:
"Alice": "red"
branchColorPatterns:
"^feat/": "cyan"

git:
autoFetch: true
autoRefresh: true
diffContextSize: 3
ignoreWhitespaceInDiffView: false
mainBranches: ["main", "master"]
skipHookPrefix: "WIP"
log:
order: topo-order # date-order | author-date-order | topo-order
showGraph: always # always | never | when-maximised
localBranchSortOrder: date # date | recency | alphabetical

os:
editPreset: "nvim" # vim | nvim | emacs | nano | vscode | zed | helix | …
# or explicit:
edit: "nvim {{filename}}"
editAtLine: "nvim +{{line}} {{filename}}"

Custom Pagers

Cycle between pagers with |. Multiple pagers can be defined.

yaml
git:
pagers:
# delta
- pager: delta --dark --paging=never --line-numbers

# delta with editor hyperlinks (click line numbers to jump)
- pager: delta --dark --paging=never --hyperlinks --hyperlinks-file-link-format="lazygit-edit://{path}:{line}"

# diff-so-fancy
- pager: diff-so-fancy

# ydiff (needs colorArg: never)
- colorArg: never
pager: ydiff -p cat -s --wrap --width={{columnWidth}}

# difftastic (external diff)
- externalDiffCommand: difft --color=always

# use git's own difftool config
- useExternalDiffGitConfig: true

Custom Commands

Defined in a customCommands array. Bound to a key in a given context.

Full Example

yaml
customCommands:
# Open GitHub URL for selected commit
- key: "o"
context: "commits"
description: "Open commit on GitHub"
command: 'open "https://github.com/user/repo/commit/{{.SelectedCommit.Hash}}"'

# New branch with ticket prefix prompt
- key: "b"
context: "localBranches"
description: "New branch with ticket"
prompts:
- type: input
title: "Ticket number"
key: Ticket
- type: input
title: "Branch name"
key: Name
command: "git checkout -b PROJ-{{.Form.Ticket}}/{{.Form.Name}}"

# Force push with confirmation
- key: "F"
context: "localBranches"
description: "Force push"
prompts:
- type: confirm
title: "Force push?"
body: "This will overwrite the remote branch."
command: "git push --force-with-lease"
loadingText: "Force pushing..."

# Menu-driven rebase action
- key: "R"
context: "commits"
description: "Rebase action"
prompts:
- type: menu
title: "Action"
key: Action
options:
- name: "squash"
value: "squash"
key: s
- name: "fixup"
value: "fixup"
key: f
command: "echo {{.Form.Action}} {{.SelectedCommit.Hash}}"
output: popup

Contexts

status, files, worktrees, submodules, localBranches, remotes, remoteBranches, tags, commits, reflogCommits, subCommits, commitFiles, stash, global

Comma-separate for multiple: context: "localBranches,remoteBranches"

Template Variables

VariableDescription
{{.SelectedCommit.Hash}}Selected commit hash
{{.SelectedFile.Name}}Selected file path
{{.SelectedLocalBranch.Name}}Selected local branch
{{.SelectedRemoteBranch.Name}}Selected remote branch
{{.SelectedTag.Name}}Selected tag
{{.SelectedStashEntry.Index}}Stash index
{{.SelectedPath}}Selected file/path
{{.CheckedOutBranch.Name}}Currently checked out branch
{{.SelectedCommitRange.From}}First commit in range
{{.SelectedCommitRange.To}}Last commit in range
{{.Form.KEY}}Value from a prompt with key: KEY
{{quote .SelectedFile.Name}}Platform-safe quoted path
{{runCommand "git rev-parse HEAD"}}Run subprocess, returns stdout

Output Modes

ModeDescription
noneDiscard output
terminalSuspend lazygit, run interactively
logStream to command log panel
logWithPtyLike log but with terminal color support
popupDisplay result in overlay

Command Menus (nested)

yaml
customCommands:
- key: X
commandMenu:
- key: c
command: "git cherry-pick {{.SelectedCommit.Hash}}"
context: commits
description: "Cherry pick"
- key: r
command: "git revert {{.SelectedCommit.Hash}}"
context: commits
description: "Revert"

Features

Interactive Rebase

Press i in the Commits panel. Then on any commit: s squash, f fixup, d drop, r reword, e edit, <c-k>/<c-j> move. Continue with m → continue. One-off actions work without explicitly starting a rebase.

Partial Staging

In the Files panel, press enter on a file to open staging view. Stage individual lines with space, select ranges with v, toggle hunks with a.

Cherry-pick

C on a commit to copy, V to paste (cherry-pick). <c-r> to reset the cherry-pick selection.

Amend Old Commit

Stage your changes, then A on any commit in the Commits panel. Runs an interactive rebase in the background.

Bisect

Press b in the Commits panel to mark a commit as good/bad and begin git bisect.

Worktrees

Access from the Branches panel tabs or w from various panels. Create worktrees from any branch; switch between them without stashing.

Custom Patches

Enter a commit's files with enter, then a file's diff with enter. Add lines with space, then <c-p> for patch options (remove from commit, apply in reverse, split commit, etc.).

Rebase from Marked Base

B to mark a base commit, then rebase onto another branch — only commits from your feature branch are brought along.

PR Integration

Requires gh CLI and gh auth login. In the Branches panel, branches with open PRs show a GitHub icon. G opens the PR in the browser; <c-y> copies the PR URL.

Commit Graph

Enlarge with +/_ to cycle screen modes. Colors correspond to commit authors; parent commits are highlighted as you navigate.

Diff Comparison

<shift-w> on a commit or branch to mark it, then navigate to another commit/branch to diff against it.

Undo / Redo

z undoes the last action (via reflog — covers commits and branches, not working tree or stash). Z redoes.

Commit Colors

ColorMeaning
GreenIncluded in the main branch
YellowNot in the main branch
RedNot pushed to upstream