How do you search for a given string inside many different files? If you’re familiar with the command line, you have the answer on the tip of your tongue: grep. You may know that there is a Git-specialized version of grep called the git grep command.
This post is going to teach you about this command. You’ll learn what it is, how it differs from the regular grep, and how to use it in various situations.
Let’s get started.
The requirements for following along with this post are simple. We assume you:
- are comfortable working with the command line
- know at least some basic Git commands
- has Git installed
We don’t make any assumptions regarding your operating system. I’m currently on Ubuntu as I write this, but the commands should work for Windows and Mac as well. We also don’t assume you have any previous knowledge or experience with grep.
Git Grep: The Fundamentals
As promised, let’s start with some fundamentals of Git Grep. What is this command about and what can you do with it? Let’s cover that now.
What Is Git Grep?
git grep command is a specialized version of the famous
grep command. Similarly to its general counterpart, git grep allows you to search for a given string pattern inside files, finding the lines that match the specified patterns.
But since grep already exists, why would you use its git counterpart? We’ll cover that in more detail later, but one of the reasons has to do with which files you can search when using git grep. That leads us to the next section.
What Files Can Be Searched in Using Git Grep?
One of the differences between git grep and the regular grep command has to do with what files you can search in using each command. Regular grep will search through all files matching the specified patterns.
Git grep, on the other hand, has its preferences. It only searches files that Git knows about. What does that mean?
Git grep will search through files:
- tracked by existing commits
- added to the stage
- exist in the working directory
Most importantly, git grep allows you to search files in different branches or in different points from the repo’s timeline. This makes the command incredibly powerful and flexible, setting it apart from regular grep.
Git Grep vs Regular Grep: How Do They Compare?
Having touched briefly on this before, let’s now go into more detail about the differences between the git grep command and the regular grep.
First, let’s talk about speed. If you’re searching for files that you know are part of a Git repo, then the command
git grep is faster. That’s because it only searches inside files that are part of the repository, making the search surface area way smaller.
Most importantly, git grep allows you to search files in different branches or in different points from the repo’s timeline.
The two commands are also different when it comes to the actual syntax and options they support. We won’t go into much detail here since, as we promised, the post doesn’t assume you have prior knowledge of the regular grep command.
Finally, as we’ve said before, a big difference between the two (and a big advantage of git grep) is the ability to charge in any branch, commit, or range of commits.
Let’s now walk you through some examples of practical examples of
git grep usage. Example #1 Let’s start by creating a directory, accessing it, and starting a new repository:
$ mkdir grep-demo $ cd grep-demo $ git init
Now, let’s add some files and commits:
$ echo 'hello world' > file1 $ git add file1 $ git commit -m "add first file" $ echo 'goodbye world' > file2 $ git add file2 $ git commit -m "add second file"
You’re now ready to test git grep for the first time. Just run:
$ git grep hello
You should see an output saying that the “hello” string was found inside file “file1”:
Now, let’s add more stuff to that file:
$ echo 'a second line' >> file1 $ echo 'a third line' >> file2 $ git commit -am "more stuff on file1"
Use the command to search for the word “second”:
$ git grep second
The result should look similar:
file1:a second line
Notice that the result doesn’t contain line numbers. Not a problem in our situation since the file is very small. But with a larger file, that would certainly hurt. So, that leads us to the next example.
Example #2: Seeing Line Numbers
Run the following command:
$ git grep -n second
Now the output looks like this:
file1:2:a second line
So, by using the
-n flag, we can make sure number lines appear in the result. However, if you’re like me, you’d like to see the line numbers all the time, so using the flag might get old first. Luckily, there is a way to configure this:
$ git config --global grep.lineNumber true
By setting the
grep.lineNumber config option to true, we ensure line numbers are always displayed.
Example #3: Searching in a Specific Commit
For the next example, we will delete the first file and commit that:
$ rm file1 $ git commit -am "delete file1"
If you now run git grep hello, it won’t find anything, which makes sense. But let’s do this instead:
$ git grep hello HEAD~1
By running the command above, you’ll see that the result now displays the found string inside file1. In this case, we’re using
HEAD~1 to say we want to search in the commit before the last one (that is, HEAD.) If you wanted to search in the commit before that, we’d use
HEAD~2, and so on.
Of course, you can also use the hash of the commit and it’d work just as fine.
Example #4: Searching in Another Branch
For the next example, let’s create a new branch, add a new file and commit that file:
$ git checkout -b new $ echo foo > file3 $ git add file3 $ git commit -m "commit in new branch" $ git checkout master
Now we’re back in master; let’s use git grep to search for the string “foo” in the new branch:
$ git grep foo new
You’ll see the result containing the line number.
Example #5: Searching Through Several Commits
A great example of the power of the git grep command is the ability to search through various commits. You can, for instance, specify several different commits you want to search into:
$ git grep hello HEAD HEAD~1 new
In the example above, we’re searching into the tip of the current branch (
HEAD), the commit before that (
HEAD~1), and the commit that the new branch currently points at.
Instead of using references, you could use the ids of the commits to identify them directly.
Git Grep to the Rescue
Git grep is a flexible and powerful command you can use to search through files, similarly to the regular grep command. However, it has capabilities that surpass its regular GNU counterpart. In this post, we’ve walked you through the git grep command, explaining what it does, how it differs from regular grep and giving several usage examples. Feel free to explore the command’s capabilities even further, including how to use regular expressions to perform even more powerful searches.