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

git 2.36.0 very slow on normal commands, when sparse-checkout #3840

Open
rpier1 opened this issue May 4, 2022 · 4 comments
Open

git 2.36.0 very slow on normal commands, when sparse-checkout #3840

rpier1 opened this issue May 4, 2022 · 4 comments

Comments

@rpier1
Copy link

rpier1 commented May 4, 2022

In our company we have a huge repo using a sparse-checkout, and sparse-checkout seems to be the cause of major slowdowns in git behaviour (e.g. git diff), since having switched to git 2.36.0. It's so bad that we're using the 2.35.3 instead.

I've tried to make this reproducible with public repos such as linux etc. but it's all quite a hassle and I'm not quite sure I can make it reproducible; and waiting for the huge linux clone is just a pain and poking around the .git/info/sparse-checkout on speculation also just sucks.

Unfortunately, I don't know what exact form .git/info/sparse-checkout needs, so that things start getting crazy slow...

Here's my attempt to get it reproducible. Try it on various large repo, perhaps one of them will have the slow behaviour...

git reset --hard
git clean -fdx

git sparse-checkout disable

echo hello >> "$(find . -maxdepth 1 -type f | head -1)" # modify some file in the toplevel

time git diff # 2> /dev/null
time git diff # 2> /dev/null                             # should be fast

#===========================

DEEPEST_FILE="$(find . -type f -printf '%03d %P\n' | sort -r -n -k 1 | head -1 | awk '{print $2}')"
#DEEPEST_DIR="$(find . -type d -printf '%03d %P\n' | sort -r -n -k 1 | head -1 | awk '{print $2}')"

DEPTH2_FILE="$(find "$(find . -maxdepth 1 -type d | head -1)" -maxdepth 2 -mindepth 2 -type f -printf '%P\n' | grep -v '^.git' | head -1)"

#git sparse-checkout set '/*' '!/*/' "/${DEEPEST_DIR}/*"

git sparse-checkout set
cat <<EOF > .git/info/sparse-checkout
/*
!/*/
/${DEPTH2_FILE}
/${DEEPEST_FILE}
EOF

git sparse-checkout reapply


time git diff # 2> /dev/null
time git diff # 2> /dev/null                     # if bad case: should be slow (?)
@rpier1
Copy link
Author

rpier1 commented May 4, 2022

Oh and another thing.. i don't know if this is relevant, but the old script we use to conjure up the sparse-checkout uses this:

git config core.sparsecheckout true
git checkout

That is to say: it does not use git sparse-checkout init nor git sparse-checkout set etc.

I haven't yet checked, but perhaps that (in conjunction with git 2.36.0) the cause of the slowness... ??
speculation....

Edit: I've checked it. It's got nothing to do with the old sparse-checkout commands.
I get the same behaviour with git sparse-checkout set and git sparse-checkout reapply

@dscho
Copy link
Member

dscho commented May 4, 2022

You could bisect through the latest snapshots to pinpoint this further.

@dscho
Copy link
Member

dscho commented May 4, 2022

You could bisect through the latest snapshots to pinpoint this further.

@rpier1 ah, I see that you responded in the other ticket. Continuing the discussion in this ticket.

My guess is that the regression was introduced with v2.36.0-rc0, in which case we will have to dig in deeper and bisect from there. But let's verify that hypothesis before getting into that rabbit hole.

Yes indeed, that's true! I tried git diff with our huge sparse repo and it takes ages with PortableGit-2.36.0-rc0-64-bit.7z.exe ; but is quick with the previous version (PortableGit-prerelease-2.35.1.windows.2-7-g158a30d60b-20220224121117-64-bit.7z.exe)

I fear that the next stop, then, is to bisect through the commits introduced between 158a30d and v2.36.0-rc0. This is a bit tricky because you will need to first generate the diff between v2.36.0-rc0 and v2.36.0-rc0.windows.1, and then re-apply this diff (or commit on a throw-away branch, then cherry-pick -n) for every bisect step.

To get you started

  1. install Git for Windows' SDK,
  2. sdk cd git,
  3. git switch -c throw-away v2.36.0-rc0 && git diff ..v2.36.0-rc0.windows.1 | git apply --index && git commit -m throw-away
  4. build Git via make -j$(nproc)
  5. test in-place via ./git --exec-path="$PWD" -C <directory> <command> and verify that it is slow
  6. THROWAWAY=$(git rev-parse HEAD)
  7. git switch -d 158a30d60b && make -j$(nproc)
  8. test in-place and verify that it is fast again
  9. git bisect start v2.36.0-rc0 158a30d60b
  10. every time git bisect stops to let you test the current revision, git cherry-pick -n $THROWAWAY && make -j$(nproc) and test. If it is slow, continue with git bisect bad, otherwise with git bisect good

ItzLevvie added a commit to ItzLevvie/winget-pkgs-validate-and-install that referenced this issue May 5, 2022
…windows/git#3840)

This means we're no longer stuck on Git version 2.35.3 and because of this change Git version 2.36.0.windows.1.8.gdc88e3cd72.20220428163258 is now compatible with this script.
@rhuijben
Copy link

rhuijben commented May 12, 2022

Which variant of sparse checkout did you use? Legacy or cone?
These have slightly different configs, but quite different performance behavior.

Cone should be able to use a more efficient index format, which may help here... Or -while development of the feature is in progress- may slow things down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants