Git
Mercurial
Version Control
Search Commits
String Search

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.

bash
git log --grep="timeout"

This searches commit messages, not the code snapshot inside each commit.

You can make the output easier to scan:

bash
git log --grep="timeout" --oneline

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:

bash
git log -S"timeoutInterval"

Search by matching a regular expression in diffs:

bash
git log -G"timeout.*request"

These are different from --grep:

  • '--grep searches commit messages'
  • '-S searches for changes in the count of a literal string'
  • '-G searches 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:

bash
git grep "timeout" $(git rev-list --all)

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.

bash
hg log -k "timeout"

This is roughly analogous to Git commit-message search.

If you want a concise result:

bash
hg log -k "timeout" --template "{rev}:{node|short} {desc|firstline}\n"

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.

bash
hg grep -r "all()" "timeout"

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:

bash
git log -S"timeoutInterval" -- src/network/

Mercurial example:

bash
hg grep -r "all()" "timeout" src/network

This often turns a vague expensive search into a fast useful one.

Pick the Question Before the Command

A reliable mental checklist is:

  1. Do I mean commit message text
  2. Do I mean a change introducing or removing code text
  3. 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 --grep when the goal was to search code history, not commit messages.
  • Using git grep on the working tree and expecting it to search all revisions automatically.
  • Confusing -S and -G in 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 --grep for messages, -S or -G for change history, and git grep $(git rev-list --all) for snapshot-wide content searches.
  • In Mercurial, hg log -k is the message search baseline, and hg grep is 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.

Course illustration
Course illustration

All Rights Reserved.