Command Reference

git log Tutorial

Shows how git log inspects commit history, graph structure, authorship, and filtered history for debugging, review, and recovery.

Who This Is For
  • Developers who already know basic commit and branch actions
  • Readers who want to understand command boundaries and risk
Prerequisites
  • A basic mental model of worktree, index, and commits
  • Comfort reading `git status` and a small commit graph
Common Risks
  • Using local cleanup commands on already shared history
  • Continuing to rewrite before confirming a recovery path

The short version

git log is the main command for reading commit history and understanding how branches and commits actually relate.

Log is not only a list of commits

The highest-value use of git log is not memorizing old commit messages. It is learning the shape of history before you merge, rebase, reset, revert, or recover anything.

The daily high-value form

git log --oneline --graph --decorate --all

This single form gives you:

  • short commit IDs
  • visible branch structure
  • tags and branch labels
  • context across all refs

For many debugging or review tasks, this is the fastest first look.

What this command helps you decide

Use git log when you need to answer questions like:

  • what changed recently on this branch?
  • where did my branch diverge from main?
  • did this commit already land somewhere else?
  • what was the last good point before a mistake?
  • who introduced this sequence of changes?

That is why git log belongs in both everyday work and incident recovery.

Practical forms worth knowing

See the latest few commits

git log -5 --oneline

Filter by author

git log --author="Alice"

Follow one file's history

git log -- path/to/file

Compare branch-specific history

git log main..feature/login --oneline

That helps answer: “what commits are on my branch but not on main?”

How to use log before risky actions

Before history-changing commands, a reliable routine is:

  1. run git status
  2. run git log --oneline --graph --decorate --all -20
  3. identify the commit or ref you may need later
  4. only then rebase, reset, revert, or recover

This lowers the chance of acting on vague assumptions.

Diagram view

Where history inspection creates clarityInspection commands do not usually rewrite anything, but they decide whether your next history action is informed or blind.
Observed layers
Commit historyRefsBranch tipsPath history
Outputs
Visible ancestryReview contextRecovery target
The biggest win from `git log` is often not the output itself, but the bad decision it prevents.

Typical misunderstandings

  • git log does not show “the truth” independent of scope; it shows the history you asked for.
  • A simple linear log can hide branch shape, which is why --graph --decorate --all is so valuable.
  • File history and branch history answer different questions. Do not assume one replaces the other.
Reach for graph view early

If a repository feels confusing, add --graph --decorate --all before adding more filters. Structure usually matters more than clever filtering at the start.

Boundaries and related commands

git log is strongest when paired with:

  • git show for one commit in detail
  • git diff for exact change comparison
  • git reflog for local branch-tip movement and recovery

If git log shows something surprising, the next question is often not “is Git broken?” but “am I reading the right history scope?”

Do not confuse branch history with reflog history

git log shows commit ancestry. git reflog shows how your refs moved locally. They help with different debugging and recovery tasks.

Try it yourself

Custom format placeholders

The --format flag lets you define exactly what information git log displays. Git provides dozens of placeholders:

git log --format="%h - %an, %ar : %s"

Common placeholders

PlaceholderMeaning
%HFull commit hash
%hAbbreviated commit hash
%anAuthor name
%aeAuthor email
%adAuthor date (respects --date format)
%arAuthor date, relative
%cnCommitter name
%sSubject (first line of commit message)
%bBody (full commit message)
%DRef names (decorations like tags, branches)
%pParent hashes
%G?GPG verification status

Date formatting

git log --date=short --format="%h | %ad | %s"
git log --date=relative --format="%h | %ad | %an | %s"
git log --date=format:"%Y-%m-%d %H:%M" --format="%h | %ad | %s"

Pretty presets

git log --pretty=oneline      # hash + subject
git log --pretty=short        # hash, author, subject
git log --pretty=medium       # default
git log --pretty=full         # author + committer
git log --pretty=fuller       # all dates too
git log --pretty=email        # patch + email header format
git log --pretty=raw          # raw commit object
git log --pretty=format:"%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset"

The last example uses color codes (%Cred, %Creset, etc.) for rich terminal output.

Search history

Content search: -S

-S<string> finds commits where the number of occurrences of a string changed:

git log -S"TODO" --oneline
git log -S"api_key" --source --all

Useful for tracking when a specific piece of text was added or removed.

Content search: -G (regex)

-G<regex> finds commits where a diff line matches a regex:

git log -G"password" --oneline
git log -G"import.*from.*react" --oneline

Difference from -S: -G matches any changed line against the regex, while -S counts exact string occurrences.

Message search: --grep

Search commit messages:

git log --grep="fix" --oneline
git log --grep="bug" --grep="crash" --all-match --oneline
git log --grep="TODO" --regexp-ignore-case

--all-match requires all --grep patterns to match (AND logic).

Author and committer search

git log --author="Alice" --oneline
git log --committer="Bob" --oneline
git log --author="Alice" --since="2024-01-01" --oneline

You can also use --grep with --author to combine filters.

File tracking with --follow

When a file is renamed, git log normally stops at the rename. Use --follow to trace history across renames:

git log --follow -- src/old-name.ts

This follows the file through renames all the way back to its original name.

Important notes on --follow

  • Only works with one file path at a time
  • Only follows renames, not copies
  • Works best with git log --follow -p to see the actual changes
  • Does not work with --all or --branches simultaneously

Statistics output

--shortstat — minimal summary

git log --oneline --shortstat

Shows one summary line per commit:

a1b2c3d Fix login validation
 2 files changed, 15 insertions(+), 3 deletions(-)

--stat — per-file detail

git log --stat -3

Shows which files changed and how many lines per file, plus the overall summary.

--numstat — machine-friendly

git log --numstat -1

Useful for scripting and metrics dashboards.

Combined with filters

git log --author="Alice" --since="2024-01-01" --shortstat
git log main..feature --stat

Time range filtering

# Commits after a date
git log --since="2024-01-01" --oneline

# Commits before a date
git log --before="2024-06-30" --oneline

# Relative dates
git log --since="2 weeks ago" --oneline
git log --since="3 months ago" --before="1 month ago" --oneline

# Combined with author
git log --author="Alice" --since="2024-01-01" --oneline

# Since a specific tag
git log --since="v1.0" --oneline

Date formats accepted: YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, relative (2 weeks ago), and more.

Graph output with colors

Full graph with decorations

git log --oneline --graph --decorate --all

This is the most commonly useful graph view:

*   a1b2c3d (HEAD -> main) Merge feature/auth
|\
| * d4e5f6g (feature/auth) Add OAuth support
| * h7i8j9k Add JWT middleware
* | l0m1n2o Fix config loading
* | p3q4r5s Update dependencies
|/
* s6t7u8v (tag: v1.0) Release 1.0

Colored graph output

Git colors graph lines by default. You can enhance with:

git log --oneline --graph --decorate --all \
  --format="%C(auto)%h%d %s %C(green)(%cr)%Creset %C(bold blue)<%an>%Creset"

Graph for specific branches

git log --oneline --graph --decorate main..feature
git log --oneline --graph feature/login feature/api

Aliases for daily use

Add these to your ~/.gitconfig:

[alias]
  lg = log --oneline --graph --decorate --all
  lg10 = log --oneline --graph --decorate --all -10
  lgstat = log --oneline --graph --decorate --all --stat -5
Exercise: inspect branch divergence before integration

The goal is to use `git log` as a decision tool rather than a passive viewer.

Setup
git switch -c lab/log-demo
# create two commits on the branch
# move main forward with one different commit
Try it
  1. Run `git log --oneline --graph --decorate --all -12`.
  2. Run `git log main..HEAD --oneline` to see branch-only commits.
  3. Run `git log HEAD..main --oneline` to see what upstream has that you do not.
  4. Decide whether the next action should be merge, rebase, or wait.
What happens next
  • You can see branch divergence instead of guessing it.
  • You learn whether your branch is ahead, behind, or both.
  • Your next integration decision becomes evidence-based.
Common mistake checks
  • If the graph looks too simple, add `--all` and `--decorate` before drawing conclusions.
  • If the output looks empty, confirm you are comparing the intended refs.
  • If you need local recovery history, switch to `git reflog` instead of forcing `git log` to answer the wrong question.