この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Gitリポジトリ内を検索する機会はよくあると思います。
- このメソッドって、どこで使われてるんだっけ?
- その定数の定義って、値は何だっけ? どこにあるんだっけ?
- あのURLって、何箇所で使われているんだろう?
git grep
コマンドを使えば、Git管理下のファイルのみを対象としてgrepができます。
シンプルなコマンドですが、利便性はとても高いと思います。
なお、grep対象はカレントブランチのみです。
目次
シンプルな例
シンプルな例ですが、よく使います。
特定ワードを含む箇所を調べたい(大文字小文字を区別する)
一番シンプルな例です。大文字小文字の区別をするので、注意が必要です。
なお、ワードの指定は正規表現(基本)です。正規表現(拡張)を使う場合は、-E
オプションを使います。
$ git grep "lambda"
hello_world/slash_command.py:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:def lambda_handler(event, context) -> dict:
template.yaml: Handler: slash_command.lambda_handler
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
特定ワードを含む箇所を調べたい(大文字小文字を区別しない)
-i
オプションを使います。
$ git grep -i "Lambda"
hello_world/slash_command.py:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:def lambda_handler(event, context) -> dict:
template.yaml: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
template.yaml: Handler: slash_command.lambda_handler
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
行番号を表示したい
-n
オプションを使います。
$ git grep -n "lambda"
hello_world/slash_command.py:4:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:7:def lambda_handler(event, context) -> dict:
template.yaml:32: Handler: slash_command.lambda_handler
tests/unit/test_handler.py:74: ret = app.lambda_handler(apigw_event, "")
行番号表示は、Gitの設定でデフォルトONにできます。
$ git config --global grep.lineNumber true
正規表現(拡張)で検索したい
-E
オプションを使えば、正規表現(拡張)の表記で検索ができます。
次の例は「数字が2つ並んでいる箇所」です。
$ git grep -E "[0-9]{2}"
hello_world/common_lambda.py: if res.status_code == 200:
hello_world/requirements.txt:requests==2.20.0
hello_world/slash_command.py: "statusCode": 200,
template.yaml:AWSTemplateFormatVersion: '2010-09-09'
template.yaml:Transform: AWS::Serverless-2016-10-31
template.yaml: Timeout: 10
単語で検索したい
-w
オプションを使います。
$ git grep -w "Function"
template.yaml: Function:
template.yaml: Type: AWS::Serverless::Function
template.yaml: Type: AWS::Serverless::Function
ちなみに-w
オプションが無い場合は次のような感じです(増えてますね)。
$ git grep "Function"
template.yaml: Function:
template.yaml: NotifyPeriodicFunction:
template.yaml: Type: AWS::Serverless::Function
template.yaml: NotifySlashCommandFunction:
template.yaml: Type: AWS::Serverless::Function
なお次を単語とみなしているようです。
- 行の先頭で始まる or 頭に単語以外の文字がある
- 行の終わりで終わるか or 単語以外の文字が続く
少し便利な例
ニッチな事例かもしれませんが、たまに役立つかもしれません。
- 特定フォルダのみで検索したい
- 特定フォルダを除外して検索したい
- 複数のワードを調べたい
- 表示時にファイル毎に空行を入れて見やすくする
- 不一致な行を調べたい
- 一致した行の上側を表示したい
- 一致した行の下側を表示したい
- 一致した行の上下を表示したい
- 一致した行を含む関数を表示したい
- ファイル名の一覧を調べたい
- 一致した数を調べたい(ファイル毎)
- 一致した数を調べたい(全体)
- 一致した数を調べたい(ファイル数)
- 複数ファイルの特定文字列を置換する(Git管理ファイルのみ)
特定フォルダのみで検索したい
-- <dir_name>
を使用します。
$ git grep lambda -- hello_world/
hello_world/periodic.py:from common_lambda import get_notify_delays, get_message
hello_world/periodic.py:def lambda_handler(event, context) -> None:
hello_world/slash_command.py:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:def lambda_handler(event, context) -> dict:
特定フォルダを除外して検索したい
-- :^<dir_name>
を使用します。:^
がポイントです。
$ git grep lambda -- :^hello_world/
template.yaml: Handler: periodic.lambda_handler
template.yaml: Handler: slash_command.lambda_handler
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
複数のワードを調べたい
--and
と--or
が使えます。ついでに--not
も使えます。パターンは-e
で指定する必要があります。
and
$ git grep -e lambda --and -e app
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
or
$ git grep -e lambda --or -e app
hello_world/common_lambda.py: notify_delays.append(check_item)
hello_world/common_lambda.py: details.append(f'・{company}: {name}: <{website}|こちら>')
hello_world/periodic.py:from common_lambda import get_notify_delays, get_message
hello_world/periodic.py:def lambda_handler(event, context) -> None:
hello_world/slash_command.py:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:def lambda_handler(event, context) -> dict:
template.yaml: Handler: periodic.lambda_handler
template.yaml: Handler: slash_command.lambda_handler
tests/unit/test_handler.py:from hello_world import app
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
tests/unit/test_handler.py: app.requests, 'get', side_effect=requests_response_mock)
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
表示時にファイル毎に空行を入れて見やすくする
--break
オプションを使います。
$ git grep --break lambda
hello_world/periodic.py:from common_lambda import get_notify_delays, get_message
hello_world/periodic.py:def lambda_handler(event, context) -> None:
hello_world/slash_command.py:from common_lambda import get_notify_delays, get_message
hello_world/slash_command.py:def lambda_handler(event, context) -> dict:
template.yaml: Handler: periodic.lambda_handler
template.yaml: Handler: slash_command.lambda_handler
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
tests/unit/test_handler.py: ret = app.lambda_handler(apigw_event, "")
不一致な行を調べたい
-v
オプションを使います。あまり使いどころはないかもしれませんが……。
$ git grep -v "lambda"
...(略)...
template.yaml:Description: Notify Slack Train Delay
template.yaml:
template.yaml:Globals:
template.yaml: Function:
template.yaml: Timeout: 10
template.yaml:
template.yaml:Resources:
template.yaml:
template.yaml: NotifyPeriodicFunction:
template.yaml: Type: AWS::Serverless::Function
...(略)...
一致した行の上側を表示したい
-B <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と上側の2行」を表示しています。
$ git grep -B 2 lambda
template.yaml- Properties:
template.yaml- CodeUri: hello_world/
template.yaml: Handler: periodic.lambda_handler
--
template.yaml- Properties:
template.yaml- CodeUri: hello_world/
template.yaml: Handler: slash_command.lambda_handler
--
tests/unit/test_handler.py-
tests/unit/test_handler.py-
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
一致した行の下側を表示したい
-A <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と下側の2行」を表示しています。
$ git grep -A 2 lambda
template.yaml: Handler: periodic.lambda_handler
template.yaml- Runtime: python3.6
template.yaml- Policies:
--
template.yaml: Handler: slash_command.lambda_handler
template.yaml- Runtime: python3.6
template.yaml- Events:
--
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
tests/unit/test_handler.py-
tests/unit/test_handler.py- requests_response_mock = namedtuple("response", ["text"])
一致した行の上下を表示したい
-C <num>
オプションを使います。<num>
には数値を指定します。
次の例だと、「lambdaがヒットした行と上下の2行」を表示しています。
(「周辺をちょっと見たい」場合に使えそうですが、そのようなケースに遭遇したことはないです……)
$ git grep -C 2 lambda
template.yaml- Properties:
template.yaml- CodeUri: hello_world/
template.yaml: Handler: periodic.lambda_handler
template.yaml- Runtime: python3.6
template.yaml- Policies:
--
template.yaml- Properties:
template.yaml- CodeUri: hello_world/
template.yaml: Handler: slash_command.lambda_handler
template.yaml- Runtime: python3.6
template.yaml- Events:
--
tests/unit/test_handler.py-
tests/unit/test_handler.py-
tests/unit/test_handler.py:def test_lambda_handler(apigw_event, mocker):
tests/unit/test_handler.py-
tests/unit/test_handler.py- requests_response_mock = namedtuple("response", ["text"])
一致した行を含む関数を表示したい
-W
オプションを使います。
関数の場合は良い感じにしてくれそうですが、YAMLファイルとか単なるTextファイルなどの場合は微妙です……(仕方がない)。
$ git grep -W lambda
hello_world/periodic.py:def lambda_handler(event, context) -> None:
hello_world/periodic.py-
hello_world/periodic.py- notify_delays = get_notify_delays()
hello_world/periodic.py-
hello_world/periodic.py- if not notify_delays:
hello_world/periodic.py- # 遅延が無ければ通知しない
hello_world/periodic.py- return
hello_world/periodic.py-
hello_world/periodic.py- # Slack用のメッセージを作成して投げる
hello_world/periodic.py- (title, detail) = get_message(notify_delays)
hello_world/periodic.py- post_slack(title, detail)
hello_world/periodic.py-
hello_world/periodic.py- return
ファイル名の一覧を調べたい
-l
オプションを使います。「xxxメソッドを変更するため、対象ファイルを知りたい」とかで使ってます。
$ git grep -l lambda
hello_world/periodic.py
hello_world/slash_command.py
template.yaml
tests/unit/test_handler.py
一致した数を調べたい(ファイル毎)
-c
オプションを使います。
$ git grep -c lambda
hello_world/periodic.py:2
hello_world/slash_command.py:2
template.yaml:2
tests/unit/test_handler.py:2
一致した数を調べたい(全体)
wc -l
コマンドと組み合わせて、改行の数をカウントしています。
$ git grep lambda | wc -l
8
一致した数を調べたい(ファイル数)
こちらもwc -l
コマンドと組み合わせます。
$ git grep -l lambda | wc -l
4
複数ファイルの特定文字列を置換する(Git管理ファイルのみ)
ファイル一覧を取得して、後段で1ファイルずつ置換処理させています。
$ git grep -l '検索対象の文字列' | xargs sed -i '' -e 's/置換対象の文字列/置換後の文字列/g'
さいごに
長く書きましたが、次の3つが使えればとりあえず便利です!
git grep xxx
- シンプル版
git grep -i yyy
- 大文字小文字を区別しない版
git grep -E zzz
- 正規表現版
現在の仕事では複数リポジトリを扱っているので、「修正対象はどのリポジトリだっけ?」などを簡単に調査できるため重宝しています。(IDE開いて検索するより簡単)