Git フックは、Git リポジトリで特定のイベントが生じるたびに自動で実行されるスクリプトです。ユーザーは Git フックを使用して Git の内部動作をカスタマイズし、カスタマイズ可能なアクションを開発ライクサイクルのキーポイントでトリガーできます。

コミット作成プロセス中にフックを実行

Git フックの一般的な使用事例には、コミットポリシーの促進、リポジトリの状態に応じたプロジェクト環境の変更、継続的インテグレーション ワークフローの実装などがあります。しかし、スクリプトは無限にカスタマイズ可能なため、事実上、開発ワークフローのあらゆる側面を Git フックを使用して自動化したり、最適化したりすることができます。

この記事では、Git フックの仕組みについて概念的な概要から説明します。その後、ローカルおよびサーバー側の両方のリポジトリで最もよく使用されているフックをいくつか概観します。

考え方の概要

すべての Git フックは普通のスクリプトで、リポジトリで特定のイベントが生じると Git が実行します。このため、フックはインストールや設定が非常に簡単です。

フックはローカルまたはサーバー側のいずれかのリポジトリに配置でき、そのリポジトリ内のアクションにのみ反応して実行されます。この記事の後半で、フックのカテゴリを実際に見ていきます。このセクションの残りの部分で説明している設定は、ローカルおよびサーバー側のフックの両方に適用されます。

フックのインストール

フックは、すべての Git リポジトリの .git/hooks ディレクトリに格納されています。リポジトリを初期化すると、このディレクトリにサンプル スクリプトが自動的に入力されます。.git/hooks の中を見てみると、次のファイルが見つかります。

applypatch-msg.sample       pre-push.sample
commit-msg.sample           pre-rebase.sample
post-update.sample          prepare-commit-msg.sample
pre-applypatch.sample       update.sample
pre-commit.sample

使用可能なフックのほとんどが示されていますが、.sample 拡張子があるため、既定では実行されないようになっています。.sample 拡張子を削除するだけで、フックを「インストール」できます。または、新しいスクリプトを最初から作成する場合は、.sample 拡張子を除いて上記のファイル名の 1 つと一致する新しいファイルを簡単に追加できます。

例として、単純な prepare-commit-msg フックをインストールしてみましょう。.sample 拡張子を削除し、次の内容をファイルに追加します。

#!/bin/sh

echo "# Please include a useful commit message!" > $1

フックを実行可能にする必要があります。したがって、スクリプトを一から作成している場合、スクリプトのファイル権限を変更する必要がある場合もあります。たとえば、prepare-commit-msg が実行可能であることを確認するには、次のコマンドを実行します。

chmod +x prepare-commit-msg

git commit を実行するたびに、既定のコミット メッセージの代わりにこのメッセージが表示されます。これが実際にどのように機能するかについては、「コミット メッセージの準備」セクションで詳しく見ていきます。とりあえず、Git の内部機能の一部をカスタマイズできるという事実に注目しましょう。

組み込みのサンプルスクリプトは、各フックに渡されるパラメーターが記載されているため (パラメーターはフックごとに異なります)、 非常に役立つリファレンスです。

スクリプト言語

組み込みスクリプトは、ほとんどがシェル スクリプトと PERL スクリプトですが、実行可能ファイルとして実行できる限り、任意のスクリプト言語を使用できます。各スクリプトのシバン行 (#!/bin/sh) は、ファイルの解釈方法を定義します。したがって、別の言語を使用するには、シバン行を変更してご使用のインタープリターのパスを指定すればよいだけです。

たとえば、シェル コマンドを使用する代わりに、prepare-commit-msg ファイルに実行可能な Python スクリプトを記述できます。次のフックは、前のセクションのシェル スクリプトと同じことを行います。

#!/usr/bin/env python

import sys, os

commit_msg_filepath = sys.argv[1]
with open(commit_msg_filepath, 'w') as f:
    f.write("# Please include a useful commit message!")

最初の行が Python インタ-プリターを指すように変更されていることに注目してください。そして、$1 を使ってスクリプトに渡される最初の引数にアクセスする代わりに、sys.argv [1] が使われています。(詳細は後で説明します)。

ユーザーが最も使いやすい言語を使用して作業できるため、これは Git フックの非常に強力な機能です。

フックの範囲

フックは特定の Git リポジトリに限定されており、git clone を実行しても新しいリポジトリにコピーされません。また、そのリポジトリへのアクセス権を持つ人なら誰でも変更できます。

開発者のチームがフックを設定するときにこれは重要な影響を及ぼします。第一に、フックがチームメンバー間で常に最新の状態であることを確認する方法を見つける必要があります。第二に、特定の方法を示すコミットを作成することを開発者に強制できません。あなたにできることは、開発者がそうするように促すことだけです。

開発者のチーム用にフックを維持するのは簡単なことではありません。.git/hooks ディレクトリはプロジェクトの残りの部分と共に複製されず、バージョン管理もされないためです。これらの問題の簡単な解決策は、実際のプロジェクト ディレクトリ (.git の上) にフックを格納することです。これにより、バージョン管理されている他のファイルと同様にフックも編集できます。フックをインストールするには、.git/hooks にシンボリック リンクを作成するか、または、フックが更新されるたびに必ず .git/hooks ディレクトリにコピー & ペーストするようにします。

コミット作成プロセス中にフックを実行

別の方法として、Git はフックの自動インストールを容易にするテンプレート ディレクトリ メカニズムも提供しています。このテンプレート ディレクトリに含まれるファイルとディレクトリはすべて、.git ディレクトリに git init または git clone を使用するたびにコピーされます。

以下に説明するローカル フックはすべて、リポジトリの所有者が変更 (または完全にアンインストール) できます。実際にフックを使用するかどうかは、各チーム メンバー次第です。このことを念頭に置いて、Git フックは、厳しく強要される開発ポリシーではなく、便利な開発者ツールとして考えるのが最善です。

しかし、サーバー側フックを使用して、ある標準に従わないコミットを拒否することはできます。これについては、この記事の後半で詳しく説明します。

ローカルフック

ローカルフックは、そのフックが存在しているリポジトリにのみ影響を与えます。このセクションを最後まで読む間、みなさんに覚えておいてほしいことがあります。各開発者は自分自身のローカルフックを変更できるため、コミットポリシーを強制する方法としてフックを使用することはできません。ただし、フックを使用することで、開発者は特定のガイドラインをはるかに容易に守ることができます。

このセクションでは、最も役立つ次の6つのローカルフックについて取り上げます。

  • Pre-Commit
  • prepare-commit-msg
  • commit-msg
  • Post-Commit
  • Post-Checkout
  • Pre-Rebase

最初の 4 つのフックは、コミット ライフサイクル全体に組み込むことができ、最後の 2 つは、git checkout ではいくつかの追加アクション、git rebase ではいくつかのセーフティ チェックを実行できます。

pre- フックはすべて、実行直前のアクションを変更できますが、post- フックは通知にのみ使用されます。

また、フック引数の解析や、低レベルの Git コマンドを使用してリポジトリに関する情報の要求を行うための有用な手法についてもいくつか紹介します。

Pre-Commit

pre-commit スクリプトは、git commit の実行時に常に実行され、その後で Git は開発者にコミット メッセージを要求するか、コミット オブジェクトを生成します。このフックを使用してコミット直前のスナップショットを検査できます。たとえば、いくつか自動化されたテストを実行して、コミットが既存の機能性を破壊しないことを確認することもできます。

pre-commit スクリプトに渡される引数はなく、ゼロ以外のステータスで終了すると、コミット全体が中止されます。それでは、組み込みの pre-commit フックの単純化された (そして、より詳細な) バージョンを見てみましょう。このスクリプトは、git diff-index コマンドによって定義されている空白エラー (末尾空白、空白のみの行、および行の先頭のインデント内にスペースに続けてタブが設定されている場合は既定でエラーとみなされる) を検出すると、コミットを中止します。

#!/bin/sh

# Check if this is the initial commit
if git rev-parse --verify HEAD >/dev/null 2>&1
then
    echo "pre-commit: About to create a new commit..."
    against=HEAD
else
    echo "pre-commit: About to create the first commit..."
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Use git diff-index to check for whitespace errors
echo "pre-commit: Testing for whitespace errors..."
if ! git diff-index --check --cached $against
then
    echo "pre-commit: Aborting commit due to whitespace errors"
    exit 1
else
    echo "pre-commit: No whitespace errors :)"
    exit 0
fi

git diff-index を使用するには、インデックスを比較しているコミット参照がどれかを見つけ出す必要があります。通常、これは HEAD ですが、HEAD は最初のコミットの作成時には存在しません。このため、まず、このエッジケースについて git rev-parse --verify を使用して説明します。これは、単に、引数 (HEAD) が有効な参照であるかどうかをチェックします。>/dev/null 2>& 1 部分は、git rev-parse からのあらゆる出力を無視します。HEAD または空のコミット オブジェクトのいずれかが、git diff-index で使用するために against 変数に格納されます。4b825d... ハッシュは、空のコミットを表す便利なコミット ID です。

git diff-index --cached コマンドはこのインデックスに対してコミットを比較します。--check オプションを渡すことによって、変更によって空白エラーが生じるかどうかを警告するようにします。生じる場合、終了ステータス 1 を返すことによって、コミットを中止します。それ以外は 0 で終了し、コミット ワークフローは通常どおり続行されます。

これは pre-commit フックの一例にすぎません。既存の Git コマンドを使用し、提案されたコミットによって生じる変更に対してテストを実行することもありますが、pre-commit では、他のスクリプトの実行、サードパーティのテスト スイートの実行、または Lint によるコード スタイルのチェックなど、必要なあらゆることを実行できます。

Prepare Commit Message

prepare-commit-msg フックは pre-commit フックの後に呼び出されてコミット メッセージをテキスト エディタに取り込みます。これは、自動的に生成されるコミット メッセージを、1 つにまとめられたコミットや、マージされたコミットに変更する場所に適しています。

prepare-commit-msg スクリプトには、1 つから 3 つの引数が渡されます。

  1. メッセージを含む一時ファイルの名前。このファイルを直接書き換えることで、コミットメッセージを変更します。
  2. コミットのタイプ。message (-m または -F オプション)、template (-t オプション)、merge (コミットがマージ コミットの場合)、squash (コミットが他のコミットを 1 つにまとめる場合) のいずれかになります。
  3. 関連するコミットの SHA1 ハッシュ。-c-C、または --amend オプションが指定された場合のみ渡されます。

pre-commit と同様に、ゼロ以外のステータスで終了するとコミットが中止されます。

ここまで、コミット メッセージを編集した単純な例を見てきましたが、さらに便利なスクリプトを紹介します。課題トラッカーを使用する場合は、各課題を個別のブランチで扱うことが一般的な規則です。ブランチ名に課題番号を含めると、prepare-commit-msg フックを記述して、そのブランチでの各コミット メッセージに課題番号を自動的に含めることができます。

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
commit_msg_filepath = sys.argv[1]
if len(sys.argv) > 2:
    commit_type = sys.argv[2]
else:
    commit_type = ''
if len(sys.argv) > 3:
    commit_hash = sys.argv[3]
else:
    commit_hash = ''

print "prepare-commit-msg: File: %s\nType: %s\nHash: %s" % (commit_msg_filepath, commit_type, commit_hash)

# Figure out which branch we're on
branch = check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip()
print "prepare-commit-msg: On branch '%s'" % branch

# Populate the commit message with the issue #, if there is one
if branch.startswith('issue-'):
    print "prepare-commit-msg: Oh hey, it's an issue branch."
    result = re.match('issue-(.*)', branch)
    issue_number = result.group(1)

    with open(commit_msg_filepath, 'r+') as f:
        content = f.read()
        f.seek(0, 0)
        f.write("ISSUE-%s %s" % (issue_number, content))

まず、上記の prepare-commit-msg フックは、スクリプトに渡されるすべてのパラメータを収集する方法を示します。次に、git symbolic-ref --short HEAD を呼び出して HEAD に対応するブランチ名を取得します。このブランチ名が issue- で始まる場合、コミット メッセージ ファイルのコンテンツに再書き込みして、最初の行に課題番号を含めます。つまり、ブランチ名が issue-224 なら、以下のコミット メッセージが生成されます。

ISSUE-224 

# Please enter the commit message for your changes. Lines starting 
# with '#' will be ignored, and an empty message aborts the commit. 
# On branch issue-224 
# Changes to be committed: 
#   modified:   test.txt

prepare-commit-msg を使用する際に注意すべき点の 1 つは、git commit-m オプションを指定してメッセージを渡しても実行されるということです。つまり、上記のスクリプトは、自動的に ISSUE-[#] 文字列を挿入するためユーザーは編集できません。この問題には、2 番目のパラメータ (commit_type) が message と等しいかどうかを確認することで対応できます。

しかし、-m オプションがなければ、prepare-commit-msg フックを使用しても、メッセージが生成された後でユーザーが編集できるため、これはコミット メッセージ ポリシーを強制する方法よりも実際に便利なスクリプトです。そのためには、次のセクションで説明する commit-msg フックが必要です。

Commit Message

commit-msg フックは prepare-commit-msg フックとよく似ていますが、ユーザーがコミット メッセージを入力した後に呼び出されます。これは、メッセージがチームの標準に準拠していないことを開発者に警告する場所に適しています。

このフックに渡される唯一の引数は、メッセージを含むファイルの名前です。このフックでは、ユーザーが入力したメッセージがチームの標準に準拠していない場合に、このファイルを適切に変更したり (prepare-commit-msg の場合と同様)、ゼロ以外のステータスで終了してコミットを完全に中止したりします。

たとえば、次のスクリプトは、前のセクションで prepare-commit-msg フックにより自動的に生成された ISSUE-[#] 文字列をユーザーが削除していないことを確認する検査を実行します。

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
commit_msg_filepath = sys.argv[1]

# Figure out which branch we're on
branch = check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip()
print "commit-msg: On branch '%s'" % branch

# Check the commit message if we're on an issue branch
if branch.startswith('issue-'):
    print "commit-msg: Oh hey, it's an issue branch."
    result = re.match('issue-(.*)', branch)
    issue_number = result.group(1)
    required_message = "ISSUE-%s" % issue_number

    with open(commit_msg_filepath, 'r') as f:
        content = f.read()
        if not content.startswith(required_message):
            print "commit-msg: ERROR! The commit message must start with '%s'" % required_message
            sys.exit(1)

このスクリプトはユーザーがコミットを作成するたびに呼び出されますが、コミット メッセージの検査以外で呼び出すことは避けるべきです。スナップショットがコミットされたことを他のサービスに通知する必要がある場合は、代わりに post-commit フックを使用してください。

Post-Commit

post-commit フックは、commit-msg フックの直後に呼び出されます。git commit 操作の結果は変更できないため、主に通知目的で使用されます。

このスクリプトはパラメータを取らず、どのような終了ステータスであっても、コミットにまったく影響を与えません。ほとんどの post-commit スクリプトで、作成されたばかりのコミットへのアクセス権が必要になります。git rev-parse HEAD を使用すると、新しいコミットの SHA1 ハッシュを取得できます。または、git log -1 HEAD を使用してその情報をすべて取得することもできます。

たとえば、スナップショットをコミットするたびに上司にメールで通知したい場合 (ほとんどのワークフローで最善のアイデアとは言えないと思いますが)、次の post-commit フックを追加できます。

#!/usr/bin/env python

import smtplib
from email.mime.text import MIMEText
from subprocess import check_output

# Get the git log --stat entry of the new commit
log = check_output(['git', 'log', '-1', '--stat', 'HEAD'])

# Create a plaintext email message
msg = MIMEText("Look, I'm actually doing some work:\n\n%s" % log)

msg['Subject'] = 'Git post-commit hook notification'
msg['From'] = 'mary@example.com'
msg['To'] = 'boss@example.com'

# Send the message
SMTP_SERVER = 'smtp.example.com'
SMTP_PORT = 587

session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo()
session.login(msg['From'], 'secretPassword')

session.sendmail(msg['From'], msg['To'], msg.as_string())
session.quit()

post-commit を使用してローカルの継続的インテグレーション システムをトリガーすることは可能ですが、ほとんどの場合、post-receive フックでこれを実行する必要が生じるでしょう。これはユーザーのローカル マシンではなく、サーバー側で実行され、さらに、すべての開発者がコードをプッシュするたびに実行されます。つまり、継続的インテグレーションを実行する場所としては、サーバーの方がはるかに適しています。

Post-Checkout

post-checkout フックの動作は post-commit とよく似ていますが、git checkout で参照を正常にチェックアウトするたびに呼び出されます。これは、混乱を招くような生成ファイルを作業ディレクトリから消去するのに便利です。

このフックは、3つのパラメータを受け入れます。また、終了ステータスは git checkout コマンドにまったく影響を与えません。

  1. 前の HEAD の ref
  2. 新しい HEAD の ref
  3. ブランチのチェックアウトかファイルのチェックアウトかを示すフラグ。フラグはそれぞれ 10 になります。

Python 開発者によくある問題は、生成された .pyc ファイルがブランチの切り替え後に残る場合に生じます。これらの .pyc.py の代わりにインタープリターで使用されることがあります。混乱を避けるため、新しいブランチをチェックアウトするたびに .pyc をすべて削除できます。このためには、次の post-checkout スクリプトを使用します。

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
previous_head = sys.argv[1]
new_head = sys.argv[2]
is_branch_checkout = sys.argv[3]

if is_branch_checkout == "0":
    print "post-checkout: This is a file checkout. Nothing to do."
    sys.exit(0)

print "post-checkout: Deleting all '.pyc' files in working directory"
for root, dirs, files in os.walk('.'):
    for filename in files:
        ext = os.path.splitext(filename)[1]
        if ext == '.pyc':
            os.unlink(os.path.join(root, filename))

フック スクリプトの現在の作業ディレクトリは常にリポジトリのルートに設定されるため、os.walk ('.') 呼び出しがリポジトリ内のあらゆるファイルを介して繰り返されます。その後で、ファイルの拡張子を確認して .pyc ファイルであれば削除します。

また、post-checkout フックを使用して、チェックアウトしたブランチに基づいて作業ディレクトリを変更することもできます。たとえば、plugins ブランチを使用すると、コア コードベース以外のプラグインをすべて保存できます。これらのプラグインが他のブランチには必要ないバイナリを大量に必要とする場合、plugins ブランチにいるときのみ選択的にバイナリをビルドできます。

Pre-Rebase

pre-rebase フックは git rebase が何かを変更する前に呼び出されるため、大な問題が発生しないことを確認する場所に適しています。

このフックには、対象のシリーズがフォークされた上流ブランチと、リベースされるブランチの2つのパラメーターが必要です。2 番目のパラメーターは現在のブランチのリベース時には空です。リベースを中止するには、ゼロ以外のステータスで終了します。

たとえば、リポジトリでのリベースをすべて禁止したい場合、次の pre-rebase スクリプトを使用できます。

#!/bin/sh

# Disallow all rebasing
echo "pre-rebase: Rebasing is dangerous. Don't do it."
exit 1

これで、git rebase を実行するたびに次のメッセージが表示されるようになります。

pre-rebase: Rebasing is dangerous. Don't do it.
The pre-rebase hook refused to rebase.

さらに詳細な例については、組み込み済みの pre-rebase.sample スクリプトを参照してください。このスクリプトは、リベースを許可しない場合に関して、もう少しインテリジェントに機能します。リベース対象のブランチが、(主流ブランチと想定される) next ブランチに既にマージされているかどうかを確認します。マージされている場合、ブランチのリベースによって問題が生じる可能性があるため、リベースが中止されます。

サーバーサイド フック

サーバー側のフックはローカル側のフックと同じように機能します。異なるのは、サーバー側のリポジトリ (中央リポジトリ、または開発者のパブリックリポジトリなど) にフックが存在していることのみです。公的なリポジトリにある場合、これらのフックの一部は特定のコミットを拒否することで、ポリシーを強制する手段としての役割を果たします。

この記事の残りの部分では、3つのサーバー側フックについて説明します。

  • Pre-Receive
  • Update
  • Post-Receive

これらのフックを使用することで、git push プロセスのさまざまなステージに対処できます。

サーバー側フックからの出力はクライアントのコンソールにパイピングされるため、開発者へのメッセージの返信が非常に簡単です。しかし、これらのスクリプトは実行が完了するまで端末の制御を返さないことも覚えておく必要があります。したがって、長時間続く演算の実行は慎重に行ってください。

Pre-Receive

pre-receive フックは、git push が使用されるたびに実行され、コミットをリポジトリにプッシュします。このフックは、ソース リポジトリではなく、常にプッシュ先であるリモート側のリポジトリに存在している必要があります。

このフックは参照が更新される前に実行されるので、必要なあらゆる種類の開発ポリシーを強制する場所に適しています。プッシュを実行している人、コミット メッセージのフォーマット、またはコミットに含まれている変更内容を受け入れたくない場合は、簡単に拒否できます。開発者が不正な形式のコミットを作成することは止められませんが、pre-receive を使用してこれらのコミットが正式なコードベースに入り込まないように防止することはできます。

スクリプトはパラメーターを必要としませんが、プッシュされる各 ref は、次の形式で標準入力時に別の行にあるスクリプトに渡されます。

<old-value> <new-value> <ref-name>

プッシュされた ref を読み込んで出力するだけの非常に基本的な pre-receive スクリプトを使用すると、このフックがどのように機能するかを確認できます。

#!/usr/bin/env python

import sys
import fileinput

# Read in each ref that the user is trying to update
for line in fileinput.input():
    print "pre-receive: Trying to push ref: %s" % line

# Abort the push
# sys.exit(1)

繰り返しになりますが、これは他のフックとは少し異なり、情報がコマンドライン引数としてではなく標準入力を介してスクリプトに渡されます。上記のスクリプトをリモート リポジトリの .git/hooks に配置し、ディレクトリに main ブランチをプッシュすると、コンソールに以下のような文字列が表示されます。

b6b36c697eb2d24302f89aa22d9170dfe609855b 85baa88c22b52ddd24d71f05db31f4e46d579095 refs/heads/main

一部の低レベル Git コマンドと共にこれらの SHA1 ハッシュを使用して、適用予定の変更を検査できます。 一般的な使用例の一部を次に挙げます。

  • 上流のリベースが関係する変更を拒否する
  • 非ファストフォワードマージを防止する
  • 意図された変更が行われるように (ほとんどの場合、集中化された Git ワークフローが対象)、ユーザーが正しい権限を持っていることを確認する

複数の ref がプッシュされた場合、pre-receive からゼロ以外のステータスが 1 つでも返されると、それらすべての ref が中止されます。ケース バイ ケースでブランチを受け入れまたは拒否したい場合は、代わりに update フックを使用する必要があります。

Update

update フックは pre-receive の後に呼び出され、ほぼ同じように動作します。やはり実際に何かが更新される前に呼び出されますが、プッシュされた ref ごとに別々に呼び出されます。つまり、ユーザーが 4 つのブランチをプッシュしようとすると、update は 4 回実行されます。pre-receive とは異なり、このフックは標準の入力から読み込む必要はありません。代わりに、次の 3 つの引数を受け入れます。

  1. 更新される ref の名前
  2. ref に保存されている旧オブジェクト名
  3. ref に保存されている新規オブジェクト名

これは、pre-receive に渡されるのと同じ情報ですが、update は ref ごとに別に呼び出されるため、一部の ref を拒否して、その他の ref は許可することが可能です。

#!/usr/bin/env python

import sys

branch = sys.argv[1]
old_commit = sys.argv[2]
new_commit = sys.argv[3]

print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit)

# Abort pushing only this branch
# sys.exit(1)

上記の update フックは、単にブランチと新旧のコミット ハッシュを出力します。複数のブランチをリモート リポジトリにプッシュすると、各ブランチに対して print ステートメントが実行されるのがわかります。

Post-Receive

post-receive フックはプッシュ操作が成功した後に呼び出されるため、通知を実行する場所に適しています。多くのワークフローでは、これは post-commit よりも通知をトリガーする場所として適しています。その理由は、変更はユーザーのローカル マシン上にのみ存在するのではなく、パブリック サーバーで利用可能になるためです。他の開発者にメールを送信したり、継続的インテグレーション システムをトリガーしたりすることは、post-receive の一般的な使用例です。

このスクリプトはパラメータを取りませんが、標準の入力により pre-receive と同じ情報が送信されます。

概要

この記事では、リポジトリ内である種のイベントが生じた場合に Git フックを使用して内部動作を変更したり、通知を受け取ったりする方法について学習しました。フックは .git/hooks リポジトリに常駐する普通のスクリプトです。このため、インストールやカスタマイズが非常に簡単です。

また、最も一般的なローカル フックとサーバー側フックについてもいくつか取り上げました。これらを使用して開発ライフサイクル全体に関与することができます。コミット作成プロセスおよび git push プロセスのあらゆるステージでカスタマイズ可能なアクションを実行する方法も習得しました。スクリプト記述の知識が少しあれば、フックを使用して Git リポジトリで想定できることは事実上何でも実行できます。