Libgit2Sharp:在两个标签之间的所有提交中获取文件

Libgit2Sharp: get files in all commits between two tags

我可以在 GitBash 中做到这一点: $ git diff --name-only v01...HEAD -- *.sql

给出:

Components/1/Database/Stored Procedures/spDC1.sql Components/1/Database/Stored Procedures/spDC2.sql

我不知道如何在 LibGit2Sharp 中执行此操作。 有任何想法吗? 谢谢

这是我的一个项目的示例,它在两次提交之间获得了一个 ICommitLog 集合(当前 HEAD 与 master 分支):

    // git log HEAD..master --reverse
    public ICommitLog StalkerList {
        get {
            var filter = new CommitFilter { 
                SortBy = CommitSortStrategies.Reverse | CommitSortStrategies.Time,
                Since = master,
                Until = head.Tip,             
            };
            return repo.Commits.QueryBy (filter);
        }
    }

一旦您获得了所需范围内所有提交的 ICommitLog 集合,您可以循环遍历每个提交以获取在该提交中受到影响的文件列表(当然您会需要通过您的“*.sql”要求添加文件名过滤:

    public String[] FilesToMerge (Commit commit)
    {
        var fileList = new List<String> ();
        foreach (var parent in commit.Parents) {
            foreach (TreeEntryChanges change in repo.Diff.Compare<TreeChanges>(parent.Tree, commit.Tree)) {
                fileList.Add (change.Path);
            }
        }
        return fileList.ToArray ();
    }

我认为 SushiHangover 对此的回答非常正确。只是一些修改/更新。 (P.S。是的,我知道这个问题相对陈旧,但如果我今天找到它,一个完整的答案会对我有所帮助,所以把一个放在这里以供将来窥视)。

这一段应该是修正意见,但我还不能评论(低评价):

首先,我认为在 Sushi 的例子中,master 和 head.Tip 是错误的。 Until 从结果中排除提交并排除其祖先。所以如果你把 head.Tip 放在那里,它基本上会排除整个历史树。

所以 AFAIK 应该更像这样:

 // git log HEAD..master --reverse
public ICommitLog StalkerList {
    get {
        var filter = new CommitFilter { 
            SortBy = CommitSortStrategies.Reverse | CommitSortStrategies.Time,
            Since = head.Tip,
            Until = master       
        };
        return repo.Commits.QueryBy (filter);
    }
}

意识到您给他们的顺序很重要,这一点也非常重要。如果你只是交换它们,你将一无所获。

(另请注意,Sushi 的原始示例在 "head.Tip" 之后有一个错误的 ','。

此位更新:

还值得注意的是,最近更新了 libgit2sharp 库。将 "Since" 和 "Until" 分别替换为 "IncludeReachableFrom" 和 "ExcludeReachableFrom"。

这些名称并不是特别有用,直到您意识到它们只是对他们正在做的事情更加冗长。

Exclude 的注释,例如:

    /// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration.

所以最新的实现看起来更像:

using (Repository r = new Repository(@"[repo_location]"))
{
    CommitFilter cf = new CommitFilter
    {
        SortBy = CommitSortStrategies.Reverse | CommitSortStrategies.Time,
        ExcludeReachableFrom = r.Branches["master"].Tip,
        IncludeReachableFrom = r.Head.Tip
    };

    var results = r.Commits.QueryBy(cf);

    foreach (var result in results)
    {
        //Process commits here.
    }
}

在 LINQPad 中对此进行了测试,它似乎可以工作。可能遗漏了一些东西,因为它是一个快速草稿。如果是这样,请告诉我。

注意事项:master 和 Head 实际上是 Repository 的属性,我在旧示例中​​看不到任何地方,但这可能只是与旧版本的版本差异。