Git
英語 ▾ トピック ▾ 最新バージョン ▾ git-receive-pack は2.43.0で最後に更新されました

名前

git-receive-pack - リポジトリにプッシュされた内容を受信する

概要

git receive-pack <git-dir>

説明

git send-pack によって呼び出され、リモートエンドから送られた情報でリポジトリを更新します。

このコマンドは通常、エンドユーザーによって直接呼び出されることはありません。プロトコルのUIは git send-pack側にあり、プログラムのペアはリモートリポジトリに更新をプッシュするために使用されます。プル操作については、git-fetch-pack[1] を参照してください。

このコマンドは、リモートエンドでsha1 refs(heads/tags)の作成と早送り更新を可能にします(厳密に言えば、ローカルエンドの git-receive-pack が実行されますが、send-packエンドにいるユーザーにとっては、リモートを更新しています。混乱しましたか?)。

Documentation/howto ディレクトリには、updateフックとpost-updateフックの使用例が他にもあります。

git-receive-pack は receive.denyNonFastForwards 設定オプションを尊重します。このオプションは、refの更新が早送りでない場合に拒否するかどうかを指定します。

動作を調整するために、他にも多くの receive.* 設定オプションが利用できます。 git-config[1] を参照してください。

オプション

<git-dir>

同期するリポジトリ。

--http-backend-info-refs

git-http-backend[1]$GIT_URL/info/refs?service=git-receive-pack リクエストを提供するために使用されます。 git-upload-pack[1]--http-backend-info-refs を参照してください。

PRE-RECEIVE フック

refが更新される前に、$GIT_DIR/hooks/pre-receive ファイルが存在し、実行可能であれば、パラメータなしで1回呼び出されます。フックの標準入力は、更新されるrefごとに1行になります。

sha1-old SP sha1-new SP refname LF

refnameの値は$GIT_DIRからの相対パスです。例えば、masterヘッドの場合は "refs/heads/master" です。各refnameの前にある2つのsha1値は、更新前と更新後のrefnameのオブジェクト名です。作成されるrefはsha1-oldが0{40}になり、削除されるrefはsha1-newが0{40}になります。そうでない場合、sha1-oldとsha1-newはリポジトリ内の有効なオブジェクトでなければなりません。

署名付きプッシュを受け入れる場合(git-push[1] 参照)、署名付きプッシュ証明書はBLOBに格納され、環境変数 GIT_PUSH_CERT でそのオブジェクト名を参照できます。例については、post-receive フックの説明を参照してください。さらに、証明書はGPGを使用して検証され、結果は次の環境変数を使用してエクスポートされます。

GIT_PUSH_CERT_SIGNER

プッシュ証明書に署名した鍵の所有者の名前と電子メールアドレス。

GIT_PUSH_CERT_KEY

プッシュ証明書に署名した鍵のGPG鍵ID。

GIT_PUSH_CERT_STATUS

git log ファミリーコマンドの %G? 形式で使用されているのと同じニーモニックを使用して、プッシュ証明書のGPG検証の状態を示します(git-log[1] 参照)。

GIT_PUSH_CERT_NONCE

プロセスが署名者にプッシュ証明書に含めるように要求したnonce文字列。これがプッシュ証明書の "nonce" ヘッダーに記録されている値と一致しない場合、証明書は有効ですが、別の "git push" セッションから再生されている可能性を示している可能性があります。

GIT_PUSH_CERT_NONCE_STATUS
UNSOLICITED

"git push --signed" は、要求していないnonceを送信しました。

MISSING

"git push --signed" はnonceヘッダーを送信しませんでした。

BAD

"git push --signed" は不正なnonceを送信しました。

OK

"git push --signed" は、要求したnonceを送信しました。

SLOP

"git push --signed" は、現在要求したnonceとは異なるnonceを送信しましたが、以前のセッションで送信したnonceです。 GIT_PUSH_CERT_NONCE_SLOP 環境変数を参照してください。

GIT_PUSH_CERT_NONCE_SLOP

"git push --signed" は、現在要求したnonceとは異なるnonceを送信しましたが、開始時刻が現在のセッションからこの秒数だけ異なる別のセッションで送信したnonceです。 GIT_PUSH_CERT_NONCE_STATUSSLOP となっている場合にのみ意味があります。 git-config[1]receive.certNonceSlop 変数についても読んでください。

このフックは、refnameが更新される前、および早送りチェックが実行される前に呼び出されます。

pre-receiveフックがゼロ以外の終了ステータスで終了した場合、更新は実行されず、update、post-receive、post-updateフックも呼び出されません。これは、更新がサポートされない場合にすぐに処理を中止するのに役立ちます。

以下の隔離環境に関する注意事項を参照してください。

UPDATE フック

各refが更新される前に、$GIT_DIR/hooks/update ファイルが存在し、実行可能であれば、refごとに1回、3つのパラメータで呼び出されます。

$GIT_DIR/hooks/update refname sha1-old sha1-new

refnameパラメータは$GIT_DIRからの相対パスです。例えば、masterヘッドの場合は "refs/heads/master" です。2つのsha1引数は、更新前と更新後のrefnameのオブジェクト名です。フックはrefnameが更新される前に呼び出されるため、sha1-oldは0{40}(まだそのようなrefがないことを意味する)であるか、refnameに記録されているものと一致する必要があります。

フックは、指定されたrefの更新を許可しない場合は、ゼロ以外のステータスで終了する必要があります。そうでない場合は、ゼロで終了する必要があります。

このフックが正常に実行された(終了ステータスがゼロ)としても、refが実際に更新されることは保証されず、前提条件に過ぎません。そのため、このフックから通知(例:電子メール)を送信するのは良い考えではありません。代わりにpost-receiveフックを使用することを検討してください。

POST-RECEIVE フック

すべてのrefが更新された(または更新が試行された)後、refの更新が成功し、$GIT_DIR/hooks/post-receive ファイルが存在し、実行可能であれば、パラメータなしで1回呼び出されます。フックの標準入力は、正常に更新されたrefごとに1行になります。

sha1-old SP sha1-new SP refname LF

refnameの値は$GIT_DIRからの相対パスです。例えば、masterヘッドの場合は "refs/heads/master" です。各refnameの前にある2つのsha1値は、更新前と更新後のrefnameのオブジェクト名です。作成されたrefはsha1-oldが0{40}になり、削除されたrefはsha1-newが0{40}になります。そうでない場合、sha1-oldとsha1-newはリポジトリ内の有効なオブジェクトでなければなりません。

pre-receive フックと同様に、署名付きプッシュを受け入れた後、GIT_PUSH_CERT* 環境変数を調べることができます。

このフックを使用すると、リポジトリの更新内容を記述したメールを簡単に生成できます。このスクリプトの例では、リポジトリにプッシュされたコミットをリストしたメールをrefごとに1通送信し、有効な署名を持つ署名付きプッシュのプッシュ証明書をロガーサービスに記録します。

#!/bin/sh
# mail out commit update information.
while read oval nval ref
do
	if expr "$oval" : '0*$' >/dev/null
	then
		echo "Created a new ref, with the following commits:"
		git rev-list --pretty "$nval"
	else
		echo "New commits:"
		git rev-list --pretty "$nval" "^$oval"
	fi |
	mail -s "Changes to ref $ref" commit-list@mydomain
done
# log signed push certificate, if any
if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G
then
	(
		echo expected nonce is ${GIT_PUSH_NONCE}
		git cat-file blob ${GIT_PUSH_CERT}
	) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain
fi
exit 0

このフック呼び出しからの終了コードは無視されますが、ゼロ以外の終了コードはエラーメッセージを生成します。

このフックが実行されるときに、refnameにsha1-newがない場合があることに注意してください。これは、git-receive-packによってrefが更新された後、フックがそれを評価できるようになる前に、別のユーザーがrefを変更した場合に簡単に発生する可能性があります。フックは、refnameの現在の値ではなく、sha1-newに依存することをお勧めします。

POST-UPDATE フック

他のすべての処理の後、少なくとも1つのrefが更新され、$GIT_DIR/hooks/post-updateファイルが存在し、実行可能であれば、post-updateは更新されたrefのリストと共に呼び出されます。これは、リポジトリ全体のクリーンアップタスクを実装するために使用できます。

このフック呼び出しからの終了コードは無視されます。git-receive-packがその時点で実行できる唯一のことは、自身を終了することです。

このフックは、例えば、リポジトリがパックされ、ダムトランスポートを介して提供される場合に、git update-server-infoを実行するために使用できます。

#!/bin/sh
exec git update-server-info

隔離環境

receive-packがオブジェクトを受け取ると、それらは$GIT_DIR/objectsディレクトリ内の一時的な「隔離」ディレクトリに配置され、pre-receiveフックが完了した後にのみメインオブジェクトストアに移行されます。プッシュがそれ以前に失敗した場合、一時ディレクトリは完全に削除されます。

これには、ユーザーに見えるいくつかの影響と注意点があります。

  1. 受信パックの問題、オブジェクトの欠落、またはpre-receiveフックが原因で失敗したプッシュは、ディスク上にデータを残しません。これは通常、繰り返し失敗したプッシュによってディスクがいっぱいになるのを防ぐのに役立ちますが、デバッグをより困難にする可能性があります。

  2. pre-receiveフックによって作成されたオブジェクトはすべて、隔離ディレクトリに作成されます(そして、成功した場合にのみ移行されます)。

  3. pre-receiveフックは、隔離されたオブジェクトを指すようにrefを更新してはなりません。リポジトリにアクセスする他のプログラムは、オブジェクトを参照できません(また、pre-receiveフックが失敗した場合、それらのrefは破損します)。安全のために、pre-receive内からのrefの更新は自動的に拒否されます。

GIT

git[1]スイートの一部

scroll-to-top