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

23

我遇到了另一个libgit2问题,非常感谢你的帮助。

我正在尝试检索文件历史记录,即更改此文件的提交列表。看起来这相当不寻常...据我所见,没有相应的函数。

我能想到的唯一方法是使用修订历史API迭代修订版本,检查附加到提交的树对象,并在其中搜索给定的文件,如果找到,则将提交添加到我的列表中;否则继续到下一个提交。

但是,我认为这并不是最优解...

也许还有其他方法,例如直接查看.git文件夹并从中获取所需信息?

非常感谢您的帮助!

3个回答

15

但我觉得这对我来说看起来不太理想...

您的方法是正确的。请注意,您将不得不解决以下问题:

  • 简单重命名(相同的对象哈希值,不同的树形入口名称)
  • 在同一提交中进行重命名和内容更新(不同的哈希值,不同的树形入口名称。需要文件内容分析和比较功能,该功能在libgit2中不可用)
  • 多个父记录历史记录(已合并两个分支,并且文件以不同方式进行了修改)

或许还有其他方法,例如直接查看.git文件夹并在那里获取所需信息?

尽管理解.git文件夹布局总是一个值得花费时间的过程,但恐怕这不能帮助您解决此特定文件历史记录问题。

注意:这个问题非常接近于这个libgit2sharp问题:如何获得影响给定文件的最后一次提交?

更新

拉取请求#963添加了这个特性。

LibGit2Sharp.0.22.0-pre20150415174523预发布NuGet包以来,它已经可用。


其实这个问题完全一样 :) - shytikov

2

谢谢,但那不比空令牌多说什么。他也提供了一个链接。+我也用了谷歌..我希望能得到shyitok所说的要点。-我实现了它,但它没有遵循重命名 - 它是基于git日志示例代码的。 - Daij-Djan
我同意,这更像是一个更新,四年后才出现。正如所提到的,实现仍然有待商榷。 - VonC
@Daij-Djan nulltoken提到了我刚才提到的同一个PR:LibGit2Sharp.0.22.0-pre20150415174523具有此功能。 - VonC
我想要检索特定文件的文件历史记录。我已经尝试了下面的代码,但是在历史记录IEnumerable中没有任何提交。请提供一些解决此问题的信息。 Repository repo = new Repository(repoPath); IEnumerable<LogEntry> history = repo.Commits.QueryBy(filePath, new FollowFilter { SortBy = CommitSortStrategies.Topological }); - Odrai
@Odrai 我明白。看起来 https://github.com/libgit2/rugged/pull/531 仍然是“正在进行中”。 - VonC
目前我不知道@Odrai。 - VonC

0

如果使用C#,这个功能已经被添加到LibGit2Sharp 0.22.0NuGet Package(Pull Request 963)。你可以这样做:

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

在我的Diff All Files VS Extension(这是开源的,所以您可以查看代码)中,我需要获取文件的上一个提交,以便在给定的提交中查看对文件所做的更改。这是我检索文件的上一个提交的方法:
/// <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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接