【问题标题】:How to get the patch of every changed file of a single commit?如何获取单个提交的每个更改文件的补丁?
【发布时间】:2014-07-18 10:15:33
【问题描述】:

我试图通过挖掘一个 git 存储库来获取有关提交历史的一些信息。我正在使用包 libgit2sharp。

到目前为止,我得到了提交作者、提交者、sha-value、提交日期和提交消息。我的问题是遍历存储库树,以获取每个提交的所有更改文件的补丁。

以前有人解决过这个问题吗,或者可以帮助我吗?

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);
        }
   }

【问题讨论】:

    标签: git libgit2sharp


    【解决方案1】:

    >(如何)获取每个提交的所有更改文件的补丁?

    使用Diff.Compare&lt;Patch&gt;() 方法,将您愿意比较的每个CommitTree 传递给它。

    Tree commitTree1 = repo.Lookup<Commit>("f8d44d7").Tree;
    Tree commitTree2 = repo.Lookup<Commit>("7252fe2").Tree;
    
    var patch = repo.Diff.Compare<Patch>(commitTree1, commitTree2);
    

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

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

    每个TreeEntry 公开一个Target 属性,返回指向GitObject

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

    var subTree = (Tree)treeEntry.Target;
    

    【讨论】:

      【解决方案2】:

      感谢您的回答!

      现在我收到了两次提交之间的补丁。使用以下代码,经常会抛出 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;
        }
      

      【讨论】:

      • 不应该发生异常。您能否向 issue tracker 提交完整的复制案例?
      • 这是完整的代码。它发生在大约。 7.000 次提交
      • 请在跟踪器中提交一个专门的问题以及您正在处理的公共存储库的网址
      • 作为参考,记录的问题是 #790
      猜你喜欢
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多