如何获取单个提交的每个更改文件的补丁?

时间:2014-07-18 10:15:34

标签: git libgit2sharp

我正在尝试通过挖掘git-repository获取有关commit-history的一些信息。我正在使用libgit2sharp包。

到目前为止,我收到了commit-author,committer,sha-value,commit-date和commit-message。我的问题是遍历存储库树,以获取每个提交的所有已更改文件的补丁。

以前有人解决过这个问题,还是可以帮助我?

using (var repo = new Repository(@"path\to\.git"))
            {
                var commits = repo.Commits; 
                Commit lastCommit = commits.Last();

                foreach (Commit commit in commits)
                    if (commit.Sha != lastCommit.Sha)
                    {
                        Console.WriteLine(commit.Sha);
                        Console.WriteLine(commit.Author.Name);
                        Console.WriteLine(commit.Committer.Name);
                        Console.WriteLine(commit.Author.When); //Commit-Date
                        Console.WriteLine(commit.Message);

                        Tree tree = commit.Tree;
                        Tree parentCommitTree = lastCommit.Tree; 

                        TreeChanges changes = repo.Diff.Compare<TreeChanges>(parentCommitTree, tree);
                        foreach (TreeEntryChanges treeEntryChanges in changes)
                        {
                            ObjectId oldcontenthash = treeEntryChanges.OldOid;
                            ObjectId newcontenthash = treeEntryChanges.Oid;
                        } 
                     }   
            }

另一个尝试是以下代码。它显示了根级别的文件和文件夹,但我无法打开文件夹。

foreach(TreeEntry treeEntry in tree)
   {
    // Blob blob1 = (Blob)treeEntry.Target;

    var targettype = treeEntry.TargetType;
    if (targettype == TreeEntryTargetType.Blob)
      {
        string filename = treeEntry.Name;
        string path = treeEntry.Path;
        string sha = treeEntry.Target.Sha;

        var filemode = treeEntry.Mode;
        Console.WriteLine(filename);
        Console.WriteLine(path);
      }
      else if (targettype == TreeEntryTargetType.Tree)
        {
         Console.WriteLine("Folder: " + treeEntry.Name);
        }
   }

2 个答案:

答案 0 :(得分:3)

&gt;(如何)获取每次提交的所有已更改文件的补丁?

使用Diff.Compare<Patch>()方法传递您愿意比较的每个Tree的{​​{1}}。

Commit

通过查看 DiffTreeToTreeFixture.cs 测试套件中的测试方法 CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks() ,可以找到更多使用详情。

&gt;另一个尝试是以下代码。它显示了根级别的文件和文件夹,但我无法打开文件夹。

每个Tree commitTree1 = repo.Lookup<Commit>("f8d44d7").Tree; Tree commitTree2 = repo.Lookup<Commit>("7252fe2").Tree; var patch = repo.Diff.Compare<Patch>(commitTree1, commitTree2); 都会公开一个TreeEntry属性,返回指向Target的内容。

GitObject的类型为TargetType时,为了检索此子TreeEntryTargetType.Tree,您必须使用以下内容:

Tree

答案 1 :(得分:1)

感谢您的回答!

现在我收到了两次提交之间的补丁。使用以下代码,通常会抛出OutOfMemoryException。

LibGit2Sharp.Commit lastCommit = commits.First();
repository.CommitCount = commits.Count();
 foreach (LibGit2Sharp.Commit commit in commits) 
    if (commit.Sha != lastCommit.Sha)
      {
       Tree commitTree1 = repo.Lookup<LibGit2Sharp.Commit>(lastCommit.Sha).Tree;
       Tree commitTree2 = repo.Lookup<LibGit2Sharp.Commit>(commit.Sha).Tree;
       var patch = repo.Diff.Compare<Patch>(commitTree1, commitTree2);
       // some value assigments                        
        lastCommit = commit;
  }