By admin , 28 April 2026

Introduction

git log walks the commit graph from a starting point (default: HEAD) backwards through parents, printing each commit. It is the primary tool for exploring project history.

Basic usage

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

The last form is the swiss-army view: a compact graph of every branch with refs decorated.

Filtering by date, author, message

git log --since="2 weeks ago"
git log --until=2025-01-01
git log --author="Ada"
git log --grep="bugfix"
git log -S "deprecated_function"   # pickaxe: when did a string appear?

-S is invaluable for archaeology: it finds commits that change the number of occurrences of a string in any file.

Showing diffs

git log -p                 # full patch per commit
git log --stat             # files changed plus +/- counts
git log --shortstat        # summary line only
git log -p -- path/to/file # only commits touching a path

Custom formats

--pretty=format: accepts placeholders. A useful one-liner:

git log --pretty=format:"%h %an %ad %s" --date=short

%h abbreviated hash, %an author name, %ad author date, %s subject. See git help log for the full list.

Limits and ranges

git log -n 5                       # last 5 commits
git log main..feature              # commits on feature not on main
git log main...feature             # symmetric difference
git log feature ^main              # same as main..feature

Following file renames

Git does not record renames, it detects them. To follow history across a rename:

git log --follow -- path/to/file

Useful aliases

A handful of git log aliases pay for themselves in the first week. Two especially good ones:

git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.last "log -1 HEAD --stat"
git config --global alias.recent "log --since='2 weeks ago' --author=$(git config user.email)"

git lg gives the bird's-eye graph; git last shows what just happened; git recent answers "what have I worked on lately?". Add an alias for any log invocation you type more than twice.

Reverse and limit

By default git log walks newest to oldest. Sometimes (release notes, code archaeology) you want the opposite, paired with a clean format:

git log --reverse --oneline v1.0.0..v1.1.0
git log --reverse --pretty=format:"* %s (%h)" v1.0.0..HEAD > CHANGELOG.draft

This is also where pickaxe and path filters earn their keep: git log --reverse -S "old_api" -- src/ shows the chronological history of a string's appearance and disappearance, perfect for tracing deprecations.

Common mistakes

Reading only HEAD's history and missing commits on other branches; pass --all to see them. Confusing --author (a regex on the author field) with a literal exact match; quote the pattern carefully. Using git log file instead of git log -- file: the -- separator disambiguates paths from refs, especially if a branch and a file share a name. Finally, expecting git log to show deleted commits after a force-reset; use git reflog for that. git log only walks reachable history.