Last active
June 6, 2018 17:47
-
-
Save darcyparker/d5b9168ada88d0527564a11d9d9899c4 to your computer and use it in GitHub Desktop.
git grep for a git repo and its submodules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Author: [email protected] | |
# Repo: https://gist.github.com/darcyparker/d5b9168ada88d0527564a11d9d9899c4 | |
# Description: | |
# * git grep for the repo and its submodules. | |
# * greps into submodules recrusively | |
# * Output includes full relative path from the top level repo to files with matches | |
# * Output is formatted with line number, and column number of matched | |
# Usage: | |
# gitgrep "some string" | |
# gitgrep "some string" some/dir | |
# gitgrep "some string" some/dir --extra-option1 --extra-option2 | |
# * where `--extra-option1` and `--extra-option2` are `git grep` options | |
# Tip: | |
# Add a git alias in your `~/.gitconfig` like this: | |
# [alias] | |
# grepall = "!f() { gitgrep "$1" "$2" "$3"; }; f" | |
f(){ | |
pushd . > /dev/null | |
local _searchString="$1"; shift | |
if [[ $# -ge 1 ]] && [ -d "$1" ]; then | |
cd "$1" || exit; shift | |
fi | |
if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1; then | |
local _rootDir | |
_rootDir="$(git rev-parse --show-toplevel)" | |
else | |
popd > /dev/null | |
return | |
fi | |
local _args=( "git" "grep" "-n" "--no-color" ) | |
#Add optional extra args | |
if [[ $# -ge 1 ]] && [ ! -z "$1" ]; then | |
_args=( "${_args[@]}" "$1[@]" ) | |
fi | |
_args=( "${_args[@]}" "$_searchString" -- ) | |
cd "$_rootDir" || exit | |
#Two sets of results: 1) from the git repo and 2) each git submodule | |
{ | |
"${_args[@]}" "$_rootDir" | |
git --no-pager submodule --quiet foreach --recursive "echo \"\$toplevel/\$path\"" | \ | |
while read -r _subModuleDir; do | |
cd "$_subModuleDir" || exit | |
"${_args[@]}" "$_subModuleDir" | while read -r _line; do | |
#Output filepath relative to $_rootDir | |
echo "${_subModuleDir#$_rootDir/}/$_line" | |
done | |
done | |
} | \ | |
#Now pipe it to a formatter that includes path, line and column numbers and matched line | |
while read -r _line; do | |
local _filePathAndLineNum | |
_filePathAndLineNum=$(echo "$_line" | cut -d: -f1,2) | |
local _matched | |
_matched=${_line/$_filePathAndLineNum:/''} | |
local _columnNum | |
_columnNum=$(echo "$_matched" | awk "{print index(\$0, \"$_searchString\")}") | |
echo "$_filePathAndLineNum:$_columnNum:$_matched" | |
done | |
popd > /dev/null | |
} | |
f "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment