How to grep (search) committed code in the Git history

后端 未结 15 1207

I have deleted a file or some code in a file sometime in the past. Can I grep in the content (not in the commit messages)?

A very poor solution is to grep the log:

相关标签:
15条回答
  • 2020-11-22 06:44

    My favorite way to do it is with git log's -G option (added in version 1.7.4).

    -G<regex>
           Look for differences whose added or removed line matches the given <regex>.
    

    There is a subtle difference between the way the -G and -S options determine if a commit matches:

    • The -S option essentially counts the number of times your search matches in a file before and after a commit. The commit is shown in the log if the before and after counts are different. This will not, for example, show commits where a line matching your search was moved.
    • With the -G option, the commit is shown in the log if your search matches any line that was added, removed, or changed.

    Take this commit as an example:

    diff --git a/test b/test
    index ffffdc242..60a8ba6 100644
    --- a/test
    +++ b/test
    @@ -1 +1 @@
    -hello hello
    +hello goodbye hello
    

    Because the number of times "hello" appears in the file is the same before and after this commit, it will not match using -Shello. However, since there was a change to a line matching hello, the commit will be shown using -Ghello.

    0 讨论(0)
  • 2020-11-22 06:45

    You should use the pickaxe (-S) option of git log.

    To search for Foo:

    git log -SFoo -- path_containing_change
    git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
    

    See Git history - find lost line by keyword for more.


    As Jakub Narębski commented:

    • this looks for differences that introduce or remove an instance of <string>. It usually means "revisions where you added or removed line with 'Foo'".

    • the --pickaxe-regex option allows you to use extended POSIX regex instead of searching for a string. Example (from git log): git log -S"frotz\(nitfol" --pickaxe-regex


    As Rob commented, this search is case-sensitive - he opened a follow-up question on how to search case-insensitive.

    0 讨论(0)
  • 2020-11-22 06:45

    git log can be a more effective way of searching for text across all branches, especially if there are many matches, and you want to see more recent (relevant) changes first.

    git log -p --all -S 'search string'
    git log -p --all -G 'match regular expression'
    

    These log commands list commits that add or remove the given search string/regex, (generally) more recent first. The -p option causes the relevant diff to be shown where the pattern was added or removed, so you can see it in context.

    Having found a relevant commit that adds the text you were looking for (for example, 8beeff00d), find the branches that contain the commit:

    git branch -a --contains 8beeff00d
    
    0 讨论(0)
  • 2020-11-22 06:45

    Whenever I find myself at your place, I use the following command line:

    git log -S "<words/phrases i am trying to find>" --all --oneline  --graph
    

    Explanation:

    1. git log - Need I write more here; it shows the logs in chronological order.
    2. -S "<words/phrases i am trying to find>" - It shows all those Git commits where any file (added/modified/deleted) has the words/phrases I am trying to find without '<>' symbols.
    3. --all - To enforce and search across all the branches.
    4. --oneline - It compresses the Git log in one line.
    5. --graph - It creates the graph of chronologically ordered commits.
    0 讨论(0)
  • 2020-11-22 06:45

    So are you trying to grep through older versions of the code looking to see where something last exists?

    If I were doing this, I would probably use git bisect. Using bisect, you can specify a known good version, a known bad version, and a simple script that does a check to see if the version is good or bad (in this case a grep to see if the code you are looking for is present). Running this will find when the code was removed.

    0 讨论(0)
  • 2020-11-22 06:48
    git rev-list --all | xargs -n 5 git grep EXPRESSION
    

    is a tweak to Jeet's solution, so it shows results while it searches and not just at the end (which can take a long time in a large repository).

    0 讨论(0)
提交回复
热议问题