5

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

1)当提交没有父母时,我如何获得以下信息?

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

RevCommit commit = null;

RevWalk rw = new RevWalk(repository);

RevCommit parent = null;
if (commit.getParent(0) != null) {
   parent = rw.parseCommit(commit.getParent(0).getId());
}

DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(repository);
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(true);

List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
for (DiffEntry diff : diffs) {
   System.out.println(getCommitMessage());

   System.out.println("changeType=" + diff.getChangeType().name()
           + " newMode=" + diff.getNewMode().getBits()
           + " newPath=" + diff.getNewPath()
           + " id=" + getHash());
}
4

1 回答 1

7

1)使用重载scan方法 withAbstractTreeIterator并在没有父级的情况下调用如下:

df.scan(new EmptyTreeIterator(),
        new CanonicalTreeParser(null, rw.getObjectReader(), commit.getTree());

没有父级的情况仅适用于初始提交,在这种情况下,差异的“之前”为空。

2)如果您想要git diff样式输出,请使用以下内容:

df.format(diff);

并且差异将被写入传递给构造函数的输出流。因此,要单独获取每个差异,应该可以DiffFormatter每个文件使用一个实例。或者您可以使用DiffFormatter带有 a 的一个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().


一般注意事项:确保您始终释放RevWalkDiffFormat使用release().

于 2012-09-19T15:06:07.663 回答