web-dev-qa-db-ja.com

git statusのパフォーマンスを改善する方法

NFS上にあるLinuxマシンに10 GBのリポジトリがあります。最初のgit statusは36分かかり、その後のgit statusは8分かかります。 GitはファイルをキャッシュするためにOSに依存しているようです。リポジトリ全体をパック/リパックするgitcommitなどの最初のstatusコマンドのみが、巨大なリポジトリに非常に長い時間がかかります。このような大きなリポジトリでgit statusを使用したかどうかはわかりませんが、この問題に遭遇した人はいますか?

git gcgit cleangit repackを試しましたが、かかった時間はまだ/ほぼ同じです。

サブモジュールや、リポジトリを小さなものに分割するような他の概念は役立ちますか?その場合、より大きなレポを分割するのに最適です。大きなリポジトリでgitコマンドにかかる時間を改善する他の方法はありますか?

67
Senthil A Kumar

より正確には、gitはlstat(2)システムコールの効率に依存するため、クライアントの “ attribute cache timeout” を調整することで問題を解決できる場合があります。

git-update-indexのマニュアル—本質的にgit-statusのマニュアルモード—これを軽減するためにできることを --assume-unchangedフラグを使用 で説明し、通常の動作を抑制します変更したパスを手動で更新します。ファイルを保存するたびにこのフラグを設定解除するようにエディターをプログラムすることもできます。

別の方法として、チェックアウトのサイズを小さくすることもできます(ここでは、パックファイルのサイズは実際には関係ありません)。オプションは、スパースチェックアウト、サブモジュール、またはGoogleの repo ツールです。

(メーリングリストがあります NFSでのGitの使用に関するスレッド ですが、多くの質問には答えていません。)

40
Josh Lee

NFSで共有されている大規模なプロジェクトでもこの問題が発生しています。

Git commitとgit statusの両方に指定できるフラグ-unoを見つけるのに時間がかかりました。

このフラグは、追跡されていないファイルの検索を無効にします。これにより、nfs操作の数が大幅に削減されます。理由は、gitが追跡されていないファイルを発見するために、すべてのサブディレクトリを調べる必要があるため、多くのサブディレクトリがある場合、これがあなたを傷つけるからです。 gitが追跡されていないファイルを探すのを無効にすることで、これらすべてのNFS操作を排除できます。

これをcore.preloadindexフラグと組み合わせると、NFS上でも適切なパフォーマンスを得ることができます。

32
user1077329

git gc を試してください。また、 git cleanmayヘルプ。

[〜#〜] update [〜#〜]-反対票の出所は不明ですが、gitマニュアルには具体的に次のように記載されています。

現在のリポジトリ内で、ファイルリビジョンの圧縮(ディスクスペースとパフォーマンスの向上を圧縮する)や到達できない可能性のあるオブジェクトの削除など、多数のハウスキーピングタスクを実行しますgit addの以前の呼び出しから作成されています。

ユーザーは、各ディスク内でこのタスクを定期的に実行して、ディスク領域の使用率と動作パフォーマンスを維持することをお勧めします。

Git statusが遅いときにgit gcを実行すると、常に違いに気付きます!

UPDATE II-どうやってこれを見逃したかわかりませんが、OPはすでにgit gcとgit cleanを試しました。元々そこにはなかったと誓いますが、編集に変更は見られません。そのために残念!

27
Jabari

Gitリポジトリがサブモジュールを多用している場合、.gitディレクトリの設定ファイルを編集し、ignore = dirty特に大きな/重いサブモジュールの場合。例えば:

[submodule "mysubmodule"]
url = ssh://mysubmoduleURL
ignore = dirty

忘れている可能性のあるサブモジュールにステージングされていない変更があるというリマインダーの利便性は失われますが、サブモジュールがメインリポジトリと同期していないことを知ることの主な利便性は保持されます。さらに、作業ディレクトリをサブモジュール自体に変更し、通常どおりサブモジュール内でgit statusを使用して詳細情報を表示できます。 「ダーティ」の意味の詳細については、 この質問 を参照してください。

16
beno

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-listALLOC_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が次のように改善されています。

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秒になったことがわかります。 %。

7
VonC

git config --global core.preloadIndex true

私のために仕事をしました。公式ドキュメントを確認してください こちら

2
klimat

20〜30個のサブモジュールの範囲にあるコードベースでは、
git status --ignore-submodules
大幅にスピードアップしました。これはサブモジュールのステータスについてはレポートしませんであることに注意してください。

1
citysurrounded

私はそれがどのような意味を持っているのか分かりませんが、私にとってステータスは30分かかっていたので、ウェブで見つけることができるものすべてを試しました、最後に、git reset stashが別のブランチから作成されたが、このブランチに適用されたstashから適用された100の変更があり、それらはすべてステージングされたがコミットされなかった(説明するだけで、この問題に遭遇する前に私が何をしたか)、git resetは15分かかりましたが、その後、ステータスが1秒未満のようにすべてがすぐに機能し始めました。私は自分の問題を解決した理由を伝えるだけでgitの専門家ではありません。

0
Vivek

まだ言及されていないことは、Windowsマシンでファイルシステムキャッシュをアクティブにすることです(Linuxファイルシステムは完全に異なり、gitはそれらに最適化されているため、おそらくWindowsでのみ役立ちます)。

git config core.fscache true

git config core.ignoreStat true

しかし、変更されたファイルは、git addを使用して開発者自身が後で追加する必要があります。 Gitは変更自体を見つけません。

ソース

0
dCSeven