简体   繁体   English

Git 如何从 UNC 路径获取更改?

[英]How does Git fetch changes from an UNC path?

I have a Git repository in a shared folder on a Windows PC which I am accessing with an UNC path, eg我在 Windows PC 上的共享文件夹中有一个 Git 存储库,我正在使用 UNC 路径访问它,例如

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.当我从家里通过 VPN 从这个存储库中获取更改时, git-upload-pack.exe需要长时间才能运行。 I realise that there is no server (as such) involved and my local PC is running all of the executables.我意识到没有涉及服务器(因此),我的本地 PC 正在运行所有可执行文件。

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. git-upload-pack.exe的名称向我表明,我的本地 PC 正在从远程文件共享中读取文件,以便将它们上传到某个地方,但那将是它自己,这没有任何意义。 This in turn leads me to think that the fetch is nowhere near as performant as it could be.这反过来又让我认为fetch的性能远未达到应有的水平。 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?如果不通过 SSH 或远程端的任何方式运行真正的 Git 服务器,性能是否尽可能好,或者文件是否不必要地来回传输?

With git 2.1 (August 2014), this fetch should be much quicker: an old 2012 fix is finally being integrated into git.使用 git 2.1(2014 年 8 月),这个获取应该更快:一个旧的 2012 修复最终被集成到 git 中。

Seecommit 76e7c8a by ( theoleblond )请参阅( theoleblond )提交的 76e7c8a

compat/poll : sleep 1 millisecond to avoid busy wait compat/poll : 休眠 1 毫秒以避免忙等待

SwitchToThread() only gives away the rest of the current time slice to another thread in the current process. SwitchToThread()只是将当前时间片的 rest 交给当前进程中的另一个线程。 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.在尝试了一些更复杂的方案后,我发现最好的方法是在迭代之间只休眠 1 毫秒。 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.那里的代码使用SleepEx(1, TRUE)来睡眠。
See this page for a good discussion of why that is better than calling SwitchToThread , which is what was used previously:请参阅此页面,了解为什么这比调用SwitchToThread更好,这是以前使用的方法:

Note that calling SleepEx(0, TRUE) does not solve the busy wait.请注意,调用SleepEx(0, TRUE)不能解决忙等待。

The most striking case was when testing on a UNC share with a large repo, on a single CPU machine.最引人注目的案例是在单个 CPU 机器上测试具有大型 repo 的 UNC 共享。
Without the fix, it took 4 minutes 15 seconds, and with the fix it took just 1:08 !如果没有修复,它需要 4 分 15 秒,而修复它只需要 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.我认为这是因为git-upload-pack的忙碌等待正在将 CPU 从 git 进程中吃掉,而该进程正在做真正的工作。
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.使用 multi-proc,时间并没有太大的不同,但是仍然浪费了大量的 CPU 时间,这对于需要做很多其他事情的服务器来说可能是一个杀手。

It thinks that it is like local filesystem.它认为它就像本地文件系统。

There are alternatives to git over SSH: git 有替代 SSH 的替代品:

  1. HTTP[S] (git-http-backend) HTTP[S] (git-http-backend)
  2. Plain git-daemon.普通的 git 守护进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM