【问题标题】:Getting commit information from a RevCommit object in JGit从 JGit 中的 RevCommit 对象获取提交信息
【发布时间】:2012-09-11 17:09:39
【问题描述】:

我调用了 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());
}

【问题讨论】:

    标签: git jgit


    【解决方案1】:

    1) 将重载的scan 方法与AbstractTreeIterator 一起使用,并在没有父级的情况下调用如下:

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

    没有父级的情况只针对初始提交,这种情况下diff的“before”为空。

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

    df.format(diff);
    

    并且差异将被写入传递给构造函数的输出流。因此,要单独获取每个差异,应该可以为每个文件使用一个 DiffFormatter 实例。或者您可以使用DiffFormatterByteArrayOutputStream,在格式化下一个文件之前获取内容并重置它。大致是这样的:

    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() 释放RevWalkDiffFormat 的资源。

    【讨论】:

    • 感谢您的回复,有机会我会试一试。您介意详细说明您对第 2 项的回答吗?我希望每个文件的标准差异输出由 git extensions 或 git k (仅每个文件)等工具给出。你能给出一些关于我将如何做到这一点的示例代码吗?再次感谢。
    • 非常感谢您的解决方案。我已经尝试过它们,它们就像一个魅力。我很抱歉询问有关数字 2 的更多细节,我认为实施起来更复杂。也感谢你提醒我在 RevWalk 上调用 release。我在其他代码中这样做,但在这里忘记了。也感谢您让我知道需要发布 DiffFormat。
    • 是的,这正是我在你的帖子之前实现它的方式,哈哈。但是,它适用于我而无需在 toString() 中指定编码。这是巧合吗? UTF-8 是默认值吗?对于其他编码,它会中断吗?
    • 默认是“默认编码”(见API),这取决于很多事情。使用Charset.defaultCharset() 进行检查。但我不建议依赖它,因为 Git 存储库中文件的编码与 JVM 环境的编码无关。它可能因存储库而异,甚至因文件而异。无论如何,UTF-8 是比默认编码更好的猜测。
    • 谢谢,我已将编码添加到 toString。所以没有办法找出存储库的编码是什么?这是一个奇怪的限制。但我想更奇怪的是我必须使用 ByteArrayOutputStream 来获取差异信息。应该只有一个返回字符串 lol 的方法。这是我发现的关于 JGit 的奇怪之处之一。它不是非常用户友好,也没有很好的记录。许多方法应该只返回您从普通 git 命令中获得的值,而不是您经常需要解析的流。至少它有效。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多