使用libgit2sharp获取提交与父代之间的更改 [英] Get changes between a commit and its parent with libgit2sharp

查看:177
本文介绍了使用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-之间-git的和 - mercurial.html )。这似乎使得更难于在两个提交(在我的情况下是一个特定的提交和它的单个父)之间进行更改,因为数据不是作为提交的一部分存储的(如果您检查libgit2sharp的Commit.cs中的Commit类文件)。



我可以从提交中获得的是树。是否有意义的做到以下几点以找到这些信息:

<1>从所需的提交开始,沿树遍历并将所有SHA值存储在一个集合中。



2)从父对象开始执行所需的提交,并沿着它的树遍历其所有的BLOB SHA值。



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



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



我知道这个问题有很多方面,但它们是这个大目标的一部分, git。



谢谢。

解决方案

树差异功能已存在于 libgit2 ,如 tree.h中所定义头文件


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



从LibGit2Sharp的角度来看,利用现有的libgit2功能而不是在C#中重新实现它们会更有意义。但是,即使您可以从现有的 Interop定义 ,当尝试驯服.Net / native互操作层时,事情往往会变得非常棘手。 从您的角度来看(对LibGit2Sharp的贡献可能不是您的主要目标;)另一种选择是将C代码移植到C#,依靠LibGit2Sharp现有功能沿着树行走。 git_tree_diff()(及其卫星函数)是一个非常干净的代码片段,虽然它的工作非常复杂,但评论非常清晰且有帮助。



参考资料: $ b



注意:为了绑定 git_tree_diff(),应该在 libgit2 tracker ,请求更新方法定义以使其成为 GIT_EXTERN d。
$ b $ h1> UPDATE

发布 v0.9.0 的LibGit2Sharp最终带来了Tree to Tree差异功能。


$ b
TreeChanges changes = repo.Diff.Compare(fromTree, NEWTREE);



暴露的属性包括:

$ ul

  • 添加/修改行

  • 每种类型的更改(例如添加,修改,...)的TreeEntry更改集合



  • 您可以找到更多关于此功能以及如何利用 TreeChanges 查看DiffTreeToTreeFixture中的 单元测试。 cs


    I am working with libgit2sharp (a C# wrapper for libgit2) and have been running into issues because it doesnt have a lot of the functionality I am hoping for (hopefully I can contribute to it soon; this seems like a really useful project)

    The thing I am trying to do right now is get a list of the files changed from a particular commit and its parent. I will not try to figure out what has changed between a merge and its two parents. I am more interested in regular commits.

    These guys (https://github.com/libgit2/libgit2sharp/issues/89) are working on something similar. I think their procedure is a sound idea but I am a little weak on my understanding of GIT internals (there are loads of guides on an end user's guide to GIT but not so much on internal structure)

    I am curious how GIT itself does a "git diff" command. Supposedly GIT doesnt actually store deltas but rather a full version of the file (if it is unchanged it will just point to an existing SHA. This information can be found from various sources such as here http://xentac.net/2012/01/19/the-real-difference-between-git-and-mercurial.html). This seems to make it harder to get the changes between two commits (in my case a particular commit and its single parent) because the data isnt stored as part of the commit (which is clear if you examine the Commit class in libgit2sharp's Commit.cs file).

    What I can get access to from a commit is the tree. Would it make sense to do the following to find this information:

    1) Start at the desired commit and walk down the tree and store all the SHA values in a set.

    2) Start at the parent for the desired commit and walk down its tree to store all its blob SHA values in another set.

    3) The SHA's for the files changed will be the files that are not in the intersection of the two sets.

    The problem I see with this approach is that it doesnt look like there is a way to get the filename from the blob's SHA value (I dont see anything that can do this in libgit2sharp's Blob.cs file).

    I know there are a lot of facets to this question but they are part of this large goal to get a particular piece of data from git.

    Thanks.

    解决方案

    What you're after, a tree diffing feature, already exists in libgit2 as defined in tree.h header.

    The git_tree_diff() function compares two Trees and invokes a callback for every difference (addition, updation and deletion). The callback function is being passed a git_tree_diff_data structure with the filepath of the considered blob, its status, the former and current filemodes and the former and current SHAs.

    From LibGit2Sharp perspective, it would make more sense to leverage existing libgit2 feature rather than re-implementing them in C#. However, even if you can get some inspiration from existing Interop definitions, things tend to become quickly tricky when trying to tame .Net/native interop layer.

    From your perspective (as contributing to LibGit2Sharp may not your primary goal ;)), another option would be to port the C code to C#, relying on LibGit2Sharp existing features to walk down the trees. git_tree_diff() (and its satellite functions) is a very clean piece of code, and although it does quite a complex job, the comments are very clear and helpful.

    References:

    • The git_tree_diff() function is implemented in src/tree.c
    • Tests exercising this feature are available here

    Note: In order to bind git_tree_diff(), an issue should be opened in libgit2 tracker requesting that the method definition should be updated in order to be GIT_EXTERN'd. Otherwise it won't be accessible from .Net.

    UPDATE

    Release v0.9.0 of LibGit2Sharp eventually brought the Tree to Tree diffing feature.

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

    Exposed properties are:

    • Added/Modified lines
    • Collections of TreeEntry changes per kind of change (eg. Added, Modified, ...)
    • The diff Patch

    You can find more about this feature and how to leverage the TreeChanges by taking a look at the unit tests in DiffTreeToTreeFixture.cs.

    这篇关于使用libgit2sharp获取提交与父代之间的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆