Implementación LibGit2Sharp de showbranch independiente

Intento usar LibGit2Sharp para recrear la funcionalidad de git show-brach --independent que, de acuerdo con los documentos, hace esto: Among the <reference>s given, display only the ones that cannot be reached from any other <reference>.

Mi mejor bash hasta ahora es el siguiente:

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

Desafortunadamente, esto se vuelve astronómicamente lento a medida que aumenta la cantidad de historia. En realidad, es mucho más rápido para mí ejecutar git directamente, analizar el resultado y hacer que LibGit2Sharp busque los SHA resultantes antes que usar el código anterior. Supongo que esto tiene que ver con cierta optimization que tiene Git, pero LibGit2 no. ¿Esto está haciendo lo que yo quiero? Si es así, ¿hay una mejor manera de lograr esto en LibGit2Sharp?

Finalmente encontré una mejor manera de utilizar bases de combinación, gracias a esta pregunta que me señala en la dirección correcta.

Aquí está el nuevo código:

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