【问题标题】:Programmatically do "Git blame -w" in C#在 C# 中以编程方式执行“Git blame -w”
【发布时间】:2016-07-18 12:51:25
【问题描述】:

我需要使用 C# 以编程方式获取 Git 历史记录中特定行的最后一位作者。 我尝试使用libgit2sharp

var repo = new LibGit2Sharp.Repository(gitRepositoryPath);
string relativePath = MakeRelativeSimple(filename);
var blameHunks = repo.Blame(relativePath);
// next : find the hunk which overlap the desired line number

但这相当于命令

git blame <file>

事实上我需要

git blame -w <file>(比较时忽略空格)

Libgit2sharp 不要设置-w 开关,也不要提供任何参数/选项来设置它。 我有什么选择?你知道任何其他兼容blame 命令的-w 开关的库吗?

【问题讨论】:

  • 只是为了澄清你已经尝试过NGit?
  • @Jeremy:一点也不,我不知道NGit。我在这个问题上花了很多时间,所以我更愿意征求反馈意见。
  • 酷,这对 LibGit2Sharp 开发团队来说是一个非常好的功能请求 :) 如果您礼貌地要求他们引用此 Q 的链接,您可能会鼓励核心团队或贡献者之一添加它虽然这个 Q 有一个活跃的赏金附加......否则 Evk 应该得到它(+1)。手指交叉这足以说服,因为那样你就不需要依赖 2 个库。
  • @Jeremy :功能请求已经是 here(自 2015 年 8 月起)。
  • lib2gitSharp 的问题在于它使用 lib2git,它是“Git 核心方法的可移植、纯 C 实现,作为具有可靠 API 的可重入可链接库提供,允许您编写支持 C 绑定的任何语言的本机速度自定义 Git 应用程序。”它没有空格选项。它不执行git,所以你可以加-w,它实现了一切。我试图自己实现它,但 C 代码让我头晕目眩。可能您将不得不使用 NGIT。

标签: c# git libgit2 libgit2sharp git-blame


【解决方案1】:

当我遇到 git lib 没有切割它的类似高级场景时,我只是使用 start 进程将其输出到真正的 git 命令行。它不性感,但非常有效。

【讨论】:

  • 我之前也想过,但我需要为我的解决方案中的大约 2000 个文件执行此操作,并且担心性能。我会尝试作为最后的手段。
  • 事实上,在我的情况下,这种方式确实比使用 libGit2Sharp 更快。使用包含 818 个文件(4570 次提交)的测试存储库,每个文件都有责任:使用直接进程:平均 181 毫秒。每责备;使用 ligGit2Sharp :每个责备平均 1235 毫秒。
  • necro 发帖,因为这仍然是该问题的第一名。现在是 2019 年,根据github.com/libgit2/libgit2/issues/3027,libgit2 中的责任实现仍然比命令行 git 慢一个数量级
【解决方案2】:

也许使用 NGIT 库会有所帮助。那是java JGIT库的直接(自动)端口。通过nuget包安装,然后:

    static void Main() {
        var git = Git.Init().SetDirectory("C:\\MyGitRepo").Call();            
        string relativePath = "MyFolder/MyFile.cs";            
        var blameHunks = git.Blame().SetFilePath(relativePath).SetTextComparator(RawTextComparator.WS_IGNORE_ALL).Call();
        blameHunks.ComputeAll();
        var firstLineCommit = blameHunks.GetSourceCommit(0);
        // next : find the hunk which overlap the desired line number
        Console.ReadKey();
    }

注意 SetTextComparator(RawTextComparator.WS_IGNORE_ALL) 部分。

【讨论】:

  • 谢谢你的回答,我下周试试。
  • 没有办法让它工作。有些提交很好,有些则为空。特别是当存在空白差异时。我不知道我是否有错误或缺失的选项,或者是否只是由于 ngit 的过时来源(与 jgit 相比)。我放弃了,我要回归基础(robrich 解决方案)。
  • 尽管如此,我还是给你赏金,因为答案在理论上是正确的,并且给出了适当的代码示例。谢谢。
【解决方案3】:

不幸的是,libgit2sharp 在提取责任方面太慢了,并且在实际场景中使用此功能是不切实际的。因此,我认为最好的方法是使用 Powershell 脚本来使用底层的超高速原生 git。然后将结果重定向到您的应用程序。

git blame -l -e -c {commit-sha} -- "{file-path}" | where { $_ -match '(?<sha>\w{40})\s+\(<(?<email>[\w\.\-]+@[\w\-]+\.\w{2,3})>\s+(?<datetime>\d\d\d\d-\d\d-\d\d\s\d\d\:\d\d:\d\d\s-\d\d\d\d)\s+(?<lineNumber>\d+)\)\w*' } | 
foreach { new-object PSObject –prop @{  Email = $matches['email'];lineNumber = $matches['lineNumber'];dateTime = $matches['dateTime'];Sha = $matches['sha']}}

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 2018-12-04
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多