「'receive-pack' timed out on server.fatal: The remote end hung up unexpectedly」エラー
症状
git push
の後に次のメッセージが表示される。
git push origin --all
Counting objects: 9554, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5064/5064), done.
Writing objects: 100% (9554/9554), 2.79 GiB | 444.00 KiB/s, done.
Total 9554 (delta 4382), reused 9554 (delta 4382)
'receive-pack' timed out on server.fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly
原因
サイズの大きい push で (例: 非常に大きなリポジトリの初回プッシュ) で、Bitbucket Server がタイムアウトしている。
ソリューション
Git は、ソースファイルのようなテキストベースのコンテンツに関しては、非常に高速で効率的な SCM です。差分圧縮を使ってリポジトリの内容や履歴を効率的に圧縮するため、リポジトリがコンパクトになります。git リポジトリは、同等の Subversion リポジトリの半分、あるいはそれ以下のサイズになることがよくあります。この圧縮にはコストがかかります。特に大きなファイルの場合には、差分を計算するのに CPU とメモリを消費します。また、git が行う一貫性チェックの一部にも影響します。単純なオブジェクトを扱う代わりに、差分の連鎖を考慮しなければなりません。
コード リポジトリの場合、これは非常にうまく機能します。通常、変更とプッシュはかなり小さいため、差分圧縮によって追加されるオーバーヘッドはわずかです。その結果、クローン作成 (およびフェッチ) が高速化された小さなリポジトリが作成されます。残念ながら、これらの最適化により、git は大規模なバイナリ コンテンツを含むリポジトリにとっては理想的とは言えなくなります。差分縮と一貫性チェックのオーバーヘッドが非常に顕著になります。個々のオブジェクトが大きいため、git が使用する内部キャッシュは十分な大きさではないことが多く、git は常にディスクからオブジェクトを再読み取りする必要があるため、整合性チェックが完了するまでに時間がかかります。できることはいくつかありますが、それぞれに違ったトレードオフがあります。
オプション 1 - 最初のプッシュが確実に完了するように、プロセス タイムアウトを十分に大きく設定する
最初のプッシュは特に遅くなります。その後のプッシュはそれほどではないものの、それでもかなり遅くなります。このオプションを選択する場合は、最初のプッシュが確実に完了するように、プロセス タイムアウトを十分に大きく設定してください (必要であれば 1 日に設定してください)。 最初のプッシュが完了したら、低い値に戻してください。タイムアウトは、暴走したプロセスが発生した場合に確実にクリーンアップするための安全メカニズムとして存在します。このアクションを実行するには、 Bitbucket Server の設定プロパティで、パラメーター「plugin.bitbucket-git.backend.timeout.execution
」を調整してください。
オプション 2 -特定のファイル タイプを圧縮しないようにリポジトリを設定する
これにより、リポジトリ内の大きなバイナリ ファイルが圧縮されないため、プッシュが速くなります。ただし、リポジトリが大幅に大きくなり、クローニングに時間がかかります。また、そのリポジトリのすべてのローカル クローンを大きくするので、トレードオフになります。このオプションを試すには、リポジトリ (マスター上) に .gitattributes
にファイルを追加してください。例として、次の .gitattributes ファイルは .psd ファイルの差分圧縮を無効にし、git がテキストによる差分を行わないように、ファイルをバイナリとしてマークします。
*.psd binary
*.psd -delta
ファイルをコミットし、Bitbucket Server にプッシュする前に git でリポジトリを再パックします (これはおそらく時間がかかります)。
git repack
オプション 3 -リポジトリから大きなオブジェクトを削除する
http://blogs.atlassian.com/2014/05/handle-big-repositories-git/ では、大きなオブジェクトを履歴から取り除いたり、リポジトリを複数のリポジトリに分割したり、git-annex などの git 拡張機能を使用して大きなバイナリー資産を管理したりするためのテクニックをいくつか紹介しています。