如何使用 JGit 获取提交的文件列表

Posted

技术标签:

【中文标题】如何使用 JGit 获取提交的文件列表【英文标题】:How to get the file list for a commit with JGit 【发布时间】:2017-03-28 04:00:07 【问题描述】:

我一直在开发一个基于 Java 的产品,该产品将集成 Git 功能。使用其中一个 Git 功能,我已经完成了将 10 多个文件添加到 Git 存储库的操作,方法是暂存,然后在一次提交中提交它们。

上述过程的逆过程是否可行?即查找作为提交的一部分提交的文件列表。

我在git.log() 命令的帮助下获得了提交,但我不确定如何获取提交的文件列表。

示例代码:

Git git = (...);
Iterable<RevCommit> logs = git.log().call();
for(RevCommit commit : logs) 
    String commitID = commit.getName();
    if(commitID != null && !commitID.isEmpty()) 
    TableItem item = new TableItem(table, SWT.None);
    item.setText(commitID);
    // Here I want to get the file list for the commit object


【问题讨论】:

请澄清什么是“Git 功能”。您指的是Eclipse JGit,还是Eclipse IDE Git 集成,或者完全是其他的东西? 是的,你是对的 Herrmann。我说的是JGit。我需要一个函数调用,用于将文件列表作为提交的一部分提交。 然后给我们看一些代码,到目前为止你尝试了什么? 请看上面的示例代码。我将在表格中显示提交 ID,并在单独的列表中显示相应的提交文件。我不知道如何获取特定提交的文件列表。 您是否尝试在我的回答中包含代码? 【参考方案1】:

每个提交都指向一个,它表示构成该提交的所有文件。

请注意,这不仅包括在此特定提交中添加、修改或删除的文件,还包括此修订中包含的所有文件。

如果提交表示为RevCommit,则可以这样获取树的ID:

ObjectId treeId = commit.getTree().getId();

如果提交 ID 来自其他来源,则需要先解析它以获取关联的树 ID。见这里,例如:How to obtain the RevCommit or ObjectId from a SHA1 ID string with JGit?

要遍历树,请使用TreeWalk

try (TreeWalk treeWalk = new TreeWalk(repository)) 
  treeWalk.reset(treeId);
  while (treeWalk.next()) 
    String path = treeWalk.getPathString();
    // ...
  

如果您只对某个提交记录的更改感兴趣,请参阅此处:Creating Diffs with JGit 或此处:File diff against the last commit with JGit

【讨论】:

我得到:org.eclipse.jgit.errors.IncorrectObjectTypeException: Object e5acd3dd99bfc09bf93ba4dd2db4a9ddba4c7359 is not a tree. 如果不添加/修改或删除文件,为什么还要在暂存区? @NimChimpsky 谢谢你的提示。在这方面我的回答不是很清楚。请查看我编辑的答案,希望更有意义。 是否可以从存储库中的文件路径获取提交? 你在寻找这样的东西吗:***.com/questions/11471836/…?【参考方案2】:

我根据link 中给出的代码进行了一些编辑。 您可以尝试使用以下代码。

public void commitHistory(Git git) throws NoHeadException, GitAPIException, IncorrectObjectTypeException, CorruptObjectException, IOException, UnirestException 

    Iterable<RevCommit> logs = git.log().call();
    int k = 0;
    for (RevCommit commit : logs) 
        String commitID = commit.getName();
        if (commitID != null && !commitID.isEmpty())
        
            LogCommand logs2 = git.log().all();
            Repository repository = logs2.getRepository();
            tw = new TreeWalk(repository);
            tw.setRecursive(true);
            RevCommit commitToCheck = commit;
            tw.addTree(commitToCheck.getTree());
            for (RevCommit parent : commitToCheck.getParents())
            
                tw.addTree(parent.getTree());
            
            while (tw.next())
            
                int similarParents = 0;
                for (int i = 1; i < tw.getTreeCount(); i++)
                    if (tw.getFileMode(i) == tw.getFileMode(0) && tw.getObjectId(0).equals(tw.getObjectId(i)))
                        similarParents++;
                if (similarParents == 0) 
                        System.out.println("File names: " + fileName);
            
        
    

【讨论】:

以上是关于如何使用 JGit 获取提交的文件列表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jgit 查找所有提交,而不仅仅是可引用的提交

获取 Bamboo 上的提交文件列表

如何获取 git commit 中的文件列表? [复制]

[转] 利用git钩子,使用python语言获取提交的文件列表

如何找到提交给 git 分支的文件列表?

如何用 jgit 做相当于“git diff --name-status”的操作?