我正在使用libgit2sharp(libgit2的C#包装器),并且遇到了问题,因为它没有很多我想要的功能(希望我能很快为它做出贡献;这似乎是一个非常有用的项目)
我现在想做的事情是获取从特定提交及其父级更改的文件的列表。我不会试图弄清楚 merge 及其两个父级之间发生了什么变化。我对常规提交更感兴趣。
这些家伙(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中获取特定数据这一宏伟目标的一部分。
谢谢。
最佳答案
根据 libgit2 tree.h header 中的定义,在 Interop definitions 中已经存在一个差异树功能。git_tree_diff()
函数比较两个Trees
并针对每个差异(添加,更新和删除)调用回调。正在向回调函数传递git_tree_diff_data
结构,其中包含所考虑的Blob的文件路径,其状态,以前和当前的文件模式以及以前和当前的SHA。
从LibGit2Sharp的角度来看,利用现有的libgit2功能比在C#中重新实现它们更有意义。但是,即使您可以从现有的 src/tree.c 中获得一些启发,但在尝试驯服.Net/ native 互操作层时,事情往往会很快变得棘手。
从您的角度来看(作为对LibGit2Sharp的贡献可能不是您的主要目标;)),的另一种选择是依靠LibGit2Sharp的现有功能将C代码移植到C#。 git_tree_diff()
(及其附属函数)是一段非常干净的代码,尽管它完成了相当复杂的工作,但注释却非常清晰和有用。
引用:
git_tree_diff()
函数在 here 注:为了绑定(bind)
git_tree_diff()
,应在中打开一个问题unit tests in DiffTreeToTreeFixture.cs ,要求更新方法定义以使其成为GIT_EXTERN
。否则它将无法从.Net访问。更新
LibGit2Sharp的 v0.9.0 版本最终带来了Tree to Tree diffing功能。
TreeChanges changes = repo.Diff.Compare(fromTree, newTree);
公开的属性是:
通过查看 ojit_a ,您可以找到有关此功能以及如何利用
TreeChanges
的更多信息。关于git - 使用libgit2sharp获取提交及其父项之间的更改,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9133684/