8

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

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

这些人(https://github.com/libgit2/libgit2sharp/issues/89)正在做类似的事情。我认为他们的程序是一个合理的想法,但我对 GIT 内部的理解有点弱(最终用户的 GIT 指南有很多指南,但内部结构没有那么多)

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

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

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

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

3) 更改文件的 SHA 将是不在两组交集的文件。

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

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

谢谢。

4

1 回答 1

9

你所追求的,一个树差异功能,已经存在于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(),应该在libgit2 跟踪器中打开一个问题,要求更新方法定义以便GIT_EXTERN'd. 否则它将无法从.Net 访问。

更新

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

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

公开的属性是:

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

TreeChanges通过查看DiffTreeToTreeFixture.cs 中的单元测试,您可以找到有关此功能以及如何利用该功能的更多信息。

于 2012-02-03T21:23:09.420 回答