なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Lefthook の pre-push イベントでブランチ名を受け取る

Lefthook という Git Hook をうまいこと管理してくれる Golang 製ツールがあります。
メリットとしては、 Node.js に依存しない、つまりはランタイムが必要ないことがあげられ、また設定も lefthook.yml を記述するだけなので、簡単に使えるという特徴があります。
今回は、そんな Lefthook で pre-push イベントですべてのブランチ名を受け取る方法についてのメモです。

Lefthook は v1.3.3 時点で、以下のような不具合が存在します。

Pass local and remote branch names as arguments / env variables to pre-push · Issue #320 · evilmartians/lefthook · GitHub

基本的に、 Git Hook の pre-push イベントにおいて、 push 予定のすべてのブランチを取得するには、以下のようなシェルスクリプトが用いられます。

while read -r local_ref local_sha remote_ref remote_sha
do
  # ...
done

ただし、 Lefthook では上記スクリプトのまま実行させた場合、 while-done の部分が終了することはありません。
というのも、おそらく Lefthook → Shell Script への stdout において終了することが無く、永久に read コマンドで新しい行を待機するからだと思われます。
なので、以下のようにすることで、 Lefthook でも扱えるようになります。

while read -r -t 1 local_ref local_sha remote_ref remote_sha
do
  # ...
done

まぁ read コマンドをタイムアウト有りで実行するだけですね。
基本的に pre-push イベントにおいてユーザー入力が介入する場所は無いはずで、単純に Git (Lefthook) からの stdin を受け取るだけなら、このようにタイムアウトを設定するだけで正しく動作します。
ということで、メモでした。