パック ファイルが破損している場合 (つまり、pack-objects が失敗した場合)、プッシュは (postBuffer を増やしても) フリーズする可能性があることに注意してください。
これは git 2.9 (2016 年 6 月) で修正される予定です。Git 2.25 でより適切に管理 (2020 年第 1 四半期)
commit c4b2751、commit df85757、commit 3e8b06d、commit c792d7b、commit 739cf49 (2016 年 4 月 19 日) by Jeff King ( peff
)を参照してください。
( 2016 年 4 月 29 日にコミット d689301でJunio C Hamanoによってマージされました)gitster
" git push
" デッドロックされた多数の参照をプッシュしようとする破損したリポジトリから。これらの ref 更新の拒否通知をリレーするスレッドは、受信側のメイン スレッドがプッシュが失敗したことを認識し、これらの通知を読み取らずに失敗を返すことを決定した後、メイン スレッドへの書き込み時にブロックされます。
コミット 739cf49にすべての詳細があります。
send-pack
: 非同期処理を終了する前に demux パイプを閉じます
これにより、破損したリポジトリから多数の参照をプッシュする際のクライアント側のデッドロックが修正されます。
Git 2.25 (2020 年第 1 四半期) では、「git push
」が packdata の送信を完了し、リモート側への応答を待機した後のエラー処理が改善されました。
Jeff King ( )によるcommit ad7a403 (2019 年 11 月 13 日)を参照してください。( 2019 年 12 月 1 日にコミット 3ae8defでJunio C Hamanoによってマージされました)peff
gitster
send-pack
: pack-objects の失敗時にリモート ref ステータスをチェックします
支援者: SZEDER Gábor
署名者: Jeff King
パックをプッシュしていて、ローカルのパック オブジェクトが失敗した場合、いくつかのことを行うエラー コード パスを入力します。
- すべての参照のステータスを
REF_STATUS_NONE
receive_unpack_status()
反対側からエラー レポートを取得するために呼び出します
- 呼び出し元にエラーを返す
サーバーへの接続が切断されたために失敗した場合pack-objects
は、ハングアップを報告する以外にできることはありません。実際、ステップ 2 は反対側からパケットを読み取ろうとします。これはdie()
、パケット読み取りコードで " the remote end hung up unexpectedly
" になります。
しかし、接続が切断されなかった場合、最も一般的な問題は、リモートindex-pack
またはunpack-objects
パックについて不満があったことです (ローカルの pack-objects エラーも発生する可能性がありますが、これは結局同じです。不完全なパックを送信することになります)。そしてリモート側は不平を言うでしょう)。
その場合、(ステップ 2 のため) 反対側からエラーを報告しますが、ref についてはそれ以上何も言いません。
問題は 2 つあります。
- ステップ 1 の "
NONE
" ステータスは、「エラーが発生したため、ステータスがありません」ではありません。
これは通常、「この ref は refspecs と一致しなかったため、プッシュしようとしなかった」ことを意味します。したがって、プッシュ ステータス テーブルを出力するときは、ref についてはまったく言及しません。
しかし、「pack-objects error」のステータス列挙型があったとしても、すべての参照に対してやみくもにそれを設定したくはありません。たとえば、非アトミック プッシュでは、クライアント側で既に一部の参照を拒否している可能性があり (例: REF_STATUS_REJECT_NODELETE
)、それを報告する必要があります。
- ステップ 2 では、アンパック ステータスのみを読み取ります。
しかしreceive-pack
、各参照についても教えてくれます (通常、アンパッカーのエラーのために拒否されたことがわかります)。
したがって、はるかに優れた戦略は、ref ステータス フィールドをそのままにしておくことです (通常はEXPECTING_REPORT)
、ref ごとの完全なステータスを実際に受信 (および出力) します)。
このケースは、リモートの unpack-objects によって拒否されるパックを作成する t5504.8 として、テスト スイートで実際にカバーされています。
しかし、それは際どいです。私たちのパックは小さいので、ほとんどの場合、pack-objects はリモートが拒否する前にすべてを書き込むことができます。そのため、成功が返され、リモートからエラーが出力されます。
しかし、非常にまれに (または で実行した場合--stress
)、書き込みに失敗するほど遅くなりgit push
、ref に対して何も報告しません。
このパッチにより、テストは一貫して動作するはずです。
このアプローチにマイナス面はないはずです。
- 接続が切断されたことが実際に確認された場合、私たちはすでに で死んでおり
receive_unpack_status()
、今後もそうするでしょう。
- unpack ステータスを取得した後、ref ステータスが表示される前に接続が切断された場合でも、リモート アンパッカー エラーが出力されますが、コール スタックにエラーが返される代わりに、「リモート エンドがハングアップしました」と表示されます。
しかし、議論したように、現在のコードではそれ以上に役立つものは何も示されていませんでした。いずれにせよ、そのようなケースはほとんどありません (イベントの順序により、その時点でドロップする接続は pack-objects エラーとは無関係である必要があります)。
将来的には、ハングアップした場合でも完全な ref ステータス テーブルを出力する、死ぬのではなく、自分でパケット読み取りエラーを処理したいと思うかもしれません。
しかし、当面は、このパッチで厳密な改善を行う必要があります。