Show git commit history as a graph
Render the commit DAG as an ASCII graph so branch topology — merges, forks, fast-forwards, and orphan tips — is visible at a glance, instead of the default linear `git log` that hides every parallel branch.
How to show git commit history as a graph in each shell
git log --graph --oneline --all --decorate`--graph` draws ASCII branch lines (`* | / \`); `--oneline` is `--pretty=oneline --abbrev-commit` combined (short SHA + first commit-message line); `--all` includes remote-tracking branches + tags, not just HEAD's history; `--decorate` annotates each commit with branch/tag refs. Drop `--all` for "only HEAD's history".
git log --graph --oneline --all --decorategit log --graph --oneline --all --decorateSame git binary; fish has no shell-side wrinkle. To force-color when piping into `less` (git's `color=auto` disables on a non-TTY pipe): `git log --color=always --graph --oneline --all | less -R` (`-R` makes less preserve ANSI sequences).
git log --graph --oneline --all --decorateSame git binary. pwsh's automatic paging is broken for native commands — explicitly pipe through `Out-Host -Paging` (`git log --graph --oneline --all | Out-Host -Paging`) or `less` if installed. To preserve ANSI colors when piping: `git -c color.ui=always log --graph --oneline --all | Out-Host`.
git log --graph --oneline --all --decorateSame git binary. cmd has no auto-pager — output dumps to the console buffer. Pipe through `more`: `git log --graph --oneline --all | more`. ANSI color escapes render natively on Windows 10 1809+ (cmd uses the new console host); older Windows shows raw `[33m` escape codes — pipe through `git --no-pager log` then accept monochrome.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **`--graph --oneline --all --decorate` is the canonical "show me the topology" combo.** Each flag is doing distinct work: `--graph` draws the ASCII branch lines (`* | * | * |/ * |`), `--oneline` collapses each commit to one row (`<short-sha> <subject>` — without this, every commit takes 5+ lines and the graph becomes unreadable), `--all` widens scope from "HEAD's ancestry only" to "every ref in `refs/`" (branches, tags, remotes — without `--all`, branches you're not on are invisible), `--decorate` (default since git 2.13 when output is a TTY, but explicit-is-better in pipes/scripts) appends `(HEAD -> main, origin/main, tag: v1.0)` annotations. Set it as an alias once: `git config --global alias.lg "log --graph --oneline --all --decorate"` → `git lg` everywhere.
- **`--simplify-by-decoration` for huge histories.** On a 10k-commit repo, even `--graph --oneline` produces 10k lines. `--simplify-by-decoration` collapses to only the commits that carry a ref (branch tip or tag) — a 50k-commit kernel history might reduce to 200 lines showing "what landed". Combine with `--all` for cross-branch topology. Skips merge commits that aren't decoration-relevant. Different from `--no-merges` (which excludes all merges, breaking the branch graph): `--simplify-by-decoration` keeps the topology accurate but shows fewer commits.
- **`--oneline` vs `--pretty=oneline` — easy to confuse.** `--oneline` is `--pretty=oneline --abbrev-commit` combined: SHORT SHA (7 chars by default) + subject line. `--pretty=oneline` alone gives FULL 40-char SHA + subject — much wider, defeats the purpose. Custom format for richer per-line info: `--pretty=format:"%C(yellow)%h%Creset %C(green)(%cr)%Creset %s %C(blue)<%an>%Creset"` (short SHA + relative date + subject + author). Reusable: `git config --global pretty.lg "format:%C(yellow)%h%Creset %C(green)(%cr)%Creset %s %C(blue)<%an>%Creset"` then `git log --graph --all --pretty=lg`.
- **Date and author filters narrow the view.** `--since="2 weeks ago"`, `--until=2026-01-01`, `--author=alice`, `--committer=ci-bot`, `--grep="fix"` (subject-line regex), `-S "deprecated"` (the "pickaxe" — commits where the string `deprecated` was added or removed in any file). Combine: `git log --graph --oneline --all --since="2 weeks ago" --author=alice`. The `--first-parent` flag (when run on a merge-heavy main branch) shows ONLY the main-line commits — the "what merged into main" timeline without the per-branch noise. Common in CI release-note generation.
- **When ASCII isn't enough, reach for a TUI.** `tig` (terminal git browser, `apt install tig` / `brew install tig`) gives a navigable graph with hjkl scrolling, in-place diff viewer, and blame integration. `lazygit` (modern Go TUI) layers staging/branching/rebasing on top. `gitk --all` (Tk GUI, ships with git) is uglier but always installed. For one-off "where did this branch fork from?" inspection, `git merge-base --fork-point main feature` returns the divergence SHA directly — combine with `git log <fork-point>..feature` for the linear "what this branch added" view.
Related commands
Related tasks
- Find which commit introduced a bug— Use `git bisect` to binary-search the history between a known-good and known-bad commit, narrowing thousands of commits to the single guilty one in log₂(N) steps.
- Show diff between two git branches— Compare two branches' code — for code review, "what did this feature change?" inspection, or merge-conflict preview. The two-dot vs three-dot syntax distinction silently changes what the diff INCLUDES.
- Show the current git branch— Print the name of the branch HEAD points at — used in shell prompts, CI build labels, and "deploy what's on the branch" scripts.