【问题标题】:LibGit2Sharp implementation of showbranch independentshowbranch 独立的 LibGit2Sharp 实现
【发布时间】:2017-08-02 19:09:29
【问题描述】:

我正在尝试使用 LibGit2Sharp 重新创建 git show-brach --independent 的功能,根据 docs 这样做:Among the <reference>s given, display only the ones that cannot be reached from any other <reference>.

到目前为止,我的最佳尝试如下:

    List<Commit> GetIndependent(IRepository repo, IEnumerable<Commit> commits)
    {
        var indep = new List<Commit>();

        foreach (var commit in commits)
        {
            if (repo.Commits.QueryBy(new CommitFilter
            {
                FirstParentOnly = false,
                IncludeReachableFrom = commit,
                ExcludeReachableFrom = commits.Where(x => x.Equals(commit) == false)
            }).Any())
            {
                indep.Add(commit);
            }
        }

        return indep;
    }

不幸的是,随着历史数量的增加,这变得非常缓慢。实际上,我直接执行 git、解析输出并让 LibGit2Sharp 查找生成的 SHA 比使用上面的代码要快得多。我认为这与 Git 的一些优化有关,但 LibGit2 没有。这甚至在做我想要的吗?如果是这样,在 LibGit2Sharp 中是否有更好的方法来实现这一点?

【问题讨论】:

    标签: c# git libgit2 libgit2sharp


    【解决方案1】:

    感谢this question 为我指明了正确的方向,我终于找到了一种利用合并基础的更好方法。

    这是新代码:

        /// <summary>
        /// Implementation of `git show-branch --indepenent`
        /// 
        /// "Among the <reference>s given, display only the ones that cannot be reached from any other <reference>"
        /// </summary>
        /// <param name="commitsToCheck"></param>
        /// <returns></returns>
        private List<Commit> GetIndependent(IRepository repo, IEnumerable<Commit> commitsToCheck)
        {
            var commitList = commitsToCheck.ToList();
    
            for (var i = commitList.Count - 1; i > 0; --i)
            {
                var first = commitList[i];
                for (var j = commitList.Count - 1; j >= 0; --j)
                {
                    if (i == j) continue;
    
                    var second = commitList[j];
    
                    var mergeBase = repo.ObjectDatabase.FindMergeBase(first, second);
    
                    if (first.Equals(mergeBase))
                    {
                        // First commit (i) is reachable from second (j), so drop i
                        commitList.RemoveAt(i);
    
                        // No reason to check anything else against this commit
                        j = -1;
                    } else if (second.Equals(mergeBase))
                    {
                        // Second (j) is reachable from first, so drop j
                        commitList.RemoveAt(j);
    
                        // If this was at a lower index than i, dec i since we shifted one down
                        if (j < i)
                        {
                            --i;
                        }
                    }
                }
            }
    
            return commitList;
        }
    

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 2013-11-02
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2018-10-21
      • 1970-01-01
      相关资源
      最近更新 更多