使用 libgit2sharp 获取提交与其父级之间的更改

问题描述 投票:0回答:2

我正在使用 libgit2sharp(libgit2 的 C# 包装器),并且遇到了问题,因为它没有很多我希望的功能(希望我能尽快为它做出贡献;这似乎是一个非常有用的项目)

我现在想做的事情是获取从特定提交及其父级更改的文件列表。我不会试图弄清楚合并与其两个父级之间发生了什么变化。我对定期提交更感兴趣。

这些人(https://github.com/libgit2/libgit2sharp/issues/89)正在研究类似的东西。我认为他们的程序是一个不错的主意,但我对 GIT 内部结构的理解有点薄弱(GIT 最终用户指南上有很多指南,但内部结构方面的指南不多)

我很好奇 GIT 本身是如何执行“git diff”命令的。据说 GIT 实际上并不存储增量,而是文件的完整版本(如果未更改,它将仅指向现有的 SHA。可以从各种来源找到此信息,例如此处http://xentac.net/2012/ 01/19/git-and-mercurial.html 之间的真实差异)。这似乎使得获取两个提交之间的更改变得更加困难(在我的例子中是一个特定的提交及其单亲),因为数据没有存储为提交的一部分(如果您检查 libgit2sharp 的 Commit.cs 中的 Commit 类,这一点就很清楚了文件)。

我可以从提交中访问的是树。执行以下操作来查找此信息是否有意义:

1) 从所需的提交开始,沿着树向下走,并将所有 SHA 值存储在一个集合中。

2) 从所需提交的父级开始,沿着其树向下走,将其所有 blob SHA 值存储在另一个集合中。

3) 已更改文件的 SHA 将是不在两个集合的交集中的文件。

我看到这种方法的问题是,看起来没有办法从 blob 的 SHA 值中获取文件名(我在 libgit2sharp 的 Blob.cs 文件中没有看到任何可以做到这一点的东西)。

我知道这个问题有很多方面,但它们是从 git 获取特定数据这一大目标的一部分。

谢谢。

git libgit2 libgit2sharp
2个回答
9
投票

您所追求的,tree diffing功能,已经存在于libgit2中,如tree.h header中所定义。

git_tree_diff()
函数比较两个
Trees
并为每个差异(添加、更新和删除)调用回调。回调函数将传递一个
git_tree_diff_data
结构,其中包含所考虑的 blob 的文件路径、其状态、以前和当前的文件模式以及以前和当前的 SHA。

从 LibGit2Sharp 的角度来看,利用现有的 libgit2 功能比用 C# 重新实现它们更有意义。然而,即使您可以从现有的互操作定义中获得一些灵感,当尝试驯服.Net/本机互操作层时,事情往往会很快变得棘手。

从您的角度来看(为 LibGit2Sharp 做出贡献可能不是您的主要目标;)),另一个选择是将 C 代码移植到 C#,依靠 LibGit2Sharp 现有功能来实现。

git_tree_diff()
(及其卫星函数)是一段非常干净的代码,尽管它完成了相当复杂的工作,但注释非常清晰且有帮助。

参考资料:

  • git_tree_diff()
    函数在src/tree.c
  • 中实现
  • 可以使用此功能进行测试此处

注意: 为了绑定

git_tree_diff()
,应该在 libgit2 tracker 中打开一个问题,请求更新方法定义以便被
GIT_EXTERN
'd。否则无法从 .Net 访问它。

更新

LibGit2Sharp 的

版本 v0.9.0 最终带来了 Tree to Tree diffing 功能。


TreeChanges changes = repo.Diff.Compare(fromTree, newTree);

公开的属性是:

  • 添加/修改行
  • 每种更改的 TreeEntry 更改集合(例如添加、修改……)
  • 差异补丁

您可以通过查看 DiffTreeToTreeFixture.cs

 中的  单元测试来了解有关此功能以及如何利用 TreeChanges 的更多信息。


0
投票

在最新的更新中,这样做的方法是:

TreeChanges changes = repo.Diff.Compare<TreeChanges>(tree1, tree2);
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.