Overall operation
-
リモート側に接続し、 git-receive-pack を呼び出します。
-
リモートが持っているref達と、リモートが指しているコミットを知ります。 それらを私たちがプッシュしているrefspec達にマッチさせます。
-
非早送り(non-fast-forwards)があるかどうかを確認します。 fetch-packとは異なり、早送りの場合、リポジトリ send-pack の実行は受信側のスーパーセットであると想定されるため、 want(欲しい)/have(持っている) やり取りの必要はなく、早送りチェックをローカルで実行できます。 結果をもう一方の側に伝えます。
-
pack_objects() を呼び出して、パックファイルを生成し、それをもう一方の側に送信します。
-
リモート側が十分に新しい場合(v1.1.0以降)、もう一方の側からのアンパックと、フックのステータスを待ちます。
-
適切なエラーコードで終了します。
Pack_objects pipeline
この関数は、ソケット(ネットワーク経由)、またはパイプ(ローカル)のいずれか1つのファイルデスクリプタ(fd
)を取得します。 このfdに書き込まれる何かは、アンパックするために git-receive-pack に送られます。
send-pack ---> fd ---> receive-pack
関数 pack_objects は、パイプを作成してからフォークします。 フォークされた子は、標準入力からリビジョンパラメータを受け取るために、 --revs
を指定して pack-objects を実行します。 このプロセスは、パックファイルをもう一方の側に書き込みます。
send-pack
|
pack_objects() ---> fd ---> receive-pack
| ^ (pipe)
v |
(child)
子のdup2は、標準出力を相手側に戻し、標準入力をパイプから読み込むように手配します。 その後、pack-objects を実行します。 一方、親プロセスは、子プロセスのパイプラインへの供給を開始する前に、パイプラインの読み込み側と、receive-pack への fd を閉じます。
send-pack
|
pack_objects(parent)
|
v [0]
pack-objects [0] ---> receive-pack
[jc: 以前のバグを理解する前は、パイプラインははるかに複雑でドキュメントが必要でしたが、 今ではとても単純です。]