如何使用libgit2sharp查找一个git提交所在的分支?

8
为了一个研究项目,我一直在尝试复制版本控制软件(如SourceTree或TortoiseGit)中存在的图形视图。
我正在尝试实现的图形视图:
最大的问题是找到提交所属的分支。如果我有了这个信息,就可以为提交点分配列和颜色。这很困难,因为在底层,Git不存储提交最初所在的分支。
查看StackOverflow上的其他解决方案,我发现可以获取包含提交的分支列表,但我需要一种方法来隔离单个分支以在我的图形中显示。就像SourceTree或TortoiseGit一样。
我的问题也与此问题相同:Find out the branch a commit belongs to in LibGit2Sharp? 看起来他们在私人讨论室中发现了实际的解决方案。但是,我没有声望来评论并询问他们找到了什么。
有人有任何想法吗?

或者,@nulltoken,如果你偶然看到了这个并记得的话,你知道你们在那个讨论室里发现了什么吗?


聊天室中的讨论并非私密:https://chat.stackoverflow.com/rooms/8237/discussion-between-nulltoken-and-rfactor - Edward Thomson
通常的解决方案是通过附加到提交的git注释记录信息。如果您使用gerrit,则会自动执行此操作,否则您需要编写一个钩子。 - Andrew C
@EdwardThomson 哦..看起来我犯了一个错误的假设..糟糕!你能不能碰巧查看一下聊天内容?我得到了一个“页面未找到”的错误... - Jade White
3个回答

2

不确定这个答案对你有多大帮助。"git branch --contains $SHA1" 的 LibGit2Sharp 等效调用是 GitHub 上一个被请求的功能,是一个开放性问题!(链接)

很久以前,我使用了像这样的所有引用查询,但对于您的用例来说,它可能过于缓慢。

我试图想出可能缓解此问题的方法,但没有任何指导方向。 :( 然后我发现这条评论,它断言您需要遍历 DAG 并验证具有提交的实际分支。所有这些都暗示您需要采用缓慢的遍历所有引用的方法。


我认为OP并不是在询问遍历或模拟“branch --contains”。OP正在询问如何找到所有引用的当前提示以进行装饰。 - Edward Thomson
但是,说实话,我已经读了几遍,我实际上无法确定。 - Edward Thomson
@edward-thomson,没错! :) 在你这样一个声誉很高的人发表评论之后,我读了大约8次这个问题,但我也不知道你是如何得出那个结论的,或者我是如何得出我的结论的!只有这个给了我一个怀疑的余地:“最大的问题是...”和“我需要一种隔离的方法...” - vishwarajanand
我想澄清一下,我已经成功复制了 git branch --contains 的功能。但问题在于,多个分支可以包含相同的提交。这使得很难选择一个分支在我的图表中显示为“拥有该提交”(例如,它是属于 NewBranch2 还是 master)。例如,如果我从“master”创建了分支“A”,在“A”上进行了一些工作,然后将“A”合并到了master中,那么 git branch --contains $(A 中的任何 sha) 将返回 A, master - Jade White
在这种情况下,显然会是顶部结果 - “A”。但是如果我稍后从“A”分支出“B”,git branch --contains $(any sha from A)将返回“B,A,master”。在这种情况下,“B”是顶部结果 - 但提交最初在A上,因此我不能总是将顶部分支显示为拥有我的图表中的提交... - Jade White
1
感谢 @jade-white 的澄清。您可以通过 reflog 评估提交的“确切”所有者分支。我很少使用这个功能,在快速搜索时,我偶然发现了这个帖子,可能会对您有所帮助:https://dev59.com/XHbZa4cB1Zd3GeqPDTzu#18505238。请注意,您可以使用 reflog 搜索有限的历史记录。希望这能有所帮助。 - vishwarajanand

1
生成图表时,SourceTree不需要知道提交所在的分支。图表中第一个提交始终有0列。此外,可以获取给定提交的父提交列表。通过从第一个提交开始向后迭代,只使用这些信息就可以生成一个漂亮的图表。

0

当您希望展示的不仅仅是HEAD的历史记录(通过枚举repository.Commits实现),以下内容可能对您有所帮助:

repository.Commits
    .QueryBy(new CommitFilter 
    {
        IncludeReachableFrom = repository.Refs.ToList(), // or adjust to your needs
        SortBy = CommitSortStrategies.Time
    })
    .Distinct<Commit>(EqualityComparer<GitObject>.Default)
    .ToList();

复制自/灵感来自: https://stackoverflow.com/a/68564141/2240196

在迭代提交时,您可以检查哪些引用(包括分支)指向它们以显示图表中的引用名称。
我建议将引用存储在查找表中,以查找指向每个提交的引用:

ILookup<GitObject, string> refsByCommit = repo.Refs.ToLookup(@ref => @ref.ResolveToDirectReference().Target, @ref => @ref.CanonicalName);
// ( ... )
foreach (var commit in commits)
{
    // ( ... )
    var refNames = refsByCommit[commit];
    // ( ... )
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接