简体   繁体   English

如何检索文件的历史记录?

[英]How to retrieve the history of a file?

I got another libgit2 issue and will be very grateful for your help. 我得到了另一个libgit2问题,非常感谢你的帮助。

I'm trying to retrieve file history, ie list of commits where this file was changed. 我正在尝试检索文件历史记录,即更改此文件的提交列表。 And it seems to be quite unconventional... As far as I can see, there are no function for that. 而且它似乎非常传统......据我所见,没有任何功能。

The only approach I can come up with is to use revision walking API to iterate through revisions, check the tree object attached to commit and search for given file there, if found, add commit to my list, otherwise proceed to next commit. 我能想到的唯一方法是使用版本控制API迭代修订版本,检查附加到提交的树对象并在那里搜索给定文件,如果找到,则将提交添加到我的列表中,否则继续下一次提交。

But it looks none-optimal for me... 但它对我来说似乎不是最理想的......

May be is there any other approach, for example, look directly into .git folder and get needed information there? 可能是有任何其他方法,例如,直接查看.git文件夹并获取所需信息吗?

Many thanks in advance! 提前谢谢了!

But it looks none-optimal for me... 但它对我来说似乎不是最理想的......

Your approach is the correct one. 你的方法是正确的。 Beware that you'll have to fight against: 要小心你必须要反对:

  • Plain renaming (same object Hash, different tree entry name) 普通重命名(相同的对象哈希,不同的树条目名称)
  • Renaming and content updation occuring in the same commit (Different hash, different tree entry name. Would require file content analysis and comparison feature which is not available in libgit2) 在同一个提交中发生重命名和内容更新(不同的哈希,不同的树条目名称。需要文件内容分析和比较功能,这在libgit2中不可用)
  • Multiple parents history (two branches which have been merged and into which the same file has been modified in a different way) 多个父级历史记录(已合并的两个分支,并且以不同方式修改了同一文件)

May be is there any other approach, for example, look directly into .git folder and get needed information there? 可能是有任何其他方法,例如,直接查看.git文件夹并获取所需信息吗?

Even though understanding the .git folder layout is always a well-spent time, I'm afraid this won't help you with this specific file history issue. 虽然理解.git文件夹布局总是花费很多时间,但我担心这不会帮助您解决这个特定的文件历史问题。

Note: this question is very close from this libgit2sharp issue: How to get the last commit that affected a given file? 注意:这个问题与libgit2sharp问题非常接近: 如何获取影响给定文件的最后一次提交?

Update 更新

Pull request #963 adds this very feature. 拉请求#963添加了这个功能。

It's available since LibGit2Sharp.0.22.0-pre20150415174523 pre-release NuGet package. LibGit2Sharp.0.22.0-pre20150415174523预发布NuGet包以来可用。

This is mainly followed in issues/495 of libgit2. 这主要是在libgit2的问题/ 495中。
Even though it is implemented in libgit2sharp ( PR 963 , for milestone 22 ), it is still "up for grabs" in libgit2 itself. 即使它是在libgit2sharpPR 963里程碑22 )中实现的,它仍然在libgit2本身“抢夺”。

The issue is documented in issues/3041: Provide log functionality wrapping the revwalk . 问题/ 3041中记录了该问题:提供包装revwalk日志功能
The approach mentioned in the question was used in this libgit2sharp example and can be adapted to C using libgit2. 问题中提到的方法在这个libgit2sharp示例中使用 ,可以使用libgit2适应C语言。 It remains the current workaround, pending the resolution of 3041. 在3041号决议之前,它仍然是当前的解决方法。

If using C#, this functionality has been added to the LibGit2Sharp 0.22.0 NuGet Package ( Pull Request 963 ). 如果使用C#,则此功能已添加到LibGit2Sharp 0.22.0 NuGet包Pull Request 963 )。 You can do the following: 您可以执行以下操作:

var fileHistory = repository.Commits.QueryBy(filePathRelativeToRepository);
foreach (var version in fileHistory)
{
    // Get further details by inspecting version.Commit
}

In my Diff All Files VS Extension (which is open source so you can view the code), I needed to get a file's previous commit so I can see what changes were made to a file in a given commit. 在我的Diff All Files VS Extension (它是开源的,所以你可以查看代码),我需要获得一个文件的先前提交,所以我可以看到在给定的提交中对文件做了哪些更改。 This is how I retrieved the file's previous commit: 这是我检索文件先前提交的方式:

/// <summary>
/// Gets the previous commit of the file.
/// </summary>
/// <param name="repository">The repository.</param>
/// <param name="filePathRelativeToRepository">The file path relative to repository.</param>
/// <param name="commitSha">The commit sha to start the search for the previous version from. If null, the latest commit of the file will be returned.</param>
/// <returns></returns>
private static Commit GetPreviousCommitOfFile(Repository repository, string filePathRelativeToRepository, string commitSha = null)
{
    bool versionMatchesGivenVersion = false;
    var fileHistory = repository.Commits.QueryBy(filePathRelativeToRepository);
    foreach (var version in fileHistory)
    {
        // If they want the latest commit or we have found the "previous" commit that they were after, return it.
        if (string.IsNullOrWhiteSpace(commitSha) || versionMatchesGivenVersion)
            return version.Commit;

        // If this commit version matches the version specified, we want to return the next commit in the list, as it will be the previous commit.
        if (version.Commit.Sha.Equals(commitSha))
            versionMatchesGivenVersion = true;
    }

    return null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM