2017-08-02 57 views
0

我試圖用LibGit2Sharp重建的git show-brach --independent的功能,它根據docs做到這一點:Among the <reference>s given, display only the ones that cannot be reached from any other <reference>.showbranch獨立的LibGit2Sharp實施

我最好的嘗試,到目前爲止是這樣的:

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中有沒有更好的方法來實現這一點?

回答

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