Introduction
Git provides git log --grep to search commit messages by keyword or regex pattern. This filters the commit history to only show commits whose messages match the given pattern. Combined with options like --author, --since, --all, and --format, you can narrow searches to specific contributors, time ranges, or branches. For searching code changes rather than messages, use git log -S (pickaxe) or git log -G (regex in diffs).
Basic Commit Message Search
1# Search for commits containing "fix" in the message
2git log --grep="fix"
3
4# Search for "refactor" — case sensitive by default
5git log --grep="refactor"
6
7# Case-insensitive search
8git log --grep="bug" -i
9# Or: git log --grep="bug" --regexp-ignore-case
Regex Patterns
1# Search using extended regex
2git log --grep="fix(ed|ing)" --extended-regexp
3
4# Or use Perl-compatible regex
5git log --grep="fix(ed|ing)" -P
6
7# Match commit messages starting with "feat:"
8git log --grep="^feat:" --extended-regexp
9
10# Match issue numbers like #123
11git log --grep="#[0-9]\+"
Combining Search Filters
1# Search by message AND author
2git log --grep="login" --author="Alice"
3
4# Search by message AND date range
5git log --grep="deploy" --since="2024-01-01" --until="2024-06-30"
6
7# Multiple grep patterns — OR logic (match either)
8git log --grep="fix" --grep="bug"
9
10# Multiple grep patterns — AND logic (match both)
11git log --grep="fix" --grep="auth" --all-match
12
13# Combine with file path — commits matching message AND touching file
14git log --grep="refactor" -- src/auth.py
1# One-line summary
2git log --grep="fix" --oneline
3
4# Custom format
5git log --grep="fix" --format="%h %an %ar %s"
6# Output: a1b2c3d Alice 3 days ago Fix login validation
7
8# Common format placeholders:
9# %h — abbreviated commit hash
10# %H — full commit hash
11# %an — author name
12# %ae — author email
13# %ar — author date, relative
14# %ad — author date (use --date=short for YYYY-MM-DD)
15# %s — subject (first line of commit message)
16# %b — body (rest of commit message)
17
18# Show full commit details with diff
19git log --grep="fix" -p
20
21# Limit number of results
22git log --grep="fix" -n 10
Searching Across All Branches
1# By default, git log only searches the current branch
2git log --grep="migration" --all
3
4# Search in a specific branch
5git log --grep="hotfix" origin/main
6
7# Search in all remote branches
8git log --grep="release" --remotes
9
10# Search including tags
11git log --grep="v2.0" --tags
Searching Code Changes (Not Messages)
1# -S (pickaxe) — find commits that add or remove a string
2git log -S "def authenticate" --oneline
3
4# -G — find commits where the diff matches a regex
5git log -G "TODO|FIXME" --oneline
6
7# Show the actual diff for matching commits
8git log -S "authenticate" -p
9
10# Combine with file filter
11git log -S "API_KEY" -- "*.py" --oneline
Interactive Search with grep
1# Pipe git log to grep for post-filtering
2git log --oneline | grep -i "deploy"
3
4# Search in full commit messages (not just subjects)
5git log --format="%H %B" | grep -B1 "breaking change"
6
7# Count commits matching a pattern
8git log --grep="fix" --oneline | wc -l
9
10# Search and show the commit hash only
11git log --grep="security" --format="%H"
Searching in a Date Range
1# Commits from the last week containing "update"
2git log --grep="update" --since="1 week ago"
3
4# Commits in January 2024
5git log --grep="release" --after="2024-01-01" --before="2024-02-01"
6
7# Human-readable dates work too
8git log --grep="fix" --since="last Monday"
9git log --grep="deploy" --after="yesterday"
Git Shortlog for Grouped Results
1# Group matching commits by author
2git shortlog --grep="fix"
3
4# Count fixes per author
5git shortlog --grep="fix" -sn
6# 15 Alice
7# 8 Bob
8# 3 Charlie
Common Pitfalls
Forgetting that --grep is case-sensitive by default: Searching --grep="Fix" will not match "fix" or "FIX". Add -i for case-insensitive matching. This is especially easy to miss when searching for keywords that authors capitalize inconsistently.
Expecting --grep to search code changes: --grep only searches commit messages. To find commits that changed specific code, use -S "string" (exact string in diff) or -G "regex" (regex in diff). These are different search modes that complement --grep.
Using multiple --grep without --all-match: By default, multiple --grep patterns use OR logic (match any). If you want commits matching ALL patterns, add --all-match. This is the opposite of what most developers expect.
Not searching all branches: git log --grep only searches the current branch by default. Commits on other branches or remote branches are invisible. Add --all to search the entire repository history across all branches and tags.
Confusing -S and -G: -S "string" finds commits where the number of occurrences of the string changed (added or removed). -G "regex" finds commits where the diff matches the regex. -S is for "when was this introduced/removed" while -G is for "when was this line changed".
Summary
Use git log --grep="pattern" to search commit messages by keyword or regex
Add -i for case-insensitive search and --extended-regexp for extended regex
Use --all-match to require all --grep patterns to match (default is OR)
Combine with --author, --since, --until, and -- <path> to narrow results
Use --all to search across all branches, not just the current one
Use -S or -G to search code changes in diffs rather than commit messages