Skip to content

Instantly share code, notes, and snippets.

@lonnen
Created July 12, 2012 23:24
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save lonnen/3101795 to your computer and use it in GitHub Desktop.
Save lonnen/3101795 to your computer and use it in GitHub Desktop.
git grep and git blame. two great tastes that taste great together
# from i8ramin - http://getintothis.com/blog/2012/04/02/git-grep-and-blame-bash-function/
# runs git grep on a pattern, and then uses git blame to who did it
ggb() {
git grep -n $1 | while IFS=: read i j k; do git blame -L $j,$j $i | cat; done
}
# small modification for git egrep bash
geb() {
git grep -E -n $1 | while IFS=: read i j k; do git blame -L $j,$j $i | cat; done
}
@lonnen
Copy link
Author

lonnen commented Jul 12, 2012

usage looks like ggb "someClass" or geb "[[:space:]]+$"

@lonnen
Copy link
Author

lonnen commented Jul 12, 2012

Combine with awk for a simple scoreboard:
geb "[[:space:]]+$" | awk '{author = $2 " " $3; lines[author] += 1 } END { for (author in lines) { printf "%s: %d\n", substr(author, 2), lines[author]}}'

@akien-mga
Copy link

Very nice trick, I've used it to grep and blame all occurrences of #if 0 in Godot Engine and cleanup some dead code, that's quite efficient.

I tweaked ggb() a bit to show the filename and support spaces in the argument:

ggb() {     git grep -n "$1" | while IFS=: read i j k; git blame -L $j,$j $i | cat | sed 's|^|'$i':\t|'; done; }

(I know my sed is ugly and it could likely be done more cleverly with awk or similar, but it does the trick)

@mxlian
Copy link

mxlian commented Nov 2, 2017

what is the purpose of using cat?

@xvilo
Copy link

xvilo commented Jan 22, 2018

Love it

@henrik242
Copy link

A little -f makes sure the file name is always printed, and cat is not necessary:

ggb() { git grep -n "$1" | while IFS=: read i j k; do git blame -f -L $j,$j $i; done }

@tonytonyjan
Copy link

fish shell:

function git_grep_blame -d "git grep + git blame"
    set -l IFS :
    command git grep -En $argv[1] | while read -l file line code
        git blame -f -L $line,$line $file | grep -E --color "$argv[1]|\$"
    end
end

@sunapi386
Copy link

Love the fish shell, thanks! Unfortunately, can't pass grep arguments.

@rafpaf
Copy link

rafpaf commented Jan 15, 2024

I use this alias in .gitconfig:

grame = "!r() { git grep -n $1 $2 | while IFS=: read i j k; do echo $i; git blame -f -L $j,$j $i; done }; r"

(To see the filename, I added echo $i to @henrik242's command mentioned above.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment