Skip to content

Searching Tools

Git offers several tools and commands for searching through your repository's history and content. These tools provide powerful capabilities for searching through your repository's history and content, allowing you to find specific commits, changes, or patterns quickly and efficiently.

git grep

The git grep command searches through the contents of files in the repository for a specific pattern. It supports options like --all-match to match all patterns, --ignore-case for case-insensitive searches, and --extended-regexp to use extended regular expressions.

git grep <pattern>: Searches for the specified <pattern> in the contents of tracked files within the Git repository.

Basic Usage

git grep "search_string"
This command searches for "search_string" in all tracked files in the repository.

Search in Specific Files

# Searches for "pattern" only in `file1.txt` and `file2.txt`.
git grep "pattern" file1.txt file2.txt

Options

  • -i or --ignore-case: Performs a Case-Insensitive Search.

    # Performs a case-insensitive search for "pattern".
    git grep -i "pattern"
    

  • -n or --line-number: Shows line numbers where the pattern is found.

    # Shows line numbers where "pattern" is found.
    git grep -n "pattern"
    

  • -w or --word-regexp: Search for Whole Words

    # Matches "pattern" as a whole word only.
    git grep -w "pattern"
    

  • -e <pattern>: Search for Multiple Patterns

    # Searches for both "pattern1" and "pattern2".
    git grep -e "pattern1" -e "pattern2"
    

  • --cached: Searches staged changes instead of working directory files.

    git grep --cached "pattern"
    

  • -I: Excludes files that match patterns from .gitignore and .git/info/exclude.

    git grep -I "pattern"
    

  • --untracked: Includes untracked files in the search.

    git grep --untracked "pattern"
    

  • --all-match: Only lines containing all of the specified patterns are matched.

    git grep --all-match "pattern1" "pattern2"
    
    By default, when you provide multiple patterns, git grep matches lines containing any of the provided patterns. With --all-match, only lines containing all patterns are considered matches.

  • --extended-regexp: This option allows you to use extended regular expressions (ERE) instead of the default basic regular expressions (BRE). Extended regular expressions provide additional features such as alternation (|), grouping (()), and quantifiers ({}, ?, *, +) which can make pattern matching more flexible and powerful.

    git grep --extended-regexp "pattern1|pattern2"
    

  • -c or --count: Only display a count of the lines that match the given pattern.

    git grep -c "pattern"
    
    This command searches for "pattern" in all tracked files and displays the total count of lines matching the pattern across all files, rather than displaying the actual matching lines themselves. This can be useful when you're interested in the total number of occurrences of a pattern across multiple files, rather than the specific lines where the pattern occurs.

  • -p or --show-function option in git grep allows you to display the surrounding function context of the matched lines, providing more context for each match. This can be particularly useful when searching through source code files where functions are defined.

    git grep -p "pattern"
    

git log

The git log command displays the commit history of the repository. It allows you to search for commits based on various criteria such as author, date range, commit message, and paths affected. You can use options like --grep to search for commits with specific patterns in their commit messages. Perhaps you’re looking not for where a term exists, but when it existed or was introduced. The git log command has a number of powerful tools for finding specific commits by the content of their messages or even the content of the diff they introduce.

git log --grep

To search the commit log (across all branches) for the given text:

git log --all --grep='Build 0051'

To do so while ignoring case in the grep search:

git log --all -i --grep='Build 0051'

To search the actual content of commits through a repo's history, use:

git grep 'Build 0051' $(git rev-list --all)
to show all instances of the given text, the containing file name, and the commit sha1.

And to do this while ignoring case, use:

git grep -i 'Build 0051' $(git rev-list --all)

Note that this searches the entire content of the commit at each stage, and not just the diff changes. To search just the diff changes, use one of the following:

git log -S (Git “pickaxe” option)

The -S option with git log allows you to search for commits that introduced or removed specific strings of text. It's useful for finding commits that added or removed specific functionality or code snippets.

git log -S "string" --oneline
If you need to be more specific, you can provide a regular expression to search for with the -G option.

git log -G

The -G option with git log allows you to search for commits that changed the number of occurrences of a specific regular expression. It's useful for finding commits that modified specific patterns in the codebase.

git log -G "pattern"

To illustrate the difference between -S --pickaxe-regex and -G, consider a commit with the following diff in the same file:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of that string did not change).

Unless --text is supplied patches of binary files without a textconv filter will be ignored.

git log with the -L option, and it will show you the history of a function or line of code in your codebase.

git log -L '/int main/',/^}/:main.c
#Shows how the function main() in the file main.c evolved over time.
For example, if we wanted to see every change made to the function git_deflate_bound in the zlib.c file, we could run

git log -L :git_deflate_bound:zlib.c 

This will try to figure out what the bounds of that function are and then look through the history and show us every change that was made to the function as a series of patches back to when the function was first created. You could also give it a range of lines or a single line number and you’ll get the same sort of output.

Using git log to Find File Deletion

Use git log -- : Replace with the path to the file you are interested in. This command will show the commit history that affected the specified file.

git log -- <file-path>
Identify Deletion Commit: Look through the output of git log to find the commit where the file was deleted. The commit message or diff in that commit should indicate the deletion.

commit abcdef1234567890abcdef1234567890abcdef12
Author: Author Name <author@example.com>
Date:   Thu Jun 1 12:00:00 2023 +0200

    Deleted file: example.txt

diff --git a/example.txt b/example.txt
deleted file mode 100644
index 1234567890abcdef1234567890abcdef12345678..0000000000000000000000000000000000000000
View File History Before Deletion: To see the history of the file leading up to its deletion, including its contents and changes, you can use the p option with git log:

git log -p -- <file-path>
This command displays the commit log along with the diff for each commit that affected the specified file. It helps in understanding how the file evolved and what changes led to its deletion.

Find Deletion in Specific Branch or Commit Range: If you suspect the deletion occurred within a specific branch or commit range, you can specify that range with git log:

git log -- <file-path>    # All history of the file
git log --since="3 months ago" -- <file-path>   # History within a time range
git log branch-name -- <file-path>   # History in a specific branch
Using git rev-list: Another approach is to use git rev-list with -max-parents=0 to find the first commit where the file was deleted:

git rev-list -n 1 --max-parents=0 HEAD -- <file-path>

git blame

The git blame command shows the revision and author of each line in a file. It's useful for identifying when and by whom each line was last modified. You can use it to track down the origin of specific changes.

git rev-list

The git rev-list command lists commit objects in reverse chronological order. It can be combined with other commands like git grep or git log to search for commits that match specific criteria. git rev-list is a powerful and flexible command in Git used to list commit objects in reverse chronological order. It can be applied in various ways, from simple listing of commits to more advanced filtering options. Here are some common uses of git rev-list with explanations and examples.

Basic Usage of git rev-list

git rev-list [options] [<commit>...]
  • <commit>: The starting point for listing commits. If none is provided, it defaults to HEAD.
  • Options: A variety of options are available to control the output, such as limiting the number of commits, excluding certain commits, or showing only merge commits.

Common Use Cases


List All Commits in a Branch

This is the most basic use of git rev-list. You can list all the commits in the current branch (or any other branch) in reverse chronological order.

Example:

git rev-list HEAD

This lists all commits from the current HEAD to the beginning of the history.


Limit the Number of Commits

You can limit the number of commits returned by using the --max-count option.

Example:

git rev-list HEAD --max-count=5

This command lists the most recent 5 commits from the current HEAD.


List Commits Between Two Branches

git rev-list can also be used to show commits that are unique to one branch compared to another.

Example:

git rev-list branchA --not branchB

This shows all the commits that exist on branchA but are not present on branchB.


List Commits Within a Time Range

You can filter commits by specifying a date range using the --since and --until options.

Example:

git rev-list HEAD --since="2 weeks ago"

This command lists all commits from the last two weeks.

You can also combine --since and --until to specify a more specific date range:

git rev-list HEAD --since="2023-01-01" --until="2023-02-01"

List Commits by Author

You can filter commits by a specific author using the --author option.

Example:

git rev-list HEAD --author="John Doe"

This lists all commits authored by "John Doe" in the current branch.


List Commits with a Specific Message

If you're looking for commits with a particular keyword in the commit message, use the --grep option.

Example:

git rev-list HEAD --grep="fix bug"

This will list all commits whose commit messages contain "fix bug".


List Only Merge Commits

Sometimes you want to list only merge commits. This can be done using the --merges option.

Example:

git rev-list HEAD --merges

This will show only the merge commits in the current branch.


List Commits That Introduced a Specific File

You can use git rev-list to trace the history of a file to find out when it was introduced or modified.

Example:

git rev-list HEAD -- <file-path>

This lists all commits that modified the specified file.


List Commits that Changed Files in a Given Directory

If you want to list the commits that modified files in a specific directory, you can provide the directory path.

Example:

git rev-list HEAD -- path/to/directory/

This shows all commits that affected the files in the specified directory.


Find Commits That Introduced a Bug (via Bisecting)

You can use git rev-list in combination with git bisect to find a bug in the code by reviewing only a subset of commits.

Example:

git bisect start HEAD <bad-commit>
git rev-list --bisect HEAD <bad-commit>

This can help you narrow down the range of commits to find the specific one that introduced the issue.


Counting Commits

If you want to know how many commits exist in a certain range or branch, you can combine git rev-list with --count.

Example:

git rev-list --count HEAD

This outputs the total number of commits in the current branch.


View the SHA-1s of all Parents of a Commit

You can view the parent commits for a given commit using git rev-list.

Example:

git rev-list --parents HEAD

This will display each commit and its parent(s). For merge commits, more than one parent will be shown.


Advanced Options

--all-match

  • Use --all-match to show only the commits that match all the given --grep and --author conditions.

Example:

git rev-list HEAD --grep="fix" --author="John" --all-match

This lists commits where the message contains "fix" and the author is "John".


--extended-regexp

  • This option enables the use of extended regular expressions in commit message filtering.

Example:

git rev-list HEAD --grep='(fix|bug)' --extended-regexp

This command lists all commits where the message contains either "fix" or "bug".


--bisect

  • The --bisect option is used to mark commits for binary searching (bisecting) to find which commit introduced a bug or a feature.

Example:

git rev-list --bisect <bad-commit>

This shows the list of commits to be tested during a bisect operation to locate an issue.

git show

The git show command displays information about a specific commit. You can use it to view the changes introduced by a commit and search for specific patterns within those changes.

These tools provide powerful capabilities for searching through your repository's history and content, allowing you to find specific commits, changes, or patterns quickly and efficiently.