$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

git grepで除外パスを指定しやすくする

git grepにはさまざまな便利グッズがあるのだけど、どうやっても覚えられなくて困っていた。たまに使いたいものとして、特定ファイルは除外する方法があるが、この記法が覚えられない...

例えば、golangでテストファイルとgen/ディレクトリ以下にあるもの以外を検索したいなら、こういう書き方ができる。先頭のコロンも覚えられないし、!も覚えられない...

git grep hoge ':!*_test.go' ':!gen/'
# もしくは
git grep hoge ':(exclude)*_test.go' ':(exclude)gen/'

そういうことで自分が使いやすいようにgit grepをカスタマイズしてみた。 自分だったら --exclude *_test.go と書けるなら覚えられそうだなということで、こういう感じに。

git-grep-extend

#!/usr/bin/env bash

# git grepをさらに使いやすくするツール
#
# git-grep-extend:
#   Usage例:
#   git-grep-extend -i "fuga" --exclude "docs/" --exclude "vendor/"

# 検索パターンやオプション
grep_opts=()
# 除外パスを格納
exclude_opts=()

while [[ $# -gt 0 ]]; do
  case "$1" in
    --exclude)
      # 除外パスを指定できるオプション
      exclude_opts+=( ":(exclude)$2" )
      shift 2
      ;;
    *)
      # grepに渡す他のパラメータ(検索パターンやオプション)を格納
      grep_opts+=( "$1" )
      shift
      ;;
  esac
done

git grep "${grep_opts[@]}" "${exclude_opts[@]}"

これで例えば https://github.com/shibayu36/terminal-shooter からこんな検索ができて便利になった。

# case insensitive / bulletにマッチするが_bulletにはマッチしない / *_test.go以外のファイル / serverディレクトリ以下から検索
git grep-extend -i -e bullet --and --not -e '_bullet' --exclude '*_test.go' server