比較的大きな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>
[〜#〜] ps [〜#〜]。公正警告:
git
は通常、非常に高速であると考えられています。 darcs、Bazaar、hg(god forbid:TFSまたはSubversion ...)から完全なリポジトリを複製してみてください。また、定期的に完全なリポジトリを最初から複製すると、とにかく何か問題が発生します。いつでもgit remote update
を使用して、徐々に変更を加えることができます。fullリポジトリを同期状態に保つための他のさまざまな方法については、たとえば、.
(他の関連するSO投稿へのリンクが含まれています)
前述のように、「ダム」ファイル転送を使用してリポジトリをコピーすることができます。
これは確かに、圧縮、再梱包、細分化、および/またはフィルタリングに時間を無駄にしません。
さらに、あなたは
これはあなたが必要とするものかもしれないししないかもしれません、しかしそれは事実を知っているのはいいです
Gitクローンはデフォルトで帯域幅を最適化します。 git cloneは、デフォルトでは、すべてのブランチをmirrorしない(--mirror
を参照)ため、パックファイルをそのままダンプするだけでは意味がありません(そのため必要以上に送信する可能性があります)。
本当に大きな数のクライアントに配布する場合、bundles。
サーバー側のコストなしで高速クローンが必要な場合、git wayはbundle 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
を忘れないでください!
_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 2df1aa2 、 commit 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 3ab3185 、 commit 84243da 、 commit 4f3bd56 、 commit cc4aa28 、 を参照commit 2aaeb9a 、 commit 6663ae 、 commit 4eb707e 、 commit ea047a8 、 commit 608d9c9 、 commit 55cb10f 、 commit 792f811 、 commit d90fe06 (2020年2月14日)、および commit e03f928 、 commit 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()
から取られたもので、同様に個々のビットを見つける必要があります(ブロブなしで大きなチャンクをすばやくスキップしたい)。
私はgit cloneをベンチマークしています。
プロジェクトにサブモジュールexが含まれている場合、-jobsオプションを使用すると高速化できます。
git clone --recursive --shallow-submodules --depth 1 --branch "your tag or branch" --jobs 5 -- "your remote repo"
ログから、すでにクローンが完了しているようです。問題が別のマシンでこのプロセスを複数回実行する必要がある場合は、リポジトリディレクトリを1つのマシンから別のマシンにコピーできます。この方法では、各コピーとクローン元のリポジトリの間の関係(リモート)が保持されます。