web-dev-qa-db-ja.com

高速ネットワーク接続を介してgitリポジトリを複製する最も速い方法は何ですか?

比較的大きなgitリポジトリがローカルネットワークの古くて遅いホストに配置されている状況で、最初のクローンの作成にかなりの時間がかかります。

ravn@bamboo:~/git$ git clone gitosis@gitbox:git00
Initialized empty Git repository in /home/ravn/git/git00/.git/
remote: Counting objects: 89973, done.
remote: Compressing objects: 100% (26745/26745), done.
remote: Total 89973 (delta 50970), reused 85013 (delta 47798)
Receiving objects: 100% (89973/89973), 349.86 MiB | 2.25 MiB/s, done.
Resolving deltas: 100% (50970/50970), done.
Checking out files: 100% (11722/11722), done.
ravn@bamboo:~/git$

GitosisにはGit固有の設定変更はありません。

受信ビットをネットワークで可能な範囲まで高速化する方法はありますか?


編集:私は新しいリポジトリが上流のリポジトリと適切に接続されている必要があります。私の理解では、これにはgitがクローンを作成する必要があるため、git外でのrawビットコピーは機能しません。

データの転送速度の上限がgitの「外部」で確立されるssh接続であることを認識した後、私はいくつかの実験を行い、pcsp(PuTTY scp)の使用の上限は3,0 MB/sであることがわかりましたフグの暗号化方式が適切に選択されたためです。 raw ftpを使用した制御実験では、転送速度が3.1 MB /秒であることを示したため、これがネットワークの上限であることがわかりました。

これはVMwareハイパーバイザー内で実行され、ネットワークI/Oを実行するプロセスがほぼ100%のCPUを使用しているため、ボトルネックがUbuntuネットワークカードドライバーであることがわかりました。その後、VMwareツールがインストールされていても、何らかの理由でカーネルがvmxnetドライバー(ハイパーバイザーと直接通信する)の代わりにvlanceドライバー(IRQとすべてで10 MBpsネットワークカードをエミュレート)を使用していることがわかりました。これで、サービスウィンドウが変更されるのを待ちます。

言い換えれば、問題はgitではなく、基礎となる「ハードウェア」にありました。

深度を使用して浅いクローンを作成します。

git clone --depth 1 <repository>
28
northtree

[〜#〜] ps [〜#〜]。公正警告:

gitは通常、非常に高速であると考えられています。 darcs、Bazaar、hg(god forbid:TFSまたはSubversion ...)から完全なリポジトリを複製してみてください。また、定期的に完全なリポジトリを最初から複製すると、とにかく何か問題が発生します。いつでもgit remote updateを使用して、徐々に変更を加えることができます。

fullリポジトリを同期状態に保つための他のさまざまな方法については、たとえば、.

(他の関連するSO投稿へのリンクが含まれています)

ダムコピー

前述のように、「ダム」ファイル転送を使用してリポジトリをコピーすることができます。

これは確かに、圧縮、再梱包、細分化、および/またはフィルタリングに時間を無駄にしません。

さらに、あなたは

これはあなたが必要とするものかもしれないししないかもしれません、しかしそれは事実を知っているのはいいです


バンドル

Gitクローンはデフォルトで帯域幅を最適化します。 git cloneは、デフォルトでは、すべてのブランチをmirrorしない(--mirrorを参照)ため、パックファイルをそのままダンプするだけでは意味がありません(そのため必要以上に送信する可能性があります)。

本当に大きな数のクライアントに配布する場合、bundles

サーバー側のコストなしで高速クローンが必要な場合、git waybundle createです。これで、サーバーに関与することなく、バンドルを配布できます。 bundle... --allに単純なgit clone以外のものが含まれている場合は、たとえば、 bundle ... master音量を下げます。

git bundle create snapshot.bundle --all # (or mention specific ref names instead of --all)

代わりにスナップショットバンドルを配布します。これは両方の長所ですが、もちろん上記の箇条書きの項目はありません。受信側では、

git clone snapshot.bundle myclonedir/

圧縮構成

圧縮を減らしたり削除したりすることで、サーバーの負荷を減らすことができます。これらの構成設定を見てください(pack.compressionはサーバーの負荷を下げるのに役立つと思います)

core.compression

デフォルトの圧縮レベルを示す整数-1..9。 -1はzlibのデフォルトです。 0は圧縮なしを意味し、1..9はさまざまな速度/サイズのトレードオフであり、9が最も遅くなります。設定されている場合、これは、core.loosecompressionやpack.compressionなどの他の圧縮変数にデフォルトを提供します。

core.loosecompression

整数-1..9。パックファイルにないオブジェクトの圧縮レベルを示します。 -1はzlibのデフォルトです。 0は圧縮なしを意味し、1..9はさまざまな速度/サイズのトレードオフであり、9が最も遅くなります。設定しない場合、デフォルトでcore.compressionになります。これが設定されていない場合、デフォルトは1(最高速度)です。

pack.compression

整数-1..9。パックファイル内のオブジェクトの圧縮レベルを示します。 -1はzlibのデフォルトです。 0は圧縮なしを意味し、1..9はさまざまな速度/サイズのトレードオフであり、9が最も遅くなります。設定しない場合、デフォルトでcore.compressionになります。これが設定されていない場合、デフォルトは-1で、zlibのデフォルトは「速度と圧縮の間のデフォルトの妥協点(現在はレベル6と同等)」です。

圧縮レベルを変更しても、既存のすべてのオブジェクトが自動的に再圧縮されるわけではないことに注意してください。 git-repack(1)に-Fオプションを渡すことで、再圧縮を強制できます。

十分なネットワーク帯域幅が与えられた場合、これは実際にはより高速なクローンになりますベンチマークする場合は、git-repack -Fを忘れないでください!

28
sehe

_git clone --depth=1 ..._ 2014年に推奨 は、Git 2.22を使用する2019年第2四半期に速くなります。
これは、最初の "_git clone --depth=..._"部分クローン中に、promisorオブジェクト(定義上、フェッチされたすべてのオブジェクト)を列挙してスキップする接続チェックの大部分にサイクルを費やすのは無意味だからです。反対側から)。
これは最適化されています。

clone:部分的なクローンのオブジェクトチェックを高速化

部分的なクローンの場合、完全な接続チェックを行うのは無駄です。 promisorオブジェクト(部分的なクローンの場合、すべて既知のオブジェクト)をスキップし、それらをすべて列挙して接続性チェックから除外すると、大きなリポジトリではかなりの時間がかかる場合があります。

多くても、必要な参照によって参照されるオブジェクトを確実に取得する必要があります。
部分的なクローンの場合は、これらのオブジェクトが転送されたことを確認してください。

結果:

_  Test                          dfa33a2^         dfa33a2
  -------------------------------------------------------------------------
  5600.2: clone without blobs   18.41(22.72+1.09)   6.83(11.65+0.50) -62.9%
  5600.3: checkout of result    1.82(3.24+0.26)     1.84(3.24+0.26) +1.1%
_

62%高速化!


Git 2.26(2020年第1四半期)では、不要な接続性チェックがフェッチされたときに部分的なクローンで無効になりました。

Jonathan Tan(jhowtan による commit 2df1aa2commit 5003377 (2020年1月12日)を参照してください。
Junio C Hamano-gitster- によってマージ commit 8fb3945 、2020年2月14日)

connected :部分的なクローンのpromisor-nessを確認します

サインオフ:Jonathan Tan
確認者:Jonathan Nieder

コミット dfa33a298d ( "clone:部分的なクローンのオブジェクトチェックを高速化する"、2019-04-21、Git v2.22.0-rc0- merge ) _--filter_を使用して複製するときに実行される接続チェックを最適化して、refsが直接指すオブジェクトの存在のみをチェックするようにしました。
しかし、これは十分ではありません。それらはまた、promisorオブジェクトである必要があります。
これらのオブジェクトがpromisorオブジェクトであること、つまりpromisorパックに表示されることを確認することにより、このチェックをより堅牢にします。

そして:

fetch :_--filter_の場合、完全な接続チェックを行わない

サインオフ:Jonathan Tan
確認者:Jonathan Nieder

フィルターが指定されている場合、フェッチしたパックファイルの内容について完全な接続チェックを行う必要はありません。参照されるオブジェクトがpromisorオブジェクトであることを確認するだけです。

これにより、多数のpromisorオブジェクトが含まれるリポジトリへのフェッチが大幅に高速化されます。これは、接続チェック中にすべてのpromisorオブジェクトが列挙され(それらにUNINTERESTINGとマークを付けるため)、かなりの時間がかかるためです。


また、Git 2.26(2020年第1四半期)でも、オブジェクトの到達可能性のビットマップ機構と部分的なクローン機構は、部分的なクローンが本質的に使用するオブジェクトフィルタリング基準の一部であるため、うまく機能するように準備されていません。オブジェクトトラバーサルでは、ビットマップメカニズムはそのオブジェクトトラバーサルをバイパスするための最適化です。

しかし、彼らが一緒に働くことができるいくつかのケースがあり、彼らはそれらについて教えられました。

Junio C Hamano(gitster による commit 20a5fd8 (2020年2月18日)を参照してください。
commit 3ab3185commit 84243dacommit 4f3bd56commit cc4aa28を参照commit 2aaeb9acommit 6663aecommit 4eb707ecommit ea047a8commit 608d9c9commit 55cb10fcommit 792f811commit d90fe06 (2020年2月14日)、および commit e03f928commit acac50d =、 commit 551cf8b (2020年2月13日)by Jeff King(peff
Junio C Hamano-gitster- によってマージ commit 0df82d9 、2020年3月2日)

_pack-bitmap_ :_BLOB_LIMIT_フィルタリングを実装

サインオフ:Jeff King

以前のコミットが_BLOB_NONE_ を実装したのと同様に、結果のblobのサイズを確認し、必要に応じてそれらのビットの設定を解除することにより、_BLOB_LIMIT_フィルターをサポートできます。
これは_BLOB_NONE,_よりも少し高価ですが、それでも顕著なスピードアップが得られます(これらの結果は git.git にあります):

_Test                                         HEAD~2            HEAD
------------------------------------------------------------------------------------
5310.9:  rev-list count with blob:none       1.80(1.77+0.02)   0.22(0.20+0.02) -87.8%
5310.10: rev-list count with blob:limit=1k   1.99(1.96+0.03)   0.29(0.25+0.03) -85.4%
_

実装は_BLOB_NONE_と似ていますが、blobタイプのビットマップをウォークしながらオブジェクトごとに移動する必要があることを除きます(一致をマスクできないため、サイズを調べる必要があります)各blobに対して個別に)。
ctz64()を使用するコツはshow_objects_for_type()から取られたもので、同様に個々のビットを見つける必要があります(ブロブなしで大きなチャンクをすばやくスキップしたい)。

2
VonC

私はgit cloneをベンチマークしています。

プロジェクトにサブモジュールexが含まれている場合、-jobsオプションを使用すると高速化できます。

git clone --recursive --shallow-submodules --depth 1 --branch "your tag or branch" --jobs 5 --  "your remote repo"
1
dwa.kang

ログから、すでにクローンが完了しているようです。問題が別のマシンでこのプロセスを複数回実行する必要がある場合は、リポジトリディレクトリを1つのマシンから別のマシンにコピーできます。この方法では、各コピーとクローン元のリポジトリの間の関係(リモート)が保持されます。

1
idanzalz