Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow on Windows with lots of submodules #1701

Closed
Vynce opened this issue Nov 19, 2020 · 2 comments · Fixed by #1704
Closed

Slow on Windows with lots of submodules #1701

Vynce opened this issue Nov 19, 2020 · 2 comments · Fixed by #1704

Comments

@Vynce
Copy link
Contributor

Vynce commented Nov 19, 2020

git status is substantially slower on Windows than on Linux. I'm working in a repo with ~240 submodules. By default, when you run git status in a repo with submodules, it'll recursively run git status in every submodule as well (sequentially). git diff behaves similarly to git status. Pre-commit appears to run git status once at the beginning (to check if anything needs to be stashed?) and then runs git diff before and after each hook (to detect any changes made by the hook?). These calls quickly add up and make pre-commit unusable in these large repos.

The bottlenecks can be seen clearly in this Process Monitor capture:

procmon_pre-commit

Running one hook takes ~35s in this case. Two hooks take ~54s.

If I add --ignore-submodules to this git status call and this git diff call, pre-commit only takes ~1.5s for one hook and ~1.9s for two hooks.

If I understand the use of git status and git diff in pre-commit correctly, it seems like it would be completely safe to ignore submodules in the git status call since submodules can't be stashed to restore later. The git diff case might be more risky because I guess hooks could modify submodules? Perhaps an "ignore submodules" setting could be added to pre-commit?

@asottile
Copy link
Member

I think (?) this is a duplicate of #1564

if there's a way to ignore submodules that would definitely be an improvement, I don't think there's really going to be anything pre-commit can realistically do about those as diffd

@Vynce
Copy link
Contributor Author

Vynce commented Nov 20, 2020

Thanks for taking a look. We are (trying to) use read/write hooks (clang-format being the primary one), so while #1564 could definitely help in some cases, I think this issue is somewhat different (although related to the same issue of basic git commands not scaling well on large repos).

Vynce added a commit to Vynce/pre-commit that referenced this issue Nov 20, 2020
When git status runs in a repo with submodules, it'll recursively run
git status in every submodule as well by default (sequentially).
git status is substantially slower on Windows than on Linux. git diff
behaves similarly to git status in terms of running recursively within
all submodules. In repos with hundreds of submodules, this quickly adds
up when git status/diff are called multiple times. Pre-commit runs
git status once at the beginning of an operation and then runs git diff
before and after each hook. These calls quickly add up and make
pre-commit unusable in large repos with lots of submodules.

This commit drastically improves performance in repos with lots of
submodules and fixes pre-commit#1701 by telling git status and git diff to ignore
submodules. This change is not expected to have any negative effect on
existing hooks because each submodule should manage its own hooks
instead of relying on superproject hooks to manipulate their contents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants