更新フックの使用
あなたはフックについて知っています - それらについてのドキュメントを読んでください! おそらく必要なフックは、ref ごとに 1 回実行される update です。(pre-receive フックは、プッシュ全体に対して 1 回実行されます) これらのフックに関する質問と回答は、すでに SO に山ほどあります。やりたいことに応じて、必要に応じてフックの書き方に関するガイダンスを見つけることができます。
これが実際に可能であることを強調するために、ドキュメントからの引用:
このフックを使用して、オブジェクト名が、古いオブジェクト名で指定されたコミット オブジェクトの子孫であるコミット オブジェクトであることを確認することにより、特定の参照に対する強制更新を防ぐことができます。つまり、「早送りのみ」のポリシーを適用します。
古い..新しいステータスをログに記録するためにも使用できます。
そして詳細:
フックは、更新される参照ごとに 1 回実行され、次の 3 つのパラメーターを受け取ります。
- 更新される参照の名前、
- ref に保存されている古いオブジェクト名、
- およびrefに格納される新しいオブジェクト名。
したがって、たとえば、どのコミット サブジェクトも 80 文字を超えないようにしたい場合、非常に初歩的な実装は次のようになります。
#!/bin/bash
long_subject=$(git log --pretty=%s $2..$3 | egrep -m 1 '.{81}')
if [ -n "$long_subject" ]; then
echo "error: commit subject over 80 characters:"
echo " $long_subject"
exit 1
fi
もちろん、これはおもちゃの例です。一般的なケースでは、完全なコミット メッセージを含むログ出力を使用し、それをコミットごとに分割し、個々のコミット メッセージごとに検証コードを呼び出します。
更新フックが必要な理由
これはコメントで議論/明確化されています。ここに要約があります。
update フックは、ref ごとに 1 回実行されます。ref はオブジェクトへのポインターです。この場合、ブランチとタグについて話していますが、通常はブランチだけです (通常はバージョンをマークするためだけにタグをプッシュすることはあまりありません)。
ここで、ユーザーがマスターと実験的な 2 つのブランチに更新をプッシュしている場合:
o - o - o (origin/master) - o - X - o - o (master)
\
o - o (origin/experimental) - o - o (experimental)
X が「悪い」コミット、つまり commit-msg フックに失敗するコミットであるとします。明らかに、マスターへのプッシュを受け入れたくありません。したがって、更新フックはそれを拒否します。しかし、実験的なコミットには何も問題はありません! 更新フックはそれを受け入れます。したがって、origin/master は変更されませんが、origin/experimental は更新されます。
o - o - o (origin/master) - o - X - o - o (master)
\
o - o - o - o (origin/experimental, experimental)
pre-receive フックは、ref の更新を開始する直前 (初めて update フックが実行される前) に 1 回だけ実行されます。これを使用すると、プッシュ全体を失敗させる必要があり、master に不適切なコミット メッセージがあったため、experimental のコミットが正常であっても、そのメッセージが正常であるとは信じられなくなります。