签出 libgit2sharp 中的子模块

checkout submodule in libgit2sharp

我们发现 git submodule update --recursive -f 更新需要相当长的时间(因为 运行 来自 windows 7 中的 .bat 文件)并且希望使用编译的 exe(可能是 c# .NET 通过 libgit2sharp)来独立检查每个子模块(有 4 个)。 当我们在 cd'ing 到每个子模块后使用四个连续的 git checkout -f [hash] 命令与 运行ning submodule update 相比,批处理文件速度有明显的差异,我们希望获得速度增益。

有人知道如何使用 libgit2sharp 检查子模块的特定提交吗?由于 repo.Submodule["name"] 的 HEAD 属性 不可设置,我尝试对此进行创意(将子模块视为它们自己的回购协议),但 libgit2sharp 似乎认为它们 aren 't 他们自己的回购...可惜:

        for (int cntr = (int)argumentIndeces.LiquidsId; cntr < (int)argumentIndeces.MethodConfigId; cntr++)
        {
            Logger.Debug("About to checkout '" + argNames[cntr].Replace('/', '\') + "' at commit: '" + arguments[argNames[cntr]] + "'");
            Repository sub = new Repository(superProjectPath + "\" + argNames[cntr].Replace('/', '\') );
            Commands.Checkout(sub, arguments[argNames[cntr]]);
            Logger.Debug("Checked out '" + argNames[cntr].Replace('/', '\') + "' at commit: '" + arguments[argNames[cntr]] + "'");
            Console.WriteLine("checked out: " + sub.Tags);
        }

事实证明,大部分问题是子模块一开始就没有正确初始化(比如在硬盘上)。他们处于某种奇怪的半设置状态。 (superproject 有关于他们的数据,但他们缺少自己的 .git 文件等)。

一旦我解决了这个问题,并构建了一个子模块名称数组,这就奏效了:

        for (int cntr = 0; cntr < argNames.Length; cntr++)
        {
            Commands.Checkout(
                new Repository(
                    superProjectPath + "\" + argNames[cntr].Replace('/', '\')
                    ), 
                arguments[argNames[cntr]], options
                );
        }

就其价值而言,Commands.Checkout 调用非常值得包含在 try-catch 中。特别是如果像我一样,commit/branch 规范是 Main 的参数。调用者很容易弄错哈希甚至分支名称。

现在的问题是我是否可以让超级项目的签出不进行子模块更新,因为这是一种浪费(因为我之后会立即签出每个子模块的特定提交)

这借鉴了 olmobrutall 在 Github (#482) 上的 post 的一些想法,但不需要调用已弃用的函数。这只是执行 git reset --hard 而不是获取,因为这更容易实现。

            using (Repository repo = new Repository(repositoryPath))
            {
                foreach (Submodule submodule in repo.Submodules)
                {
                    String subrepoPath = Path.Combine(repo.Info.WorkingDirectory, submodule.Path);

                    using (Repository subRepo = new Repository(subrepoPath))
                    {
                        Branch remoteBranch = subRepo.Branches["origin/master"];
                        subRepo.Reset(ResetMode.Hard, remoteBranch.Tip);
                    }
                }
            }

编辑:我刚刚意识到我错过了问题的一部分,该问题要求签出特定的提交。为此,我们可以检出特定的散列,而不是检出分支:

string commitHash = "517d9bdc49abf6fff00f4d5330245592e2e138b6";
Commit commit = subRepo.Lookup<Commit>(commitHash);
subRepo.Reset(ResetMode.Hard, commit);