1

プロジェクトには Git を使用しています。リポジトリはかなり巨大です (.gitフォルダは約 8Gb です)。

git checkout -f作業ツリーを更新するために受信後フックで使用しています。

問題は、わずかに変更された 2 つのファイルのチェックアウトでも、約 20 秒と非常に時間がかかることです。なんでこんなに長いのかわからない。

それはリポジトリのサイズの問題でしょうか?

問題を特定してさらに調査するには、どの手順またはツールを試す必要がありますか?

助けてくれてありがとう。

よろしく、アレックス

4

2 に答える 2

1

元の回答 (2012 年 11 月)

.gitgit ディレクトリ ( ) をそれほど大きくしておくと、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 201155cJunio 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 1ba5f45commit f934f1bcommit daa1acecommit 11042abcommit 0d53d19 (29 Jun 2021) by Derrick Stolee ( derrickstolee)を参照してください。
( 2021 年 8 月 4 日、コミット 506d2a3Junio 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 ミリ秒のオーバーヘッドに寄与します。

于 2012-11-06T15:11:58.933 に答える