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

wz1wpwve  于 2022-10-30  发布在  Java
关注(0)|答案(3)|浏览(522)

我一直在开发一个基于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
}
}
bvjxkvbb

bvjxkvbb1#

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

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

如果提交被表示为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

6tdlim6h

6tdlim6h2#

我从这个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);
            }
        }
    }
}
13z8s7eq

13z8s7eq3#

我想出了这个解决方案来查找在提交中更改的文件列表。因为一个提交只有提交时的文件(树),它没有任何更改。你不能得到差异,直到你比较提交和另一个提交(父)。这个解决方案是通过查看Jgit如何执行diff来研究的。
注:为了简单起见,我没有处理提交有多个父提交或没有父提交的特殊情况。
查找由一组提交更改的一组文件(唯一且已排序)。

public Set<String> getChangedFiles(Git git, Set<RevCommit> commits)
{
    TreeWalk walk = new TreeWalk(git.getRepository());
    walk.setRecursive(true);
    walk.setFilter(TreeFilter.ANY_DIFF);

    Set<String> files = new TreeSet<>(); // Uses natural ordering
    commits.forEach(commit->
    {
        System.err.println( commit.getFullMessage() );
        ObjectId a = commit.getTree().getId();
        RevCommit parent = commit.getParent(0);
        ObjectId b = parent.getTree().getId();

        try
        {
            walk.reset(b,a);
            List<DiffEntry>changes = DiffEntry.scan(walk);
            changes.forEach(de->
            {
                files.add(de.getNewPath()); // use old path if change type is deleted
            });
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    });
    return files;
}

相关问题