Search code examples
gitsearchgrepdiff

Git search all diffs


I'm trying to search for changes in my git history relating to a very specific variable name.

I've tried doing this:

git diff HEAD~25000 | grep -in mydistinctvariablename

The results don't tell me which commit the result lines are from and it takes quite a bit of time (about 5-7 minutes).

Does anyone have a better solution, time and results wise?


Solution

  • git log is generally the command to use when examining commit history. git log --grep can be used to search for regular expressions in the commit message.

    What you are after is git log -S which searches the commit content simply or git log -G which searches it with a regular expression:

    -S<string> Look for differences that introduce or remove an instance of <string>. Note that this is different than the string simply appearing in diff output; see the pickaxe entry in gitdiffcore(7) for more details.

    So, for instance, in the msysGit repository I can find the commit that introduced Tcl 8.5.8 using either:

    C:\src\msysgit\src>git log --oneline --grep "8\.5\.8"
    d938476 Make `NO_SFX=1 portable-release.sh` work
    ef1dc94 Update tk to version 8.5.8
    a910049 Update tcl to version 8.5.8
    a702d7f tcltk: update to 8.5.8 and exclude release.sh from the cleanup list
    

    which just looked for 8.5.8 in the commit messages or as you want to do looking at a string that only occurred in the committed diff:

    C:\src\msysgit\src>git log --oneline -S"version=8.5.8"
    7be8622 tcltk: update release.sh script for tcl/tk 8.5.9
    a702d7f tcltk: update to 8.5.8 and exclude release.sh from the cleanup list
    

    The range limiting you have in your sample can still be used here to limit the commits to be examined. Read though the git log manual carefully to get a good idea of all the things it can do.

    Note that -S just looks for simple string differences - if you really want to search the content using a regular expression similar to you example then you should use the -G option instead of -S but this will be significantly slower.