使用 LibGit2Sharp 克隆 Git 存储库时出现超时错误

Posted

技术标签:

【中文标题】使用 LibGit2Sharp 克隆 Git 存储库时出现超时错误【英文标题】:Timeout error cloning Git repository using LibGit2Sharp 【发布时间】:2017-05-11 19:53:57 【问题描述】:

我的组织运行自己的 GitHub 服务器和网络代理。我已经配置了 git,这样我就可以从命令行使用 github.com 和我们内部的 GitHub。但是使用 LibGit2Sharp,我无法对我们的 GitHub 服务器执行操作。从CloneOptions 调用的唯一回调是RepositoryOperationStarting。不会调用其他回调。我在下面发布了相关代码和配置(名称已更改以保持匿名)。我正在使用 NuGet 的 LibGit2Sharp v0.25.2。

使用 LibGit2Sharp 的代码。评论指出在访问我们的内部 github 时会触发哪些回调。访问 github.com 时,所有回调都按预期调用。

private static void Main(string[] args)

    var options = new CloneOptions
    
        CertificateCheck = (certificate, valid, host) => true, // never called
        CredentialsProvider = (url, fromUrl, types) => null, // never called
        OnCheckoutProgress = (path, steps, totalSteps) =>  , // never called
        OnProgress = output => true, // never called
        OnTransferProgress = progress => true, // never called
        OnUpdateTips = (name, id, newId) => true, // never called
        RepositoryOperationCompleted = context =>  , // never called
        RepositoryOperationStarting = context => true // ONLY THIS ONE IS CALLED
    ;

    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; // never called

    Repository.Clone(args[0], args[1], options);

例外:

Unhandled Exception: LibGit2Sharp.LibGit2SharpException: failed to send request: The operation timed out
   at LibGit2Sharp.Core.Ensure.HandleError(Int32 result) in C:\projects\libgit2sharp\LibGit2Sharp\Core\Ensure.cs:line 136
   at LibGit2Sharp.Core.Proxy.git_clone(String url, String workdir, GitCloneOptions& opts) in C:\projects\libgit2sharp\LibGit2Sharp\Core\Proxy.cs:line 354
   at LibGit2Sharp.Repository.Clone(String sourceUrl, String workdirPath, CloneOptions options) in C:\projects\libgit2sharp\LibGit2Sharp\Repository.cs:line 715
   at gitex.Program.Main(String[] args) in D:\dev\mgunter\gitex\gitex\Program.cs:line 71

从命令行克隆有效:

C:\> git clone https://github.my-domain.com/organization/project
Cloning into 'project'...
remote: Counting objects: 1373, done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 1373 (delta 8), reused 0 (delta 0), pack-reused 1350R
Receiving objects: 100% (1373/1373), 383.10 KiB | 0 bytes/s, done.
Resolving deltas: 100% (862/862), done.

这是我的 git 配置的相关部分。我也尝试过使用HTTP_PROXYHTTPS_PROXY 环境变量,但没有运气。

[http "https://github.my-domain.com"]
    proxy = http://proxy-for-internal.my-domain.com:80
[http "https://github.com"]
    proxy = http://proxy-for-external.my-domain.com:81
    sslCAinfo = ~/certificates/my-domain-root-ca.cer
[credential]
    helper = wincred
[hub]
    host = github.my-domain.com
    protocol = https

使用 WireShark,我看到命令行 git 确实命中了我的代理服务器。但是,我使用 LibGit2Sharp 的 .NET 程序根本没有访问代理服务器。

【问题讨论】:

可能通过克隆选项传递用户名和凭据var co = new CloneOptions(); 你按照这个例子:var co = new CloneOptions(); co.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials Username = "Username", Password = "Password" ; Repository.Clone("https://github.com/libgit2/libgit2sharp.git", "path/to/repo", co); 我也没有在你的代码中看到.git 奇怪...我回家后看看这个...我将创建一个示例项目来帮助您解决这个问题 @MichaelGunter 那么这就是你的答案。我用谷歌搜索了 LibGit2Sharp 并找到了这个:github.com/libgit2/libgit2sharp/issues/1429 如果 LibGit2Sharp 没有处理代理,那么您必须自己编写代码。看起来 LibGit2Sharp 只是不完整或有错误。它似乎有读取代理的代码,只是它没有使用它。您只需要一个方法来检查是否定义了代理,如果是,请使用它。可能不是你想要的,但你最好的选择是从 GitHub 中提取 LibGit2Sharp,编译和调试它,然后与项目所有者开始对话。 【参考方案1】:

这里还有其他想法吗?看来 LibGit2Sharp 只是不尊重 .gitconfig 中的代理信息

好像是这样,来自libgit2/libgit2sharp issue 1429,其中Brandon Ording (bording)cmets:

看起来GitProxyOptions 被添加到88cf9a7 中,它们正在Commands.Fetch 中使用,as you can see here。

但是,目前在代码库中的任何地方,GitProxyOptionsGitProxyType 似乎总是被初始化为0,即None。 查看 git_proxy_t 的 libgit2 代码,似乎 None 禁用使用任何代理。

Edward Thomson (ethomson) 确认:

是的,看起来这确实是在禁用代理... Windows 上的默认传输 (WinHTTP) 不支持代理 IIRC,所以这基本上是一个问题。但是,当 libgit2 本身使用 libcurl 支持构建时,打开自动支持会有所帮助。

所以:commit 0d72f67f2 确实提到了:

代理:不要在类型中指定协议

我们将其留给 url 字段中的方案。 该类型应该只告诉我们是否需要代理以及是否要自动检测它。

那是对issue 3110的回应,一个月后涉及commit 1dc4491,带有代理配置示例,但带有libgit2和Java程序。

HTTP(S)_PROXY 应该被选中,但是:对于像您自己的 GitHub 服务器这样的内部服务,请检查您是否真的需要代理。 大多数情况下,您会设置 NO_PROXY=localhost,.mycompany.com 以便在联系内部(LAN 而不是 WAN)服务器时使用任何代理。

【讨论】:

以上是关于使用 LibGit2Sharp 克隆 Git 存储库时出现超时错误的主要内容,如果未能解决你的问题,请参考以下文章