libgit2sharp中的checkout子模块

时间:2017-09-21 22:18:50

标签: c# git-submodules libgit2sharp

我们发现git submodule update --recursive -f更新需要相当长的时间(从Windows 7中的.bat文件运行)并且希望使用已编译的exe(可能是通过libgit2sharp的c#.NET)来检查每个子模块独立(有4个)。 在我们使用四个顺序git checkout -f [hash]命令进入每个子模块与运行submodule update之后,批处理文件速度有明显的差异,我们希望速度增加。

任何人都知道如何使用libgit2sharp检出子模块的特定提交?由于repo.Submodule["name"]的HEAD属性不可设置,我试图用这个来创造它(将子模块视为自己的存储库),但libgit2sharp似乎认为它们不是他们自己的回购......真可惜:

        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);
        }

2 个答案:

答案 0 :(得分:3)

这借用了olmobrutall在Github上发布的一些想法(#482),但是不再需要调用已弃用的函数。这只是一个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);

答案 1 :(得分:1)

事实证明,大多数问题是子模块首先不是正确的(就像在HDD上一样)。他们处于一种奇怪的半安装状态。 (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中。特别是如果像我一样,提交/分支规范是Main的参数。调用者可以很容易地得到哈希值甚至分支名称。

现在的问题是,如果我可以让超级项目的结账不进行子模块更新,因为它是浪费(因为我之后立即检查每个子模块的特定提交)< / p>