使用libgit2sharp在提交及其父级之间进行更改

时间:2012-02-03 18:32:06

标签: git libgit2 libgit2sharp

我正在使用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类,那就很清楚了#39; s Commit.cs文件)。

我可以通过提交访问的是树。是否有必要执行以下操作来查找此信息:

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

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

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

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

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

感谢。

1 个答案:

答案 0 :(得分:8)

libgit2 中定义的 tree.h header 中已经存在树差异功能>

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

从LibGit2Sharp的角度来看,利用现有的libgit2功能更有意义,而不是在C#中重新实现它们。但是,即使您可以从现有的 Interop definitions 中获得灵感,在尝试驯服.Net /本地互操作层时,事情也会变得非常棘手。

从您的角度来看(作为对LibGit2Sharp的贡献可能不是您的主要目标;)),另一种选择是将C代码移植到C#,依赖于现有的LibGit2Sharp沿着树木走下去的功能。 git_tree_diff()(及其卫星函数)是一段非常简洁的代码,虽然它的工作非常复杂,但评论非常明确且有用。

<强>参考文献:

  • git_tree_diff()功能在 src/tree.c
  • 中实施
  • here
  • 可以使用此功能进行测试

注意:要绑定git_tree_diff(),应在 libgit2 tracker 中打开一个问题,请求按顺序更新方法定义是GIT_EXTERN'd。否则无法从.Net访问。

更新

发布LibGit2Sharp的 v0.9.0 最终带来了树到树的差异化功能。

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

外露属性是:

  • 添加/修改行
  • TreeEntry的集合每种更改都会发生变化(例如,添加,修改,......)
  • 差异补丁

您可以通过查看 unit tests in DiffTreeToTreeFixture.cs 找到有关此功能的更多信息以及如何利用TreeChanges