从JGit中的RevCommit对象获取提交信息

从JGit中的RevCommit对象获取提交信息,git,jgit,Git,Jgit,我调用了jgitlog命令并返回了一些RevCommit对象。我可以从中获取一些基本信息,并使用以下代码获取已更改的文件列表。不过,我还需要两件事: 1) 当提交没有父级时,如何获取以下信息 2) 如何获得每个文件中更改内容的差异 RevCommit=null; RevWalk rw=新的RevWalk(存储库); RevCommit parent=null; if(commit.getParent(0)!=null){ parent=rw.parseCommit(commit.getParen

我调用了jgitlog命令并返回了一些RevCommit对象。我可以从中获取一些基本信息,并使用以下代码获取已更改的文件列表。不过,我还需要两件事:

1) 当提交没有父级时,如何获取以下信息

2) 如何获得每个文件中更改内容的差异

RevCommit=null;
RevWalk rw=新的RevWalk(存储库);
RevCommit parent=null;
if(commit.getParent(0)!=null){
parent=rw.parseCommit(commit.getParent(0.getId());
}
DiffFormatter df=新的DiffFormatter(DisabledOutputStream.INSTANCE);
setRepository(repository);
setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(真);
List diff=df.scan(parent.getTree(),commit.getTree());
用于(差异:差异){
System.out.println(getCommitMessage());
System.out.println(“changeType=“+diff.getChangeType().name())
+“newMode=“+diff.getNewMode().getBits()
+“newPath=“+diff.getNewPath()
+“id=“+getHash());
}
1)使用重载的
scan
方法和
AbstractTreeIterator
并在没有父对象的情况下如下调用它:

df.scan(new EmptyTreeIterator(),
        new CanonicalTreeParser(null, rw.getObjectReader(), commit.getTree());
无父项的情况仅适用于初始提交,在这种情况下,diff的“before”为空

2) 如果要
git diff
样式输出,请使用以下命令:

df.format(diff);
而diff将被写入传递给构造函数的输出流中。因此,要单独获取每个差异,应该可以对每个文件使用一个
DiffFormatter
实例。或者您可以将一个
DiffFormatter
与一个
ByteArrayOutputStream
一起使用,在格式化下一个文件之前获取内容并重置它。大致如下:

ByteArrayOutputStream out = new ByteArrayOutputStream();
DiffFormatter df = new DiffFormatter(out);
// ...
for (DiffEntry diff : diffs) {
    df.format(diff);
    String diffText = out.toString("UTF-8");
    // use diffText
    out.reset();
}
请注意,Git不知道文件的编码,这必须在
toString()
方法中指定。在这里,它使用了一个合理的默认值。根据您的用例,您最好不要使用
toByteArray()
对其进行解码



一般注意事项:请确保您始终使用
release()

释放
RevWalk
DiffFormat
的资源。谢谢您的回复,我会在有机会时试一试。你介意详细说明你对第二个问题的答案吗?我希望每个文件都有标准的diff输出,就像git扩展名或git k(仅每个文件)一样。你能给我一些我将如何做到这一点的示例代码吗?再次感谢。非常感谢您的解决方案。我两个都试过了,效果很好。我很抱歉要求提供更多关于2号的细节,我认为它的实现更加复杂。还感谢您提醒我在RevWalk上调用release。我是用其他代码做的,但忘在这里了。还感谢您让我知道需要发布DiffFormat。是的,这正是我在您发布lol之前实现它的方式。但是它对我有效,而无需在toString()中指定编码。这是巧合吗?UTF-8是默认编码吗?对于其他编码,它会中断吗?默认编码是“默认编码”(请参阅),这取决于许多因素。使用
Charset.defaultCharset()
检查它。但我不建议依赖于此,因为Git存储库中文件的编码与JVM环境的编码无关。而且,不同的存储库甚至不同的文件可能会有所不同。在任何情况下,
UTF-8
都比默认编码更好。谢谢,我已经在toString中添加了编码。所以没有办法找出存储库的编码是什么?这是一个奇怪的限制。但我想更奇怪的是,我必须使用ByteArrayOutputStream来获取差异信息。应该有一个返回字符串lol的方法。这是我在JGit中发现的奇怪的事情之一。它对用户不是很友好,也没有很好的文档记录。许多方法应该只返回从普通git命令中获得的值,而不是经常需要解析的流。至少它起作用了。再次感谢。