元の回答 (2012 年 11 月)
.git
git ディレクトリ ( ) をそれほど大きくしておくと、git の速度が大幅に低下することを確認しています。
このスレッドで図を確認できます(ファイルが大きいためではなく、多数のファイルとコミット履歴のため)。
テスト リポジトリには、400 万件のコミット、線形の履歴、約 130 万のファイルがあります。
ディレクトリのサイズ.git
は約 15GB で、'
git repack -a -d -f --max-pack-size=10g --depth=100 --window=250
この再パックには、強力なマシン (つまり、大量の RAM とフラッシュ) で約 2 日かかりました。
インデックス ファイルのサイズは 191 MB です。
少なくとも、リポジトリを分割し、バイナリを独自の git リポジトリに分離し、サブモジュールを使用してソース リポジトリとバイナリ リポジトリを追跡することを検討できます。
大きなバイナリ ファイル (特に生成された場合) は、ソース参照の外に格納することをお勧めします。Nexus
のような「アーティファクト」リポジトリが推奨されます。
これらのバイナリを維持するオール git ソリューションは、「大きな git リポジトリを処理する方法」に示されているように、git-annex または git-mediaです。
2016 年 2 月の更新: git 2.8 (2016 年 3 月) では、パフォーマンスが大幅に向上するはずgit checkout
です。
David Turner ( )による commit a672095 ( 2016 年 1 月 22 日) とcommit d9c2bd5 (2015 年 12 月 21 日)を参照してください。( 2016 年 2 月 3 日にcommit 201155cでJunio C Hamanoによってマージされました)dturner-tw
gitster
unpack-trees
: 偶発的な 2 次動作を修正
ツリーをアンパックしている間 (例: 中git checkout
)、パスを過ぎてパスの外にあるキャッシュ エントリにヒットすると、反復が中断されます。
master^20000
これにより、master とTwitter の monorepo間の git checkout が約 45% 高速化され
ます。
一般的なスピードアップは、リポジトリの構造、変更の数、およびパックファイルのパッキングの決定によって異なります。
do_compare_entry
: 計算済みのパスを使用
traverse_trees では、 の完全なトラバース パスを生成しますtraverse_info
。
後の do_compare_entry では、traverse_info
パスを計算せずに cache_entry の名前と比較するために、多くの作業を行っていました。
しかし、そのパスは既にあるので、すべての作業を行う必要はありません。
代わりに、生成されたパスを に入れ、traverse_info
比較をより直接的に行うことができます。
これによりgit checkout
、Twitter の monorepo で約 25% 高速化されます。
ディレクトリ ツリーが深いほど、浅いものよりも多くのメリットがあります。
sparse-checkoutを使用すると、巨大なリポジトリのチェックアウトが大幅に高速化されます。
そして、これは Git 2.33 (2021 年第 3 四半期) でさらに改善され、 " git checkout
" ( man )と( man )は不必要にスパース インデックスを拡張することなく機能することを学びました。git commit
commit e05cdb1、commit 70569fa (2021 年 7 月 20 日)、およびcommit 1ba5f45、commit f934f1b、commit daa1ace、commit 11042ab、commit 0d53d19 (29 Jun 2021) by Derrick Stolee ( derrickstolee
)を参照してください。
( 2021 年 8 月 4 日、コミット 506d2a3でJunio C Hamanoによってマージされました)gitster
checkout
: スパース インデックスの展開を停止します
署名者: Derrick Stolee
以前の変更では、ツリーとの比較に基づいて疎インデックスを変更するためにunpack-trees.c
必要な改善が行われました。
残りの作業は、いくつかの呼び出しを削除し、興味深いケースでインデックスが展開されていないことを確認するテストを追加することだけです。
「スイッチ」と「復元」は「チェックアウト」と基本実装を共有するため、これらのテストに含めます。diff-lib.c
ensure_full_index()
p2000-sparse-operations.sh からの関連するパフォーマンス結果は次のとおりです。
Test HEAD~1 HEAD
--------------------------------------------------------------------------------
2000.18: git checkout -f - (full-v3) 0.49(0.43+0.03) 0.47(0.39+0.05) -4.1%
2000.19: git checkout -f - (full-v4) 0.45(0.37+0.06) 0.42(0.37+0.05) -6.7%
2000.20: git checkout -f - (sparse-v3) 0.76(0.71+0.07) 0.04(0.03+0.04) -94.7%
2000.21: git checkout -f - (sparse-v4) 0.75(0.72+0.04) 0.05(0.06+0.04) -93.3%
スパース インデックスの以前の結果はインデックスの拡張によって膨らんだため、フル インデックスのケースとスパース インデックスのケースを比較することが重要です。
インデックス v4 の場合、これは 88% の改善です。
HEAD に 200 万を超えるパスがあり、それらのパスのうち約 60,000 を含むスパース チェックアウト定義を持つ内部リポジトリでは、この変更により ' git checkout
' ( man )が 3.5 秒から 297 ミリ秒になりました。
これらの最大 60,000 パスのみが存在する場合の理論上の最適値は 275 ミリ秒だったので、余分なスパース ディレクトリ エントリは 22 ミリ秒のオーバーヘッドに寄与します。