2017-08-02 8 views
0

Ich versuche LibGit2Sharp zu verwenden, um die Funktionalität von git show-brach --independent neu zu erstellen, welche nach dem docs dies tut: Among the <reference>s given, display only the ones that cannot be reached from any other <reference>.LibGit2Sharp Implementierung von showbranch unabhängigen

Mein bester Versuch so weit ist die folgende:

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

Leider wird dies astronomisch langsam, wenn die Menge der Geschichte zunimmt. Es ist tatsächlich viel schneller für mich, git direkt auszuführen, die Ausgabe zu analysieren und LibGit2Sharp die resultierenden SHAs nachzuschlagen, als den obigen Code zu verwenden. Ich nehme an, das hat mit einer Optimierung zu tun, die Git hat, aber LibGit2 nicht. Macht das überhaupt was ich will? Wenn ja, gibt es einen besseren Weg, dies in LibGit2Sharp zu erreichen?

Antwort

1

Ich habe endlich einen besseren Weg gefunden, der Merge-Basen nutzt, dank this question, die mich in die richtige Richtung weisen.

Hier ist der neue Code:

/// <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; 
    } 
Verwandte Themen