Advanced git log Options
The basic git log page got you walking. This page teaches you to run. Real investigations are rarely "show me the last 10 commits" — they look more like "show me every commit Alice made last week that touched the auth module and didn't merge a branch." Once you internalise the filter families below, you can compose surgical queries against any repo.
Revision range filters
A range tells git log which slice of history to walk. The notation looks cryptic at first but maps to a small set of set operations.
Syntax | Meaning |
|---|---|
| Commits reachable from |
| Symmetric difference — commits in either branch, but not both |
| Commits in |
| In |
| Only commits that lie on a direct ancestry chain from A to B |
Range filters in practice
# What's on feature that main hasn't got yet? git log main..feature --oneline # Symmetric: commits unique to either side of a divergence git log main...feature --oneline --left-right # < unique to main (left) # > unique to feature (right) # Everything since the v1.0 tag git log v1.0..HEAD --oneline # Strict ancestry — useful when a commit was cherry-picked into many branches git log --ancestry-path 1f9ab2c..HEAD
Sample --left-right output
< 1f9ab2c Fix login redirect < d4b1e0c Update README > 5a2c7e3 Add validation helper > 2c1f8d9 Sketch feature-x API
Filtering by author and committer
Git distinguishes the author (who wrote the change) from the committer (who put it in this branch). Rebases and cherry-picks keep the author but change the committer.
git log --author="Alice" # substring match on author git log --author="alice@example.com" git log --author="Alice\|Bob" # regex OR git log --committer="release-bot" # who actually landed it git log --perl-regexp --author='^(?!Alice).*' # everyone except Alice
Output of git log --author=Alice --oneline
1f9ab2c Add login form validation b3a9f00 Tighten password rules 5a2c7e3 Add validation helper
Filtering by date
Date flags accept ISO dates, English phrases, and relative expressions. --since/--after are aliases; so are --until/--before.
git log --since="2 weeks ago" git log --since="2026-01-01" --until="2026-03-31" git log --after="yesterday" --before="now" git log --since="midnight" # today's commits git log --since="last monday"
Filtering by commit message
--grep matches the commit message
git log --grep="bugfix" git log --grep="fix" --grep="auth" --all-match # both must appear git log --grep="fix" --grep="auth" # either may appear (default OR) git log --invert-grep --grep="typo" # everything EXCEPT typo commits git log -i --grep="LOGIN" # case-insensitive git log -E --grep="^fix\(auth\):" # extended regex
The pickaxe: searching diffs
--grep searches messages. The pickaxe searches changes. Use it when you want "the commit where this code first appeared" or "when did we delete this config key?"
Flag | What it finds |
|---|---|
| Commits where the count of occurrences of |
| Commits where any line matching |
| Treat |
| Show all changes in matching commits, not just the matching ones |
Pickaxe in action
# When was this exact string added or removed? git log -S "SecretAPIKey" --oneline # Regex flavour — any line matching this regex changed git log -G "function\s+login" --oneline # Combine with -p to see the actual diffs git log -S "DEPRECATED_FLAG" -p # Track a constant across renames too git log --follow -S "MAX_RETRIES" -- src/
Typical -S output
a1b2c3d Remove legacy SecretAPIKey constant 9f8e7d6 Introduce SecretAPIKey for v1 auth
Filtering by path
# Everything touching one file git log -- src/auth/login.js # Follow renames — single file only git log --follow -- src/auth/login.js # Glob across the tree git log -- "**/*.test.js" # Multiple paths git log -- src/auth/ tests/auth/ # Filter by change type: A=added, M=modified, D=deleted, R=renamed git log --diff-filter=A -- src/ # commits that ADDED files in src/ git log --diff-filter=D -- src/ # commits that DELETED files in src/ git log --diff-filter=ADM --oneline
Topology filters
git log --no-merges # hide merge commits git log --merges # only merge commits git log --first-parent # follow only the mainline through merges git log --first-parent main # main's "official" history git log --min-parents=2 # commits with 2+ parents (merges) git log --max-parents=1 # non-merge commits only
--first-parent is the single most useful flag for reading the history of a long-lived branch — it shows you the merges into main without diving into each feature branch's internal commits.
Combining filters
Real-world combinations
# Everything Alice committed last week, no merges git log --author="Alice" --since="1 week ago" --no-merges --oneline # Every commit that touched login.js with "fix" in the message git log --grep="fix" --oneline -- src/auth/login.js # Bug-fix commits in the v2.0 release window git log v1.9..v2.0 --grep="^fix" -E --oneline # Commits that added or removed the FEATURE_FLAG_X string in tests git log -S "FEATURE_FLAG_X" --oneline -- tests/ # Mainline release history with dates git log --first-parent --pretty="%h %ad %s" --date=short main
Real-world recipes
Recipe: everything Alice did last week
git log \ --author="alice@example.com" \ --since="1 week ago" \ --no-merges \ --pretty="%h %ad %s" \ --date=short
Sample output
1f9ab2c 2026-05-13 Fix login redirect on safari b3a9f00 2026-05-14 Tighten password rules 5a2c7e3 2026-05-15 Add validation helper
Recipe: every commit that ever touched login.js (even before rename)
git log --follow --oneline -- src/auth/login.js
Recipe: when did we stop using deprecated SHA1Hash?
git log -S "SHA1Hash" --diff-filter=D -p