Daily Git,
without losing the plot.
Replace repetitive CLI choreography with a visual feedback loop—while keeping the Git model you already trust. Learn defaults first, inspect every operation, keep the CLI as an escape hatch.
1 · Orientation: keep the model, replace the choreography
Lazygit is not another version-control system. It is a terminal UI that continuously renders Git state and attaches context-sensitive actions to whatever you select.
What changes
You stop composing routine commands and flags. Select a file, branch, commit, stash, tag, remote, submodule, or worktree; then invoke an action.
What stays
Index, working tree, refs, upstreams, reflog, merge/rebase state, and remote effects remain ordinary Git. Your CLI knowledge becomes the safety model.
Translation layer
| CLI instinct | Lazygit move | Why better here |
|---|---|---|
git status + git diff | Files panel + main diff | State and diff remain visible while acting. |
git add -p | Enter, then stage hunks/lines with Space | Patch boundaries and staged/unstaged sides stay visible. |
git log --graph … | Commits panel; enlarge with + | Navigate graph and act on selected commits. |
git rebase -i | i in Commits | Reorder and mark todos directly; no todo-file editing. |
git reflog recovery | z/Z, then inspect reflog if needed | Common ref/commit actions become stepwise undo/redo. |
2 · Install, verify, launch
macOS or Linux with Homebrew
brew install lazygit
lazygit --version
Common Linux packages
# Arch
sudo pacman -S lazygit
# Fedora family via COPR
sudo dnf copr enable dejan/lazygit
sudo dnf install lazygit
# Debian 13+ / Ubuntu 25.10+
sudo apt install lazygit
Distribution packages can lag. For current binary instructions, use the official README linked in Sources. Verify exact behavior with your installed version and ?.
Launch from any repository
cd path/to/repository
lazygit
# Optional shell alias
alias lg='lazygit'
Three checks before trusting daily use
- Open a clean disposable repository and press ? in Files, Branches, and Commits.
- Press @, expose command log, then stage and unstage a harmless file.
- Confirm external editor opens with e and commit-editor submission works: ⌘ Enter on macOS, Ctrl Enter on Linux; Ctrl S is alternate.
3 · Mental model: selection + context + preview
Most mistakes come from remembering a key but forgetting its panel. Same key can mean different operations. Read focused panel border, selected row, main preview, and footer together.
Status
Repository identity and recent repositories. Enter changes repo; a/A cycles all-branch logs.
Files
Working tree + index. Stage, discard, ignore, stash, fetch, commit, and enter patch staging.
Branches
Local branches plus tabs for remotes, tags, and worktrees. Checkout, create, rebase, merge, upstream, PR.
Commits
Selected branch history. Rewrite, fixup, cherry-pick, revert, reset, bisect, tag, compare.
Stash
Apply, pop, inspect, rename, drop, or create branch/worktree from a stash.
Main
Diff, graph, staging, patch builder, or conflict resolver. 0 focuses it; Esc returns.
5 · Daily workflow: inspect → stage → commit → sync
Default loop fits in Files panel plus global push/pull. Resist speed until state transitions feel obvious.
Routine, with verification
- Focus Files. Review every changed path and main diff.
- Stage whole files with Space; enter a file with Enter for hunk/line control.
- Use Tab in staging view to compare staged and unstaged halves.
- Press c. Write subject; use description only when useful. Submit.
- Focus Commits. Verify new commit contents with Enter.
- Pull using p, handle any integration, then push using P.
- Verify upstream indicator and Files cleanliness. If unclear, inspect @.
Range-select repeated objects
Press v, expand with arrows, then invoke supported action. Or hold Shift with up/down for non-sticky range selection. Useful for multiple files, commits, and cherry-picks.
6 · Precise staging: index as a designed commit
Whole-file staging is one Space. For mixed concerns, select file and press Enter.
| Staging context | Key | Effect |
|---|---|---|
| Files | Space | Toggle entire selected file staged. |
| Files | a | Toggle all files staged/unstaged. |
| Files | Enter | Enter staging view for selected file. |
| Staging main | h/l | Previous/next hunk. |
| Staging main | Space | Toggle selected line(s) or hunk staged. |
| Staging main | a | Toggle line-selection vs hunk-selection mode. |
| Staging main | v | Start range selection. |
| Staging main | Tab | Switch staged/unstaged view. |
| Staging main | E | Edit selected hunk in external editor. |
| Staging main | d | Discard unstaged selection; unstage staged selection. |
Commit-design recipe
- Enter first mixed file; stage only lines belonging to one intent.
- Repeat across files. Use Files status marks and staged preview to audit index.
- Commit. Remaining edits stay unstaged for next commit.
- Use @ once to connect UI action with underlying
git apply/git addbehavior.
7 · Commits: amend, fixup, and review-friendly cleanup
Last commit
Stage corrections, then A in Files. Equivalent intent: git commit --amend. Avoid after others depend on published hash unless coordinated.
Older commit
Stage corrections, select target in Commits, press A. Lazygit runs an interactive rebase to amend selected commit.
Review-visible fixup
Stage corrections, select target commit, press F. Creates fixup! or amend! commit so reviewer sees delta.
Autosquash before merge
Select first commit of branch, press S. Applies fixup commits above selection.
Find target commit automatically
Ctrl F analyzes blame/base information. Stage one concern first; mixed modifications can map to multiple base commits.
Commit-editor submit
Simple subject prompt submits with Enter. Multiline commit editor uses ⌘ Enter on macOS or Ctrl Enter on Linux; Ctrl S alternate. Terminal/multiplexer must forward modified Enter.
8 · Branches, remotes, and pull requests
| Task | Context + key | Guardrail |
|---|---|---|
| Create branch | Branches: n | Confirm selected starting point/current branch. |
| Checkout selected | Branches: Space | Dirty changes may travel or block checkout. |
| Previous branch | Branches: - | Equivalent intent to git switch -. |
| Checkout by name | Branches: c | Useful with many branches; input - means previous. |
| Rename | Branches: R | Published remote branch is separate state. |
| Delete | Branches: d | Menu distinguishes local and remote deletion. |
| Merge selected into current | Branches: M | Read current vs selected branch twice. |
| Rebase current onto selected | Branches: r | Rewrites current branch commits. |
| Upstream actions | Branches: u | Set/unset/reset-to-upstream menu. |
| Move accidental commits | Branches/Commits: N | Moves unpushed commits to new branch. |
| Fetch | Files or Remotes: f | Does not integrate current branch. |
| Pull / push | Global: p / P | May prompt to configure upstream. |
Remote tabs and PRs
Use [/] to reach Remote branches/Remotes tabs. Remote checkout with Space can create tracking local branch or detached HEAD. Remotes panel supports add n, edit e, remove d, fetch f, add fork F.
For GitHub, install/authenticate gh. Branches can show PR state. Use o to create PR, O for creation options, G to open existing PR, Ctrl Y to copy URL.
9 · Stash: temporary shelf, not mystery storage
| Task | Key | Semantics |
|---|---|---|
| Stash all quickly | Files: s | Creates stash entry. |
| Choose stash variation | Files: S | Menu includes all/staged/unstaged variants. |
| Inspect stash files | Stash: Enter | Preview before applying. |
| Apply, retain entry | Stash: Space | Like git stash apply. |
| Pop, remove on success | Stash: g | Like git stash pop. |
| Create branch from stash | Stash: n | Branches from stash base and applies content. |
| Create worktree from stash | Stash: w | Keeps current workspace untouched. |
| Rename / drop | Stash: r / d | Drop is not covered by lazygit undo. |
10 · Conflicts: resolve, verify, continue
Conflicted files appear in Files. Select one and enter main conflict resolver. Lazygit groups competing hunks and can auto-stage resolved files by default.
| Conflict action | Key | Use |
|---|---|---|
| Previous/next hunk | k/j | Move inside current conflict. |
| Previous/next conflict | h/l | Move between conflict groups. |
| Pick selected hunk | Space | Accept highlighted side. |
| Pick both hunks | b | Keep both; edit ordering/combination afterward. |
| Undo resolver choice | z | Conflict-resolver-local undo. |
| Edit/open file | e/o | Resolve semantics beyond side selection. |
| Conflict options | M | Context actions for current merge conflict. |
| Continue/abort/skip operation | m | Global merge/rebase options. |
11 · Rewrite history: interactive rebase without todo-file editing
In Commits, press i to start interactive rebase for current branch commits down to main/first merge boundary. Press e to start from selected commit. One-off rewrite actions can also start background rebase.
| Todo/action | Key | Meaning |
|---|---|---|
| Pick | p | Retain commit when mid-rebase. |
| Squash | s | Meld into commit below; append message. |
| Fixup | f | Meld into commit below; discard selected message. |
| Reword | r / R | Inline prompt / external editor. |
| Edit | e | Pause at commit for changes. |
| Drop | d | Remove selected commit. |
| Move | Ctrl K / Ctrl J | Move commit up/down. |
| Continue/abort/skip | m | Open operation menu. |
Rebase current branch onto another branch
- Checkout branch whose commits should move.
- Select destination/base branch in Local branches.
- Press r; choose normal or interactive option from menu.
- Resolve conflicts, then m → continue. Abort if assumptions fail.
- Review graph and tests before force-pushing rewritten published branch.
Rebase only commits above marked base
Uses git rebase --onto. Essential when feature branch was stacked on another feature branch and only its own commits should move.
12 · Cherry-pick, revert, reset, undo
Choose by intent
| Intent | Lazygit action | History effect |
|---|---|---|
| Bring selected commit(s) here | Commits/Reflog: C; destination commits: V | Creates new commit(s). Range selection supported. |
| Publicly negate commit | Commits: t | Creates revert commit; preserves history. |
| Move branch/index/tree to commit | Commits: g | Reset menu: soft/mixed/hard. Hard can destroy edits. |
| Undo recent ref/commit action | Global: z | Walks reflog-supported operations backward. |
| Redo lazygit undo | Global: Z | Walks forward through marked undo state. |
| Recover from known reflog point | Reflog tab: inspect, branch n or reset g | Manual recovery from reachable commit. |
Undo boundary
z/Z uses reflog. It can reason about commits, resets, rebases, and checkouts—including actions run outside lazygit. It cannot restore working-tree discards, stash operations, remote pushes, or branch creation. Undo is unsupported mid-rebase; use m and abort.
13 · Bisect: binary search through history
Use when test outcome is binary and a known-good commit precedes known-bad state. In Commits, press b for bisect options.
- Start from known bad state, select known-good commit, open b menu, mark good/bad as prompted.
- Git checks out midpoint. Run deterministic test outside lazygit or through :.
- Return to Commits, b, mark current commit good or bad.
- Repeat until culprit identified. Use b menu to reset bisect.
git bisect run ./test-command. Lazygit remains useful for graph inspection and manual classification.14 · Worktrees: parallel branches without stash churn
Worktree gives another working directory and index sharing repository objects and refs. Use for long-running feature, review checkout, urgent hotfix, or side-by-side test.
Create from branch/commit/tag
Select source and press w. Choose new worktree path/branch details. Current directory remains usable.
Manage Worktrees tab
n new, Space switch, o open editor, d remove.
Changing shell directory on exit
Lazygit can switch internally, but parent shell cannot normally be changed by child process. Official wrapper uses LAZYGIT_NEW_DIR_FILE; exiting with q changes directory through wrapper, while Q exits without changing.
lg() {
export LAZYGIT_NEW_DIR_FILE="$HOME/.lazygit/newdir"
lazygit "$@"
if [ -f "$LAZYGIT_NEW_DIR_FILE" ]; then
cd "$(cat "$LAZYGIT_NEW_DIR_FILE")" || return
rm -f "$LAZYGIT_NEW_DIR_FILE"
fi
}
15 · Submodules, tags, remotes, search, and comparison
Submodules
| Task | Key | Meaning |
|---|---|---|
| Enter nested repository | Enter | Esc returns to parent. |
| Initialize / update | i / u | Initialize metadata, then fetch/checkout configured commit. |
| Bulk options | b | Operate across submodules. |
| Add / update URL | n / e | Changes parent repository configuration. |
| Remove | d | Removes submodule and directory; review confirmation. |
Tags
Tags tab: n creates from current commit, Space checks out detached HEAD, P pushes selected tag, d offers local/remote deletion, w creates worktree, g resets to tag.
Search, filter, compare
- / filters some views and searches others. Search keeps context and uses n/N; filter narrows list.
- Files Ctrl B filters by staged/unstaged status.
- Global Ctrl S filters commit log, including file path.
- Select commit/ref and press W (or Ctrl E) to mark diff reference; choose another ref. Menu reverses direction or exits diff mode.
- {/} decreases/increases diff context. Ctrl W toggles whitespace. Ctrl T launches configured
git difftool. - |/\ cycles configured pagers forward/backward.
16 · Real-repo labs
All labs use disposable local repository. No network remote required. Commands create intentional history and conflicts; run only inside generated directory.
lab_dir="$(mktemp -d)/lazygit-lab"
mkdir -p "$lab_dir"
cd "$lab_dir"
git init -b main
git config user.name "Lazygit Student"
git config user.email "student@example.invalid"
printf '# Lazygit Lab\n' > README.md
printf 'mode=stable\n' > app.conf
git add README.md app.conf
git commit -m "Initialize lab"
printf '\nFirst note.\n' >> README.md
printf 'mode=fast\nfeature=off\n' > app.conf
lazygit
- Identify both changed files and inspect diffs.
- Stage only
README.md; commit “Document first note.” - Enter
app.conf; stage onlymode=fast; commit. - Leave
feature=offunstaged. Verify with Files and @.
# Start from lab repo after Lab 0
git switch main
git status --short
- Create
feature/togglefrom Branches with n. - Commit remaining
feature=offas “Add feature toggle.” - Change it to
feature=on. Stash using Files s; rename stash. - Apply with Stash Space, keeping entry. Stage correction.
- Select “Add feature toggle” commit, press F to create fixup commit.
- Select branch's first commit, press S to autosquash. Inspect graph.
- Drop retained stash only after verifying correction exists in history.
git switch main
printf 'color=blue\n' > theme.conf
git add theme.conf
git commit -m "Add blue theme"
git switch -c feature/theme
printf 'color=green\n' > theme.conf
git commit -am "Use green theme"
git switch main
printf 'color=amber\n' > theme.conf
git commit -am "Use amber theme"
lazygit
- In Local branches, select
feature/theme, press M, choose merge. - Enter conflicted
theme.conf. Navigate hunks and choose content. - Edit file if needed; final result must be one valid
color=…line. - Use m to continue merge. Inspect merge commit and run
cat theme.confthrough :.
git switch -c feature/history main
printf 'one\n' > one.txt
git add one.txt && git commit -m "Add one"
printf 'two\n' > two.txt
git add two.txt && git commit -m "Add two"
printf 'three\n' > three.txt
git add three.txt && git commit -m "Add three"
lazygit
- In Commits, press i. Reword “Add one”; swap last two with Ctrl K/Ctrl J; continue via m.
- Verify file semantics and graph. Undo entire rebase with z; redo with Z.
- Create branch
release/pickfrom main. - Find one feature commit, copy with C; checkout
release/pick; paste with V. - Inspect resulting new commit ID and content.
- Select
mainin Branches, press w, create sibling worktree namedreview. - Open Worktrees tab. Switch/open editor, then return to original worktree.
- Create several commits changing
result=good; one changes it toresult=bad; later commits add unrelated files. - Press b in Commits. Mark initial commit good and HEAD bad.
- At each midpoint run
grep -q '^result=good$' result.txt, then mark good/bad. - Identify culprit, reset bisect, verify original branch checkout.
17 · Troubleshooting and safety playbook
| Symptom | Likely cause | Action |
|---|---|---|
| Key does wrong thing | Wrong focused panel/context | Read focused border and footer; press ?. |
| Modified Enter ignored | Terminal/tmux lacks extended-key forwarding | Try Ctrl S; update terminal; configure tmux extended keys. |
| State looks stale | Refresh/fetch distinction | R refreshes local state; f fetches remote refs. |
| Cannot checkout branch | Dirty collision or branch checked out in worktree | Read error; stash/commit, or switch to owning worktree. Do not reflexively force checkout. |
| Push rejected | Upstream ahead/diverged or missing upstream | Fetch, inspect graph, choose pull/rebase/merge deliberately; set upstream via u. |
| Rebase/merge stuck | Unresolved conflicts or pending operation | Files → resolve; m continue/skip/abort. |
| Commit disappeared | Reset/rebase/drop changed branch | Try z; inspect Reflog; branch from known commit before experiments. |
| Discarded edit disappeared | Working-tree discard not in reflog | Check editor local history/backups. Lazygit undo cannot restore it. |
| PR actions unavailable | gh absent or unauthenticated | Install gh, run gh auth login; verify host/remotes. |
| Need unsupported operation | No built-in action | Use : for shell command, quit to CLI, or later define custom command. |
Five-second destructive-action pause
- Where? Focused panel and selected object.
- What state? Working tree, index, local ref, or remote?
- Recoverable? Reflog, stash, branch, backup, or none?
- Shared? Has commit/ref been pushed or consumed?
- Verify? What visible change and test confirms success?
18 · Comprehensive default-key reference
Curated for v0.63.0 daily and advanced operations. Press ? for complete context list in installed version.
Global + navigation
| Key | Action | Key | Action |
|---|---|---|---|
| ? | Context keybindings | q/Ctrl C | Quit |
| j/k | Next/previous item | h/l | Previous/next panel |
| 1…5 | Jump side panel | 0 | Focus main |
| Enter/Esc | Enter/return-cancel | [/] | Previous/next tab |
| / | Search/filter current view | n/N | Next/previous match |
| v | Sticky range select | Shift ↑/Shift ↓ | Extend range |
| ,/. | Previous/next page | </> | Top/bottom |
| K/J | Scroll main up/down | H/L | Scroll left/right |
| +/_ | Screen size next/previous | R | Refresh local Git state |
| p/P | Pull/push | : | Execute shell command |
| @ | Command-log options | Ctrl R | Recent repository |
| z/Z | Undo/redo | m | Merge/rebase operation menu |
| W/Ctrl E | Diffing options | Ctrl W | Toggle whitespace |
| {/} | Diff context −/+ | |/\ | Cycle pager forward/back |
| Ctrl T | External difftool | Ctrl O | Copy selected identifier/path |
Files + staging
| Key | Files action | Key | Files/staging action |
|---|---|---|---|
| Space | Stage selected file | a | Stage/unstage all |
| Enter | Enter line/hunk staging | Tab | Switch staged/unstaged main |
| c/C | Commit prompt/editor | A | Amend last commit |
| w | Commit without hook | Ctrl F | Find fixup base commit |
| s/S | Stash all/options | i | Ignore/exclude |
| d/D | Discard menu/reset menu | g | Upstream reset options |
| f | Fetch | M | Conflict options |
| ` | Tree/flat view | -/= | Collapse/expand directories |
| Ctrl B | Filter by status | e/o | Edit/open file |
| Space | Stage line/hunk in staging | a | Toggle line/hunk selection |
| E | Edit hunk | h/l | Previous/next hunk |
Branches + remotes
| Key | Branch action | Key | Branch/remote action |
|---|---|---|---|
| Space | Checkout selected | n | New branch/remote |
| c/- | Checkout by name/previous | F | Force checkout; Remotes: add fork |
| R | Rename branch | d | Delete branch/remote |
| r | Rebase current onto selected | M | Merge selected into current |
| f | Fast-forward; Remotes: fetch | u | Upstream options/set upstream |
| N | Move unpushed commits to new branch | w | Create/view worktree options |
| T | Create tag | s | Sort order |
| o/O | Create PR/options | G | Open PR in browser |
| Ctrl Y | Copy PR URL | Enter | View commits/remote branches |
Commits + reflog
| Key | Action | Key | Action |
|---|---|---|---|
| Enter | View files | Space | Checkout detached HEAD |
| i/e | Interactive rebase/from selected | p | Pick during rebase |
| s/f | Squash/fixup down | r/R | Reword inline/editor |
| d | Drop commit | Ctrl K/Ctrl J | Move commit up/down |
| F/S | Create/apply fixup commits | A | Amend selected with staged changes |
| C/V | Copy/paste cherry-pick | Ctrl R | Cancel copied selection |
| t | Revert commit | g | Reset options |
| B | Mark rebase base | b | Bisect options |
| T | Tag selected commit | n/N | Branch off/move unpushed commits |
| y | Copy commit attribute | o/G | Open commit/PR in browser |
| Ctrl L | Log options | * | Select current-branch commits |
| Ctrl P | Custom patch options | w | New worktree |
Stash + worktrees + submodules + tags
| Context | Key | Action |
|---|---|---|
| Stash | Space/g | Apply/pop |
| Stash | n/w | New branch/worktree from stash |
| Stash | r/d | Rename/drop |
| Worktrees | n/Space | New/switch |
| Worktrees | o/d | Open editor/remove |
| Submodules | Enter | Enter nested repo; Esc returns |
| Submodules | i/u/b | Initialize/update/bulk options |
| Submodules | n/e/d | Add/edit URL/remove |
| Tags | n/P/d | Create/push/delete |
| Tags | Space/w/g | Detached checkout/worktree/reset |
Main view + commit-file patch building + conflicts
| Context | Key | Action |
|---|---|---|
| Main normal | Tab/Esc | Switch staged/unstaged view; return to side panel |
| Main staging | h/l | Previous/next hunk |
| Main staging | a/v/Space | Line-vs-hunk mode/range select/toggle staged |
| Main staging | d/E | Discard or unstage/edit hunk |
| Commit files | c | Checkout file from selected commit into working tree |
| Commit files | d | Remove file's changes from commit via rebase |
| Commit files | Space/a | Toggle file/toggle all files in custom patch |
| Commit files | Enter | Enter line-level custom patch builder |
| Patch builder | h/l | Previous/next hunk |
| Patch builder | a/v/Space | Line-vs-hunk mode/range select/toggle patch lines |
| Patch builder | d | Remove selected lines from old commit via rebase |
| Conflict resolver | j/k | Next/previous hunk |
| Conflict resolver | h/l | Previous/next conflict |
| Conflict resolver | Space/b/z | Pick hunk/pick both/undo resolver choice |
| Any main mode | e/o/Ctrl T | Edit/open/use external difftool |
Less-frequent global/status controls
| Key | Action | Key | Action |
|---|---|---|---|
| Q | Quit without shell-directory change | Ctrl Z | Suspend application |
| Alt Shift C | Edit config externally | Status e | Edit config |
| Status u | Check for update | Status Enter | Recent repositories |
| Status a/A | Cycle all-branch logs forward/back | Ctrl S | Commit-log filter options |
| (/) | Rename similarity threshold −/+ | {/} | Diff context −/+ |
| Ctrl P | Custom patch options | Ctrl O | Copy current path/hash/name |
19 · Compact cheat sheet
Daily loop
Move & inspect
History
Safety
20 · Retrieval quiz, glossary, sources
Answer aloud before revealing. Mark honestly; score persists locally in this browser.
Glossary
- Focused panel
- Panel receiving keystrokes; shown with emphasized border.
- Main view
- Large preview/work area showing diff, graph, staging, patch, or conflict content.
- Range select
- Contiguous multi-selection, toggled with v or extended with Shift+arrows.
- Custom patch
- Selected files/hunks/lines from an old commit, used for history surgery through Ctrl P.
- Fixup commit
- Temporary
fixup!/amend!commit targeting earlier commit for later autosquash. - Marked base
- Commit selected with B delimiting commits moved by next rebase-onto.
- Nuke
- Destructive Files reset option removing everything visible in Git status, including dirty submodules.
- Reflog undo
- Lazygit's interpretation of ref/commit movements, navigated with z/Z.
Sources
Content verified against official tagged v0.63.0 source and installed v0.63.0 binary on 2026-07-20. External links require network; guide itself does not.
- Official lazygit README: features, installation, usage
- Official v0.63.0 default keybindings
- Official undo/redo behavior and limitations
- Official fixup/amend commit workflow
- Official range-selection behavior
- Official searching/filtering behavior
- Official stacked-branches guidance
- Official terminal compatibility notes