git hooks とは、commit や push などの決まった時点で git が自動で走らせる台本(プログラム)の仕組みです。

  • pre-commit・pre-push がいつ呼ばれ、何を受け取り、どの終了コードで commit や push を止めるか
  • husky と core.hooksPath の関係と、hook が「在るのに走っていない」を見分ける測り方
  • 長い pre-push の間に SSH が切れて push が落ちた記録と、ServerAliveInterval で直した形、--no-verify を使った回の後始末

当社は、コードの変更を AIエージェント の席に書かせ、手元の hook と merge queue の CI の 2 段で門を掛けています。この頁は、その手元の門(git hooks)で実際に詰まった記録を、git と husky と OpenSSH の公式の文書の定義と並べたものです。なお、Claude Code の hooks は Claude Code の側で動く別の仕組みで、この頁の git hooks とは別物です。

git hooks の仕組み: 置き場所と、止まる条件

git の文書(githooks)では、hook は hooks のディレクトリに置くプログラムで、既定の置き場は $GIT_DIR/hooks、core.hooksPath の設定で変えられます。実行の権限(executable bit)が無い hook は無視されます。

hook呼ぶ命令と時点(公式の文書)受け取る物(公式の文書)0 以外で終わると(公式の文書)飛ばす印
pre-commitgit commit。commit の文言を受け取る前、commit を作る前引数なしcommit を作らずに止まるgit commit --no-verify(-n)。pre-commit と commit-msg を飛ばす
pre-pushgit push。push を止めるために使える引数 2 つ(宛先の remote の名前と場所)。標準入力に 1 行ずつ <local-ref> <local-object-name> <remote-ref> <remote-object-name>何も push せずに止まるgit push --no-verify。pre-push を丸ごと飛ばす

出典: githooks・git-commit・git-push(git-scm.com、2026-11-05 に確認)。

githooks の文書は、pre-push が remote へ繋ぐ前か後かを書いていません。当社の記録では、git は hook の前に GitHub へ SSH で繋いでいました(社の実測 2026-10-15・後の節)。

husky で hook をリポジトリに入れる

husky の公式の文書では、husky は「速い、現代のネイティブな git hooks」の道具で、git の core.hooksPath を使います。入れ方は次の 2 手です(husky Get Started、2026-11-05 に確認)。

  1. npm install --save-dev husky(pnpm・Yarn・Bun にも同じ手がある)
  2. npx husky init。.husky/ に pre-commit の台本を作り、package.json の prepare の台本を書き換える

hook を一時的に止めるには、-n/--no-verify を持つ命令ではそれを使い、持たない命令では HUSKY=0 git … とします。GUI から git を撃つと version manager が初期化されず、PATH に Node が無くて command not found になることがあり、husky は各 hook の前に ~/.config/husky/init.sh を読むので、そこに初期化を書きます(husky How To、2026-11-05 に確認)。

hook が「在る」と「走る」は別。当社の測り方

hook の門で最初に疑うべきは、そもそも走っているかです。当社は 2 回、走っていないのに気付きませんでした(社の実測 2026-09-29・2026-09-20)。

  • 当社の棚のリポジトリでは、2026-09-18 以降 core.hooksPath が配線されておらず、pre-commit が 1 本も走っていませんでした。設定を測ると、撃つ前は空([])、配線後は [scripts/git-hooks] です(社の実測 2026-09-29)。
  • 別のリポジトリでは、説明の紙が「手元の pre-commit は撤去済み」と書きながら、同じ紙の 4 行が存在しない hook を前提にしていました。共有の clone には core.hooksPath=.husky/_ の残骸が在り、外しました。hook の実体は無く、挙動は変わりません(社の実測 2026-09-20)。

「効いているか」の測り方も一度間違えました。[ -x <hooksPath>/pre-push ] で測ると、husky のローダが在るだけで真になる偽陽性でした(社の実測 2026-09-18)。今は git hook run pre-push を撃ち、stderr に cannot find a hook named が出ないことで測ります。終了コードは hook が無くても 0 なので、rc では測りません(社の実測 2026-09-18)。

測り方hook が在って走る時hook が無い・配線されていない時使えるか
[ -x <hooksPath>/pre-push ]真husky のローダが在るだけで真(偽陽性)使えない(社の実測 2026-09-18)
git hook run pre-push の rchook の結果0使えない(社の実測 2026-09-18)
git hook run pre-push の stderrcannot find a hook named が出ないcannot find a hook named が出る使う(社の実測 2026-09-18)
git config core.hooksPath配線先が出る空配線の有無だけ分かる(社の実測 2026-09-29)

出典: 社の実測 2026-09-18・2026-09-29。

pre-push の間に SSH が切れ、ゲートは PASS なのに push が exit 141 で落ちた

当社の pre-push は、手元でゲート(試験の束)を撃ちます。ゲートの順番待ちが長く、admin の unit 試験まで走る回で、ゲートは PASS なのに git push が exit 141(SIGPIPE)で終わり、remote に載っていませんでした。1 つの席で 3 回、同じ日に 3 つの席が踏みました(社の実測 2026-10-15)。

原因は、git が hook の前に GitHub へ SSH で繋いでおり、hook が走っている間は無通信なので、その接続が切られることでした。hook は git が繋いだ後に走るので、hook の中では直せません(社の実測 2026-10-15)。

直した所: ホームの .ssh/config の ServerAliveInterval

OpenSSH の ssh_config の文書では、ServerAliveInterval は server から何も受け取らない秒数がこれを超えたら、暗号化された経路で応答を求める message を送る間隔で、既定は 0(送らない)です。ServerAliveCountMax は応答が無いまま送ってよい数で、既定は 3、超えると ssh は切ります(OpenBSD ssh_config、2026-11-05 に確認)。

当社は機体のホームの .ssh/config に次を足しました(社の実測 2026-10-15)。

Host github.com
  ServerAliveInterval 30
  ServerAliveCountMax 120

16 分眠るだけの hook で比べました(社の実測 2026-10-15)。

条件結果
keepalive あり(上の設定)remote に着地、rc=0
陽性対照 ServerAliveInterval=0Connection to github.com closed by remote host、rc=141

出典: 社の実測 2026-10-15。

Host github.com に絞ったので、他の Host の設定が変わらないことを ssh -G で確かめています(社の実測 2026-10-15)。

もう 1 つの逃げ道: HTTPS で push する

HTTPS の push は hook の後に繋ぎ直すので、長い回でも着地しました(社の実測 2026-10-15)。

git -c credential.helper= -c 'credential.helper=!gh auth git-credential' \
  push https://github.com/<org>/<repo>.git HEAD:refs/heads/<枝>

どちらの道でも、ゲートの PASS や push の exit を着地の証拠にせず、git ls-remote で remote の枝の先を測ります(社の実測 2026-10-15)。PASS の文字は「手元の試験が通った」しか言っていません。

--no-verify を使った 2 回と、その後の決まり

--no-verify は hook を丸ごと飛ばす印です(git-push・git-commit)。当社は 2 回使い、1 回は筋が通り、1 回は後始末が要りました。

日飛ばした hook飛ばした理由確かめた事結果
2026-09-22pre-push(タグの push)門で 42 分止まった。同じ作業木で他の席の push 2 本も同じ門を走らせ、機体の load が 148そのタグの commit が merge queue の CI で 23 success/3 skippedgit push --no-verify origin <tag> で出した(社の実測 2026-09-22)
2026-10-23pre-commit(型検査)取り込みの merge の commit を git commit --no-verify で作った型の誤りは 0unit 試験が 10 本赤。数を直す commit を hook を通して作り、unit 1003 本緑、pre-push を通して push(社の実測 2026-10-23)

出典: 社の実測 2026-09-22・2026-10-23。

2 回目の赤は、両方の枝が 1 本ずつ仕事を足し、試験の期待の数が片方の分だけだったためで、型では捕まりません(社の実測 2026-10-23)。pre-commit を飛ばしても型の誤りが 0 だったことは、取り込みが正しい証拠になりませんでした。

それ以後、当社は --no-verify を使いません。hook が遅い・落ちるなら、その理由を直します(社の実測 2026-10-23)。1 回目のタグについては、CI 済みの commit を手元で撃ち直すだけなので、タグの push では pre-push を撃たない形を恒久の候補にしています(社の実測 2026-09-22)。手元で取り消したい変更がある時の手は、姉妹頁の git add の取り消し にまとめています。

pre-push の lint が 0.0 秒で落ちたら、hook より先に機体を見る

機体の /opt/homebrew/bin が丸ごと消え、npx が引けず、pre-push の lint が 0.0 秒・exit 1 で落ちました(社の実測 2026-10-24)。hook の中身は何も悪くありません。

  1. lint が 0.0 秒で exit 1 になっている
  2. command -v npx が空
  3. ls /opt/homebrew/bin で中身を見る

この順で見ると、hook の台本を疑って時間を使わずに済みます(社の実測 2026-10-24)。

よくある質問

pre-commit と pre-push はどう使い分ける?

pre-commit は git commit が commit を作る前に、pre-push は git push が push する前に呼ばれ、どちらも 0 以外で終わると止めます(githooks)。当社は pre-commit に型検査、pre-push に lint や試験の束を置いています(社の実測 2026-10-23・2026-10-24)。

git push --no-verify を使ってもよい?

--no-verify は pre-push を丸ごと飛ばします(git-push)。当社は型の誤り 0 でも試験が 10 本赤になった回を踏み、以後は使わず、hook が遅い理由の方を直しています(社の実測 2026-10-23)。

pre-push の後に push が exit 141 で落ちるのはなぜ?

当社の場合は、git が hook の前に SSH で繋いだ接続が、長い hook の間の無通信で切られていました(社の実測 2026-10-15)。ホームの .ssh/config の Host github.com に ServerAliveInterval 30 と ServerAliveCountMax 120 を足すと着地しました(社の実測 2026-10-15)。

husky を入れたのに hook が走らないのはなぜ?

husky は core.hooksPath を使うので(husky の公式の頁)、その設定が空なら hook は走りません。当社は配線が外れたまま pre-commit が 1 本も走っていなかった回があり(社の実測 2026-09-29)、今は git hook run pre-push の stderr に cannot find a hook named が出ないことで確かめています(社の実測 2026-09-18)。

出典

  1. githooks Documentation https://git-scm.com/docs/githooks (2026-11-05 に確認)
  2. git-commit Documentation https://git-scm.com/docs/git-commit (2026-11-05 に確認)
  3. git-push Documentation https://git-scm.com/docs/git-push (2026-11-05 に確認)
  4. Husky https://typicode.github.io/husky/ ・Get Started https://typicode.github.io/husky/get-started.html ・How To https://typicode.github.io/husky/how-to.html (2026-11-05 に確認)
  5. OpenBSD manual ssh_config(5) https://man.openbsd.org/ssh_config (2026-11-05 に確認)
  6. 社の実測 2026-09-18・2026-09-20・2026-09-22・2026-09-29・2026-10-15・2026-10-23・2026-10-24

ブルーランプ 記事の編集部/更新日 2026-11-05