Git Grep: Repository-Aware Search
Search tracked content, index entries, committed trees, and selected untracked files with Git-aware patterns and pathspecs.
Advanced
Learner goal
By the end of this lesson, you should be able to use `git grep` to search tracked working-tree content, the index, committed trees, and selected untracked files; constrain searches with pathspecs; and choose focused matching options without confusing Git-aware search with ordinary recursive shell search.
What `git grep` searches
With no special source option, `git grep` searches tracked files in the working tree. Git can instead search blobs registered in the index with `--cached`, or blobs in one or more tree objects by naming the tree. These modes let you compare the content you are currently editing with staged or committed content without first exporting it.
git grep 'pattern'
git grep --cached 'pattern'
git grep 'pattern' HEADQuick check
Which source does `git grep --cached` search?
Stage a line that is not yet in HEAD.git grep --cached 'that line'
Working tree, index, and committed tree are different sources
The distinction matters when the same path has different content in different Git states. A normal `git grep` sees the tracked working-tree version; `--cached` sees the index version; and a tree argument such as `HEAD` searches the blobs stored in that tree. The command is therefore useful for asking a precise content question about a precise repository state.
git grep 'feature'
git grep --cached 'feature'
git grep 'feature' HEADQuick check
Why can `git grep 'feature'` and `git grep --cached 'feature'` produce different results for the same path?
Limit the search with a pathspec
Put `--` before pathspecs when you want an unambiguous boundary between options or the search pattern and paths. A pathspec can narrow the search to a directory or matching path pattern. This is often safer and more useful than searching the whole repository when you already know where the relevant content lives.
git grep 'TODO' -- src/
git grep 'TODO' -- 'src/*.c'Quick check
What is the purpose of `--` before the pathspec in these examples?
Useful matching controls
`-n` adds line numbers, `-i` ignores case, `-l` reports only filenames containing matches, and `-F` treats the pattern as a fixed string rather than a regular expression. These options answer different questions: where is the match, does capitalization matter, which files match, or should punctuation be interpreted literally?
git grep -n -i 'warning'
git grep -l 'deprecated'
git grep -F 'a.b'Quick check
Which option makes `git grep` print only filenames containing a match?
Searching untracked files deliberately
Normal `git grep` searches tracked working-tree files. `--untracked` adds untracked files to that search. Ignored files are still excluded by the normal ignore rules; the official manual provides `--no-exclude-standard` for deliberately including ignored files when using `--untracked`. Use this distinction intentionally so a repository search does not silently become a search of generated or ignored material.
git grep --untracked 'TODO'
git grep --untracked --no-exclude-standard 'TODO'Quick check
What does `--untracked` add to the search?
When `--no-index` is appropriate
`--no-index` tells Git to search files without treating the current directory as a Git repository. The official manual describes it as similar to recursive ordinary `grep`, with Git pathspec benefits. It cannot be combined with `--cached` or `--untracked`. This is a useful boundary case, but it should not obscure the main purpose of `git grep`: repository-aware content search.
git grep --no-index 'pattern' path/to/fileQuick check
Which combination is invalid according to the official `git grep` documentation?
A precise investigation workflow
When investigating a repository-wide text question, first decide which state you need to search. Use the default mode for tracked working-tree content, `--cached` for staged content, a tree such as `HEAD` for committed content, and `--untracked` when untracked files are intentionally in scope. Then narrow paths and add only the output or matching options needed for the question.
git grep -n 'needle' -- src/
git grep --cached -n 'needle' -- src/
git grep -n 'needle' HEAD -- src/Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official source boundary
This lesson uses the official Git `git-grep` documentation for command semantics, options, source-selection modes, pathspec behavior, and constraints. No third-party documentation is used for the command semantics.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.