Lazygit is a terminal user interface (TUI) for git, written in Go. It replaces the need to memorize and type complex git commands by presenting an interactive, keyboard-driven interface for staging, committing, branching, rebasing, merge conflict resolution, stashing, cherry-picking, bisecting, worktree management, and more. If you can use git from the command line, lazygit lets you do the same things faster and with less friction.
1. Quick Start
Open lazygit in a repository
cd /path/to/your/repo
lazygit
That's it. Lazygit opens with five main panels arranged vertically on the left and a diff/detail view on the right:
| Panel | Key | What it shows |
|---|---|---|
| Status | 1 |
Current branch, repo name, recent activity |
| Files | 2 |
Working directory changes (staged and unstaged) |
| Branches | 3 |
Local branches, remotes, tags, worktrees (as tabs) |
| Commits | 4 |
Commit log for the current branch |
| Stash | 5 |
Stashed changes |
Press the number key to jump directly to any panel. Use <tab> to cycle through panels, or h/l (left/right arrow keys) to move between them.
The 60-second workflow
- Open lazygit in your repo
- Navigate to the Files panel (
2) - Use
j/kto select a file, press<space>to stage it - Press
cto open the commit prompt, type your message, press<enter> - Press
Pto push
Tip
Press
ain the Files panel to stage or unstage all files at once. This is the fastest way to commit everything in your working directory.
Navigating the interface
Lazygit follows vim-style navigation throughout:
| Key | Action |
|---|---|
j / <down> |
Move down |
k / <up> |
Move up |
h / <left> |
Previous panel |
l / <right> |
Next panel |
<enter> |
Go into / confirm |
<esc> |
Go back / cancel |
q |
Quit lazygit |
? |
Open options/help menu |
Press ? on any panel to see context-sensitive keybindings for that panel.
2. Installation
Package managers
macOS
# Homebrew
brew install lazygit
# MacPorts
sudo port install lazygit
Linux
# Arch Linux
pacman -S lazygit
# Fedora / RHEL (COPR)
sudo dnf copr enable atim/lazygit -y
sudo dnf install lazygit
# Ubuntu / Debian (via Snap or binary release)
sudo snap install lazygit
# Void Linux
sudo xbps-install -S lazygit
# Nix
nix-env -iA nixpkgs.lazygit
Windows
# Scoop
scoop install lazygit
# Chocolatey
choco install lazygit
# Winget
winget install -e --id=JesseDuffield.Lazygit
From source
go install github.com/jesseduffield/lazygit@latest
Important
Lazygit requires git version 2.32.0 or later. Run
git --versionto check. Older git versions will cause unexpected behavior or crashes.
Verifying installation
lazygit --version
This prints the version, build date, commit hash, build source, and OS/architecture.
Warning
If you install from source with
go install, ensure your$GOPATH/bin(or$GOBIN) is in yourPATH. Otherwise thelazygitcommand will not be found.
3. Configuration
Config file location
Lazygit reads its configuration from a YAML file:
| Platform | Default path |
|---|---|
| Linux / macOS | ~/.config/lazygit/config.yml |
| Windows | %APPDATA%\lazygit\config.yml |
The path follows the XDG Base Directory specification ($XDG_CONFIG_HOME/lazygit/config.yml). Lazygit also checks the legacy path ~/.config/jesseduffield/lazygit/config.yml for backward compatibility.
State information (e.g., recent repos) is stored separately at $XDG_STATE_HOME/lazygit/state.yml.
Overriding config location
Use the LG_CONFIG_FILE environment variable to point to one or more custom config files (comma-separated):
LG_CONFIG_FILE="~/dotfiles/lazygit.yml,~/lazygit-local.yml" lazygit
Or use the CLI flag:
lazygit --use-config-file ~/dotfiles/lazygit.yml
To override the entire config directory:
lazygit --use-config-dir ~/my-lazygit-config/
Printing the defaults
To see the full default configuration:
lazygit --config
To find your config directory:
lazygit --print-config-dir
Key configuration options
Below are some of the most commonly customized settings. For the full configuration reference, see the Admin Guide.
Editor preset
Set os.editPreset to have lazygit open files in your preferred editor. Supported values:
| Preset | Editor |
|---|---|
vi |
Vi |
vim |
Vim |
nvim |
Neovim |
nvim-remote |
Neovim remote |
lvim |
LunarVim |
emacs |
Emacs |
micro |
Micro |
nano |
Nano |
kakoune |
Kakoune |
helix |
Helix |
vscode |
VS Code |
sublime |
Sublime Text |
bbedit |
BBEdit |
xcode |
Xcode |
zed |
Zed |
acme |
Acme |
Example config:
os:
editPreset: nvim
Language
Lazygit supports multiple interface languages. Set gui.language in your config:
gui:
language: auto
Supported values: auto, en, zh-CN, zh-TW, pl, nl, ja, ko, ru, pt.
Mouse support
Mouse support is enabled by default. To disable:
gui:
mouseEvents: false
Nerd Fonts icons
If you use a Nerd Font in your terminal, enable icons:
gui:
nerdFontsVersion: "3"
Supported values: "2" for Nerd Fonts v2, "3" for Nerd Fonts v3.
Custom pager
Lazygit works with external diff tools like delta, diff-so-fancy, and difftastic. Configure them under git.paging:
git:
paging:
colorArg: always
pager: delta --dark --paging=never
Non-repository behavior
The notARepository setting controls what happens when you open lazygit outside a git repo:
| Value | Behavior |
|---|---|
prompt |
Ask whether to initialize or open a recent repo (default) |
create |
Automatically run git init |
skip |
Open the most recently used repo |
quit |
Exit immediately |
notARepository: prompt
Environment variables
| Variable | Purpose |
|---|---|
LG_CONFIG_FILE |
Comma-separated list of config file paths |
CONFIG_DIR |
Override config directory |
LAZYGIT_LOG_PATH |
Custom log file path |
GIT_WORK_TREE |
Git work tree path |
GIT_DIR |
Git directory path |
DEBUG |
Set to TRUE to enable debug mode |
LOG_LEVEL |
Log level: debug, info, warn, error |
4. Core Usage
Understanding the layout
Lazygit divides the terminal into two regions:
- Side panels (left): the five main panels stacked vertically
- Main view (right): shows diffs, file contents, commit details, or merge conflict views depending on context
The panels can be displayed in different screen modes. Press + to cycle forward through modes (normal, half, full) or _ to cycle backward.
Note
In full screen mode, the side panels are hidden and the main view takes the entire terminal. This is useful when reviewing large diffs. Press
_to return to normal mode.
Side panel tabs
Some panels contain tabs. For example, the Branches panel has four tabs:
- Local Branches
- Remotes
- Tags
- Worktrees
Press ] to move to the next tab and [ for the previous tab within a panel.
File tree vs. flat view
The Files panel can show changes as a flat list or as a directory tree. Press the backtick key (`) to toggle between views. Tree view is helpful in large repositories where changes span many directories.
Staging changes
Navigate to the Files panel and select a file:
| Key | Action |
|---|---|
<space> |
Stage/unstage the selected file |
a |
Stage/unstage all files |
<enter> |
Open file to stage individual lines or hunks |
When you press <enter> on a file, the main view switches to a staging view where you can:
| Key | Action |
|---|---|
<space> |
Stage/unstage selected line |
a |
Toggle select entire hunk |
v |
Enter range select mode |
Tip
Use range select (
v) in the staging view to select multiple lines, then press<space>to stage them all. This gives you precise control over what goes into each commit.
Committing
From the Files panel:
| Key | Action |
|---|---|
c |
Commit staged changes (inline message prompt) |
C |
Commit with your configured editor |
w |
Commit without running git hooks |
A |
Amend the last commit |
After pressing c, type your commit message and press <enter> to confirm.
Pushing and pulling
These bindings work from any panel:
| Key | Action |
|---|---|
P (shift) |
Push to remote |
p |
Pull from remote |
f |
Fetch from remote (in Files panel) |
Important
Push is
P(uppercase/shift) and pull isp(lowercase). Mixing these up is the most common mistake for new users.
Branching
In the Branches panel:
| Key | Action |
|---|---|
n |
Create a new branch |
<space> |
Checkout selected branch |
c |
Checkout branch by name |
R |
Rename branch |
d |
Delete branch |
M |
Merge selected branch into current |
r |
Rebase current branch onto selected |
F |
Force checkout |
f |
Fast-forward current branch to match selected |
u |
Set/change upstream |
s |
Change sort order |
Searching and filtering
Press / to start a search within the current panel. Use n to jump to the next match and N for the previous match.
Press <c-s> (Ctrl+S) to open the filtering menu, which lets you filter commits by path or other criteria.
Undo and redo
Lazygit maintains an undo/redo stack for many operations:
| Key | Action |
|---|---|
z |
Undo |
Z |
Redo |
This works for commits, branch checkouts, and other ref-changing operations. It uses git's reflog under the hood.
Executing shell commands
Press : to open a shell command prompt. Type any shell command and press <enter> to execute it. The output appears in the main view.
Copying to clipboard
Press <c-o> (Ctrl+O) to copy the currently selected item to your clipboard. In the Commits panel, press y to copy commit attributes (hash, message, URL, etc.).
Opening recent repos
Press <c-r> (Ctrl+R) to open a list of recently visited repositories and switch between them.
5. Common Tasks
Recipe 1: Stage specific lines from a file
- Go to the Files panel (
2) - Select the modified file and press
<enter> - In the staging view, navigate to the lines you want
- Press
vto enter range select, select lines withj/k - Press
<space>to stage selected lines - Press
<esc>to return to the Files panel - Press
cto commit
Recipe 2: Interactive rebase (reorder, squash, edit commits)
- Go to the Commits panel (
4) - Select the commit where you want to start the rebase
- Press
ito begin an interactive rebase - Use
<c-j>and<c-k>to move commits up and down - Press
son a commit to mark it for squash - Press
fto mark as fixup (squash without keeping the message) - Press
rto reword a commit message - Press
pto pick (keep as-is) - Navigate to the bottom and confirm the rebase
Recipe 3: Resolve merge conflicts
- When a merge or rebase produces conflicts, lazygit shows conflicted files in the Files panel
- Select a conflicted file and press
<enter> - The main view shows conflict markers with incoming and current changes highlighted
- Use
<space>to select which version to keep - Press
bto pick both versions - After resolving all conflicts in a file, press
<esc>to return - Stage the resolved file with
<space>and continue the merge/rebase
Recipe 4: Cherry-pick commits between branches
- Go to the Commits panel (
4) - Select the commit(s) you want to cherry-pick
- Press
C(shift+C) to copy the commit - For multiple commits, use range select (
v) thenC - Switch to the target branch in the Branches panel
- Press
V(shift+V) to paste (apply) the cherry-picked commits - Press
<c-R>to clear the cherry-pick selection when done
Recipe 5: Stash and restore changes
Stash everything:
- In the Files panel, press
sto stash all changes
Stash with options:
- Press
S(shift) to see stash options (stash staged only, stash with message, etc.)
Restore a stash:
- Go to the Stash panel (
5) - Select the stash entry
- Press
<space>to apply it (keeps the stash) - Press
gto pop it (applies and removes the stash)
Recipe 6: Create and push a tag
- Go to the Commits panel (
4) - Select the commit to tag
- Press
Tto create a tag, enter the tag name - Go to the Branches panel (
3), then the Tags tab (]to cycle tabs) - Select the tag and press
Pto push it to the remote
Recipe 7: Git bisect to find a bug
- Go to the Commits panel (
4) - Press
bto open bisect options - Mark the current commit as bad
- Navigate to a known good commit and mark it as good
- Lazygit walks you through the bisect, checking out commits for you to test
- Mark each commit as good or bad until the culprit is found
Recipe 8: Work with multiple worktrees
- Go to the Branches panel (
3) - Navigate to the Worktrees tab (press
]until you reach it) - Press
nto create a new worktree - Select an existing worktree and press
<enter>to switch to it
Recipe 9: Manage submodules
- In the Files panel, navigate to the Submodules tab
- Press
ito initialize submodules - Press
uto update submodules - Press
bfor bulk operations (init all, update all, deinit all) - Press
<enter>on a submodule to open lazygit inside it
Recipe 10: Amend a specific commit (not just the last one)
- Go to the Commits panel (
4) - Stage the changes you want to add in the Files panel
- Return to the Commits panel and select the target commit
- Press
Ato amend the staged changes into that commit
Note
Amending a commit that is not the most recent triggers an automatic interactive rebase. This rewrites history, so avoid doing this on commits that have already been pushed to a shared branch.
Recipe 11: Build a patch from an old commit
- Go to the Commits panel and select a commit
- Press
<enter>to view its files - Select a file and press
<enter>to view the diff - Use
<space>to select lines or hunks to include in your patch - Press
<c-p>to open the patch options menu - Choose to apply the patch, create a new commit from it, or other options
Recipe 12: Reset a branch to a previous state
- In the Files panel, press
Dto view reset options - Choose soft reset (keep changes staged), mixed (keep changes unstaged), or hard (discard everything)
Alternatively, in the Commits panel:
- Select the commit to reset to
- Press
gto open reset options - Choose the reset type
Recipe 13: View and compare diffs
- Press
Wto open the diffing menu - Select a branch or commit to diff against
- The main view updates to show the diff
- Press
<c-w>to toggle whitespace visibility in diffs - Press
}/{to increase or decrease diff context lines
Recipe 14: Create a fixup commit
- Stage your changes in the Files panel
- Press
<c-f>to find the base commit that your changes fix - Lazygit creates a fixup commit automatically targeting that base commit
- Later, use interactive rebase to autosquash fixup commits
6. Troubleshooting
Warning
Many issues are terminal-specific. If lazygit behaves unexpectedly, try running it in a different terminal emulator to isolate the problem.
Lazygit crashes on startup
Symptoms: Immediate crash or panic when launching lazygit.
Possible causes and solutions:
- Terminal incompatibility: Some newer terminals may have compatibility issues. If lazygit crashes in one terminal (e.g., Ghostty) but works in another (e.g., VS Code's integrated terminal), the issue is terminal-specific. Check for updates to both lazygit and the terminal. (See GitHub issue #5511)
- Symlinked directory: Opening lazygit when your current directory is a symlink to a git repo can cause crashes.
cdto the real path instead. (See GitHub issue #3015) - Corrupt config: Rename
~/.config/lazygit/config.ymltemporarily and retry with defaults. - Corrupt state file: Delete
$XDG_STATE_HOME/lazygit/state.ymlto reset state.
Keybinding not working during search
When the search prompt is active (/), some keybindings like q (quit) are consumed by the search input rather than their normal action. Press <esc> to close search first, then use the keybinding. (See GitHub issue #5520)
Option+Enter / Alt+Enter appends extra characters
On macOS, using Option+Enter to commit from the title field may insert an extra character (like "m") into the description field. This is a known terminal/keybinding interaction issue. Use <enter> instead, or commit via C to use your external editor. (See GitHub issue #5521)
Moving commits triggers unexpected panel switch
When using <c-j> to move a commit down during an interactive rebase, the view may sometimes jump to the diff files section instead. If this happens, press <esc> to return to the Commits panel and retry. (See GitHub issue #5517)
Rebase continuation popup persists
If you complete a rebase externally (e.g., in another terminal), lazygit may still show the "continue rebase" popup. Press <esc> to dismiss it, or press R to refresh the state. (See GitHub issue #5197)
Pull request integration shows 401 errors
If you use submodules with different GitHub credentials, the PR integration may fail with authentication errors. The PR fetch runs automatically and cannot currently be disabled via config. Ensure your GitHub credentials are configured correctly for all remotes. (See GitHub issue #5516)
PR integration fails with URL casing mismatch
If your remote URL uses different casing than the GitHub repository (e.g., uppercase vs. lowercase letters in the owner or repo name), PR lookups may fail. Ensure your remote URL matches the exact casing on GitHub. (See GitHub issue #5494)
Branch with empty name causes display issues
A branch with an empty name (which can be created through unusual git operations) may prevent the branch list from rendering correctly. Delete the problematic branch directly with git branch -d "" from the command line. (See GitHub issue #5112)
Caution
Running
lazygitinside a bare repository or a repository with a detached worktree requires explicit--work-treeand--git-dirflags. Without these, lazygit cannot locate your files.
Debug mode
To diagnose issues, run lazygit with debug logging enabled:
lazygit --debug
Or set the environment variable:
DEBUG=TRUE lazygit
To tail the logs in real time (in a separate terminal):
lazygit --logs
You can customize the log path with:
LAZYGIT_LOG_PATH=/tmp/lazygit.log lazygit
Set the log level for more or less verbosity:
LOG_LEVEL=debug lazygit
Performance issues
- Large repositories: Lazygit may feel sluggish in repos with thousands of changed files. Use path filtering (
lazygit --filter path/to/dir) to limit scope. - Auto-fetch: If network operations are slow, disable auto-fetch in config:
git:
autoFetch: false
- Auto-refresh: If you notice high CPU usage, check if your filesystem watcher is causing excessive refreshes. Press
Rto manually refresh instead of relying on auto-refresh.
7. FAQ
Q: How do I quit lazygit?
Press q to quit. If you want to quit and have your shell cd to the directory you were last browsing in lazygit, configure the promptToReturnFromSubprocess behavior. Press Q (shift) to quit without changing directory.
Q: Can I use lazygit with a bare repository? Yes, but you must specify the work tree and git directory explicitly:
lazygit --work-tree=/path/to/worktree --git-dir=/path/to/repo.git
Q: How do I customize keybindings?
Add a keybinding section to your config.yml. See the Admin Guide for the full keybinding configuration reference.
Q: Does lazygit support mouse input?
Yes, mouse support is enabled by default. Click on panels, files, commits, and other elements to select them. Disable it with gui.mouseEvents: false in your config.
Q: Can I open lazygit focused on a specific panel? Yes. Pass the panel name as a positional argument:
lazygit status # Open focused on Status panel
lazygit branch # Open focused on Branches panel
lazygit log # Open focused on Commits panel
lazygit stash # Open focused on Stash panel
Q: How do I filter the git log to a specific file or directory?
Use the --filter flag:
lazygit --filter src/main.go
Or press <c-s> inside lazygit to open the filtering menu.
Q: Can I use multiple config files?
Yes. Use the --use-config-file flag or LG_CONFIG_FILE environment variable with comma-separated paths:
lazygit --use-config-file base.yml,overrides.yml
Later files override earlier ones.
Q: How do I configure lazygit to use delta / diff-so-fancy / difftastic as my pager? Set the pager in your config:
# For delta
git:
paging:
colorArg: always
pager: delta --dark --paging=never
# For diff-so-fancy
git:
paging:
colorArg: always
pager: diff-so-fancy
Q: What are the screen modes?
Lazygit has three screen modes: normal (side panels + main view), half (enlarged main view), and full (main view only). Press + to cycle forward and _ to cycle backward. You can also start in a specific mode:
lazygit --screen-mode full
Q: Is there undo support?
Yes. Press z to undo and Z to redo. This uses git's reflog to reverse operations like commits, checkouts, and rebases. Not all operations are undoable.
Q: Can lazygit create GitHub pull requests?
Yes. In the Branches panel, press o to create a pull request for the selected branch, O to view PR options, and <c-y> to copy the PR URL to your clipboard.
Q: How do I open lazygit for a repo in a different directory?
Use the --path flag:
lazygit --path /path/to/other/repo
Q: What is the snake game?
Lazygit includes a hidden snake game easter egg. It exists in the source code under pkg/snake but discovery is left as an exercise for the curious.
Q: How do I change the interface language?
Set gui.language in your config. Supported languages: auto, en, zh-CN, zh-TW, pl, nl, ja, ko, ru, pt.