NFS上にあるLinuxマシンに10 GBのリポジトリがあります。最初のgit status
は36分かかり、その後のgit status
は8分かかります。 GitはファイルをキャッシュするためにOSに依存しているようです。リポジトリ全体をパック/リパックするgit
、commit
などの最初のstatus
コマンドのみが、巨大なリポジトリに非常に長い時間がかかります。このような大きなリポジトリでgit status
を使用したかどうかはわかりませんが、この問題に遭遇した人はいますか?
git gc
、git clean
、git repack
を試しましたが、かかった時間はまだ/ほぼ同じです。
サブモジュールや、リポジトリを小さなものに分割するような他の概念は役立ちますか?その場合、より大きなレポを分割するのに最適です。大きなリポジトリでgitコマンドにかかる時間を改善する他の方法はありますか?
より正確には、gitはlstat(2)
システムコールの効率に依存するため、クライアントの “ attribute cache timeout” を調整することで問題を解決できる場合があります。
git-update-index
のマニュアル—本質的にgit-status
のマニュアルモード—これを軽減するためにできることを --assume-unchanged
フラグを使用 で説明し、通常の動作を抑制します変更したパスを手動で更新します。ファイルを保存するたびにこのフラグを設定解除するようにエディターをプログラムすることもできます。
別の方法として、チェックアウトのサイズを小さくすることもできます(ここでは、パックファイルのサイズは実際には関係ありません)。オプションは、スパースチェックアウト、サブモジュール、またはGoogleの repo ツールです。
(メーリングリストがあります NFSでのGitの使用に関するスレッド ですが、多くの質問には答えていません。)
NFSで共有されている大規模なプロジェクトでもこの問題が発生しています。
Git commitとgit statusの両方に指定できるフラグ-unoを見つけるのに時間がかかりました。
このフラグは、追跡されていないファイルの検索を無効にします。これにより、nfs操作の数が大幅に削減されます。理由は、gitが追跡されていないファイルを発見するために、すべてのサブディレクトリを調べる必要があるため、多くのサブディレクトリがある場合、これがあなたを傷つけるからです。 gitが追跡されていないファイルを探すのを無効にすることで、これらすべてのNFS操作を排除できます。
これをcore.preloadindexフラグと組み合わせると、NFS上でも適切なパフォーマンスを得ることができます。
git gc を試してください。また、 git cleanmayヘルプ。
[〜#〜] update [〜#〜]-反対票の出所は不明ですが、gitマニュアルには具体的に次のように記載されています。
現在のリポジトリ内で、ファイルリビジョンの圧縮(ディスクスペースとパフォーマンスの向上を圧縮する)や到達できない可能性のあるオブジェクトの削除など、多数のハウスキーピングタスクを実行しますgit addの以前の呼び出しから作成されています。
ユーザーは、各ディスク内でこのタスクを定期的に実行して、ディスク領域の使用率と動作パフォーマンスを維持することをお勧めします。
Git statusが遅いときにgit gcを実行すると、常に違いに気付きます!
UPDATE II-どうやってこれを見逃したかわかりませんが、OPはすでにgit gcとgit cleanを試しました。元々そこにはなかったと誓いますが、編集に変更は見られません。そのために残念!
Gitリポジトリがサブモジュールを多用している場合、.gitディレクトリの設定ファイルを編集し、ignore = dirty
特に大きな/重いサブモジュールの場合。例えば:
[submodule "mysubmodule"]
url = ssh://mysubmoduleURL
ignore = dirty
忘れている可能性のあるサブモジュールにステージングされていない変更があるというリマインダーの利便性は失われますが、サブモジュールがメインリポジトリと同期していないことを知ることの主な利便性は保持されます。さらに、作業ディレクトリをサブモジュール自体に変更し、通常どおりサブモジュール内でgit statusを使用して詳細情報を表示できます。 「ダーティ」の意味の詳細については、 この質問 を参照してください。
Git statusのパフォーマンスはGit 2.13(2017年第2四半期)で改善されるはずです。
commit 950a234 (2017年4月14日)by Jeff Hostetler(jeffhostetler
) を参照してください。
( C浜野潤夫-gitster
- in commit 8b6bba6 、2017年4月24日)
string-list
:ALLOC_GROW
の再割り当て時に string_list
マクロ を使用
string_list
配列を再割り当てするときは、単純に32ずつ増やすのではなく、ALLOC_GROW()
マクロを使用します。
これはパフォーマンスの最適化です。非常に大きなレポのステータスで多くの変更がある場合、合計実行時間のかなりの割合が
wt_status.changes
array の再割り当てに費やされます。この変更により、非常に大きなリポジトリで
wt_status_collect_changes_worktree()
の時間が125秒から45秒に短縮されます。
さらに、Git 2.17(2018年第2四半期)では、インデックスが多い操作で時間を費やしている場所を測定するための新しいトレースが導入されます。
commit ca54d9b (2018年1月27日)by NguyễnTháiNgọcDuy(pclouds
) を参照してください。
( 浜野潤夫-gitster
- in commit 090dbea 、2018年2月15日)
trace
:インデックスの多い操作で時間が費やされる場所を測定します既知のすべての重いコードブロックが測定されます(オブジェクトデータベースアクセスを除く)。これは、最適化が効果的かどうかを識別するのに役立つはずです。
最適化されていないgit-statusは、次のようなものになります。
0.001791141 s: read cache ...
0.004011363 s: preload index
0.000516161 s: refresh index
0.003139257 s: git command: ... 'status' '--porcelain=2'
0.006788129 s: diff-files
0.002090267 s: diff-index
0.001885735 s: initialize name hash
0.032013138 s: read directory
0.051781209 s: git command: './git' 'status'
同じGit 2.17(2018年第2四半期)では、git status
が次のように改善されています。
コミットf39a757 、 コミット3ca1897 、 コミットfd9b544 、 コミットd7d1b49 (2018年1月9日)作成 ジェフHostetler(jeffhostetler
) 。
( ジュニオC浜野-gitster
- in commit 4094e47 、2018年3月8日)
"git status
"は、現在のブランチとその上流との関係を計算するのに多くのサイクルを費やすことができますが、これは "--no-ahead-behind
"オプションで無効にできます。
commit ebbed3b (2018年2月25日)by Derrick Stolee(derrickstolee
) .
revision.c
:オブジェクトデータベースクエリの削減
mark_parents_uninteresting()
では、オブジェクトファイルの存在をチェックして、コミットを解析済みとして扱う必要があるかどうかを確認します。その結果、コミット時に「解析済み」ビットが設定されます。結果が解析されたビットを変更する場合にのみ
has_object_file()
をチェックするように条件を変更します。ローカルブランチがその上流の参照と異なる場合、「
git status
」は前/後カウントを計算します。
これはPaint_down_to_common()
を使用し、mark_parents_uninteresting()
をヒットします。リモートブランチ「
Origin/master
」の背後にある「master」のローカルインスタンスを〜60,000コミットしたLinuxリポジトリのコピーでは、「git status
」のパフォーマンスが-7.0の相対差で1.42秒から1.32秒になったことがわかります。 %。
git config --global core.preloadIndex true
私のために仕事をしました。公式ドキュメントを確認してください こちら 。
20〜30個のサブモジュールの範囲にあるコードベースでは、git status --ignore-submodules
大幅にスピードアップしました。これはサブモジュールのステータスについてはレポートしませんであることに注意してください。
私はそれがどのような意味を持っているのか分かりませんが、私にとってステータスは30分かかっていたので、ウェブで見つけることができるものすべてを試しました、最後に、git reset
stashが別のブランチから作成されたが、このブランチに適用されたstashから適用された100の変更があり、それらはすべてステージングされたがコミットされなかった(説明するだけで、この問題に遭遇する前に私が何をしたか)、git reset
は15分かかりましたが、その後、ステータスが1秒未満のようにすべてがすぐに機能し始めました。私は自分の問題を解決した理由を伝えるだけでgitの専門家ではありません。
まだ言及されていないことは、Windowsマシンでファイルシステムキャッシュをアクティブにすることです(Linuxファイルシステムは完全に異なり、gitはそれらに最適化されているため、おそらくWindowsでのみ役立ちます)。
git config core.fscache true
git config core.ignoreStat true
しかし、変更されたファイルは、git add
を使用して開発者自身が後で追加する必要があります。 Gitは変更自体を見つけません。