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

发布于 2024-12-17 17:27:58 字数 289 浏览 5 评论 0原文

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

我正在尝试检索文件历史记录,即更改此文件的提交列表。这似乎很不传统......据我所知,没有任何功能。

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

但它对我来说看起来不是最佳的......

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

非常感谢!

I got another libgit2 issue and will be very grateful for your help.

I'm trying to retrieve file history, i.e. 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.

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?

Many thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

勿忘初心 2024-12-24 17:27:58

但它看起来对我来说不是最佳的......

你的方法是正确的。请注意,您必须应对:

  • 普通重命名(相同的对象哈希,不同的树条目名称)
  • 在同一提交中发生重命名和内容更新(不同的哈希,不同的树条目名称。需要文件内容分析和比较功能,这是libgit2 中不可用)
  • 多个父历史记录(已合并的两个分支,并且同一文件已以不同方式修改到其中)

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

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

注意:这个问题与这个 libgit2sharp 问题非常接近:How to get the影响给定文件的最后一次提交?

更新

拉取请求#963 添加了这个功能。

它自 LibGit2Sharp.0.22.0-pre20150415174523 预发布 NuGet 包起可用。

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)
  • 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?

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.

Note: this question is very close from this libgit2sharp issue: How to get the last commit that affected a given file?

Update

Pull request #963 adds this very feature.

It's available since LibGit2Sharp.0.22.0-pre20150415174523 pre-release NuGet package.

荒路情人 2024-12-24 17:27:58

这主要是在libgit2的issues/495中遵循的。
即使它是在libgit2sharp中实现的PR 963,用于 里程碑 22),它在 libgit2 本身中仍然是“待抢夺的”。

该问题记录在 issues/3041:提供包装 revwalk 的日志功能< /a>.
问题中提到的方法用于
此 libgit2sharp示例并且可以进行调整使用 libgit2 转换为 C。在 3041 决议得到解决之前,它仍然是当前的解决方法。

This is mainly followed in issues/495 of libgit2.
Even though it is implemented in libgit2sharp (PR 963, for milestone 22), it is still "up for grabs" in libgit2 itself.

The issue is documented in issues/3041: Provide log functionality wrapping the revwalk.
The approach mentioned in the question was used in this libgit2sharp example and can be adapted to C using libgit2. It remains the current workaround, pending the resolution of 3041.

2024-12-24 17:27:58

如果使用 C#,此功能已添加到 LibGit2Sharp 0.22.0 NuGet Package< /a> (拉取请求 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;
}

If using C#, this functionality has been added to the LibGit2Sharp 0.22.0 NuGet Package (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. 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文