Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Git fetch changes from an UNC path?

Tags:

git

windows

I have a Git repository in a shared folder on a Windows PC which I am accessing with an UNC path, e.g.

git clone //server/share/MyRepo.git

When I fetch changes from this repository over a VPN from home it takes a very long time for git-upload-pack.exe to run. I realise that there is no server (as such) involved and my local PC is running all of the executables.

The name of git-upload-pack.exe suggests to me that my local PC is reading files from the remote file share in order to upload them somewhere, but that would be to itself, which makes no sense. This in turn leads me to think that the fetch is nowhere near as performant as it could be. It's like the local machine is doing all the work to cut down the data to transfer, but to do that it has to transfer all the data.

Can anyone shed some light on how this works? Is performance as good as possible without running a true Git server via SSH or whatever at the remote end, or are files being transferred back and forth unnecessarily?

like image 733
GraemeF Avatar asked Nov 05 '22 22:11

GraemeF


1 Answers

With git 2.1 (August 2014), this fetch should be much quicker: an old 2012 fix is finally being integrated into git.

See commit 76e7c8a by (theoleblond)

compat/poll: sleep 1 millisecond to avoid busy wait

SwitchToThread() only gives away the rest of the current time slice to another thread in the current process. So if the thread that feeds the file decscriptor we're polling is not in the current process, we get busy-waiting.

I played around with this quite a bit. After trying some more complex schemes, I found that what worked best is to just sleep 1 millisecond between iterations. Though it's a very short time, it still completely eliminates the busy wait condition, without hurting perf.

There code uses SleepEx(1, TRUE) to sleep.
See this page for a good discussion of why that is better than calling SwitchToThread, which is what was used previously:

Note that calling SleepEx(0, TRUE) does not solve the busy wait.

The most striking case was when testing on a UNC share with a large repo, on a single CPU machine.
Without the fix, it took 4 minutes 15 seconds, and with the fix it took just 1:08
! I think it's because git-upload-pack's busy wait was eating the CPU away from the git process that's doing the real work.
With multi-proc, the timing is not much different, but tons of CPU time is still wasted, which can be a killer on a server that needs to do bunch of other things.

like image 136
VonC Avatar answered Nov 09 '22 08:11

VonC