5

I would like to search for a specific string using git grep but I would like to filter the results by using git blame to know that the string I'm looking for was changed by a specific person.

I just don't know how can I combine them to get the results I want.

Thank you for your help.

VaTo
  • 2,936
  • 7
  • 38
  • 77

2 Answers2

3

You can write a little shell script to accomplish this:

git rev-list --author=Doe HEAD |
while read rev; do
    if git show -p $rev | grep "PATTERN" >/dev/null; then
        echo $rev
    fi
done

This will output the SHA's that are reachable by HEAD that have an author of "Doe" and have "PATTERN" in the commit content's.

Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • Thank you @Jonathan.Brick I was just wondering if there's any way to do it without a script, I mean isn't there any git command that I can use to accomplish this? – VaTo Dec 03 '15 at 01:25
  • @SaulOrtega I did some googling and unfortunately I couldn't find one...it would be nice if git-grep had an --author option. But, perhaps you could wrap this command in an alias, called something like "grepAuthor" so you could easily invoke it without having to type out all that? – Jonathan.Brink Dec 03 '15 at 01:27
  • Inverting this by starting with `git grep` and piping to `git annotate` with an appropriate `-L` option might work a bit better... maybe. – Etan Reisner Dec 03 '15 at 03:06
0

This should do what you want.

author="Some User"
searchstring=string
searchfiles=(file1 file2 file3) # Leave empty for all files.

while IFS= read -rd '' file; read -rd '' nr; read -r line; do
    if git annotate -p -L "$nr,$nr" -- "$file" | grep -q "$author"; then
        printf '%s:%s:%s\n' "$file" "$nr" "$line"
    fi
done < <(git grep -nz "$searchstring" -- "${searchfiles[@]}")

Whether this works better/faster than Jonathan.Brink's answer is going to depend on the volume of matches for the line, the size of the history, where the author's commits live in the history, whether the change is in a more recent or less recent commit of the author's, etc.

Uses git grep -z to be safe for arbitrary file names and read -d '' to read those NUL-delimited fields.

Uses git annotate -L to limit lines that need annotation.

Output is the original git grep -n output but only for the author-matching lines.

Community
  • 1
  • 1
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • I still can't believe there's not a flag or a command to do this :( – VaTo Dec 04 '15 at 01:22
  • I can, in the sense that it makes a relatively cheap `grep` operation into a more expensive (and potentially **much** more expensive) annotate operation. That said it would certainly be handy for you in this case. You *might* be able to get away with `git log -S` if the string was added/removed in the revision you care about. – Etan Reisner Dec 04 '15 at 18:20