How to search through all Git and Mercurial commits in the repository for a certain string?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Searching version-control history can mean two very different things: searching commit messages or searching file content across past revisions. Git and Mercurial support both, but with different commands, and picking the right one matters because grep, log, and pickaxe-style searches answer different questions.
Git: Search Commit Messages
If you want to find commits whose messages contain a string, use git log --grep.
This searches commit messages, not the code snapshot inside each commit.
You can make the output easier to scan:
This is the right command for questions such as:
- "Which commit mentioned this bug ID"
- "When did someone say they fixed timeout handling"
Git: Search Code Changes Across History
If you want to know when a string appeared or disappeared in file content, use pickaxe-style searches.
Search by added or removed exact string occurrence:
Search by matching a regular expression in diffs:
These are different from --grep:
- '
--grepsearches commit messages' - '
-Ssearches for changes in the count of a literal string' - '
-Gsearches diff hunks by regex'
That distinction is the main thing people get wrong.
Git: Search the Full Snapshot of Every Commit
Sometimes you want to scan repository content across all commits, not just diffs. A brute-force but effective approach is:
This searches every reachable revision. It can be expensive on large repositories, but it answers a different question from git log -S.
Use it when you really mean:
- "show me every commit snapshot where this string exists"
not:
- "show me the commits that introduced or removed this string"
Mercurial: Search Commit Messages
In Mercurial, searching commit descriptions is typically done through hg log and revset filtering.
This is roughly analogous to Git commit-message search.
If you want a concise result:
That makes history review much easier on large repositories.
Mercurial: Search File Content in History
Mercurial also has hg grep, which can search through revisions.
This searches tracked file content through repository history. Depending on your version and options, you can scope revisions more narrowly if needed.
As with Git, ask first whether you want:
- commit-message search
- change search
- full content-history search
Those are not the same operation.
Narrow the Search When Possible
History searches can be expensive, especially on large monorepos. Narrow the scope by:
- file path
- date range
- branch
- author
Git example:
Mercurial example:
This often turns a vague expensive search into a fast useful one.
Pick the Question Before the Command
A reliable mental checklist is:
- Do I mean commit message text
- Do I mean a change introducing or removing code text
- Do I mean the presence of text in any historical snapshot
Once that is clear, the command choice becomes obvious.
Many "search all commits" questions are really asking about only one of those three categories.
Common Pitfalls
- Using
git log --grepwhen the goal was to search code history, not commit messages. - Using
git grepon the working tree and expecting it to search all revisions automatically. - Confusing
-Sand-Gin Git. - Running broad history searches on huge repositories without path or revision constraints.
- Assuming Git and Mercurial use identical semantics for similarly named commands.
Summary
- Decide first whether you are searching commit messages, diffs, or historical file contents.
- In Git, use
--grepfor messages,-Sor-Gfor change history, andgit grep $(git rev-list --all)for snapshot-wide content searches. - In Mercurial,
hg log -kis the message search baseline, andhg grepis the content-history tool. - Narrow the search by path or revision range when possible.
- The right search command depends on the question, not just on the repository tool.

