Reading history with git log

Git · Essentials · 9 min

Understanding why code is the way it is starts with reading its history.

git log lists commits from newest to oldest, starting at HEAD. The default output is verbose; these forms are more useful day to day:

  • git log --oneline: one line per commit (short hash and summary).
  • git log --oneline --graph --all: an ASCII graph of all branches, showing where they fork and merge.
  • git log -p path/to/file: every change to a file, with diffs.
  • git log -n 5 or -5: limit the count.

Filtering is where log gets powerful:

  • --author="Ada", --since="2 weeks ago", --until=2026-01-01.
  • --grep="invoice" searches commit messages.
  • -S "parseDate" (the "pickaxe") finds commits that added or removed that string, perfect for "when did this function disappear?".
  • main..feature shows commits on feature that are not on main.

git show <commit> prints one commit's metadata and diff; git show <commit>:path/file prints a file as it was in that commit.

git blame file annotates each line with the commit and author that last changed it. Use it to find the commit, then read that commit's message and diff for the why. git blame -w ignores whitespace changes, and -L 40,60 limits it to some lines.

Commits can be named many ways: a hash prefix, a branch or tag name, HEAD~2 (two commits back along first parents), or HEAD^2 (the second parent of a merge).

Example

git log --oneline --graph --all -15
git log --author="Ada" --since="1 month ago" --oneline
git log -S "parse_date" --oneline        # when was this added/removed?
git log --oneline main..feature          # commits only on feature
git show 3f9a2c1                         # one commit with diff
git show HEAD~2:src/app.py               # file as it was 2 commits ago
git blame -w -L 40,60 src/app.py         # who last touched lines 40-60

Remember

  • --oneline --graph --all gives a quick picture of the whole repo
  • -S finds commits that add or remove a string; --grep searches messages
  • A..B = commits reachable from B but not from A
  • blame finds the commit; its message tells you why

Watch out for

  • Treating git blame as finding who to blame — the last toucher is often just a refactor; follow the history further back.

Check yourself

  1. Which command finds the commit that removed calls to legacy_auth()?
  2. What does git log main..feature list?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History