showbranch 独立的 LibGit2Sharp 实现
LibGit2Sharp implementation of showbranch independent
我正在尝试使用 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 中实现此目的?
感谢 为我指明了正确的方向,我终于找到了一种利用合并基础的更好方法。
这是新代码:
/// <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;
}
我正在尝试使用 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 中实现此目的?
感谢
这是新代码:
/// <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;
}