diff 如何处理 JGit 中的合并提交

How does diff treat merge commits in JGit

我正在尝试使用 JGit 库以编程方式查找两次提交之间的差异。

假设我有以下提交层次结构:

---1---2---3---4---5---6---7---8--
        \--9-—10—-11--/

现在假设我正在分析提交 4 - 7 之间的差异,diff 命令将如何引用 6 中的合并? 它会保存与先前提交(4 之前)相关的信息,例如 2 吗?

我正在使用以下代码来确定差异:

private static List<DiffEntry> getDiffsBetweenCommits(String repositoryWorkDir, String fromCommit, String toCommit) {
    List<DiffEntry> diffs = null;
    try {

        // Access GIT repository
        File workDir = new File(repositoryWorkDir);
        Git git = Git.open(workDir);
        repository =  git.getRepository();

        // Locate commit references
        ObjectId current = repository.resolve(toCommit + "^{tree}");
        ObjectId previous = repository.resolve(fromCommit + "^{tree}");

        // Generate tree iterators
        ObjectReader reader = git.getRepository().newObjectReader();
        CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
        oldTreeIter.reset(reader, previous);
        CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
        newTreeIter.reset(reader, current);

        // Calculate GIT differences
        diffs = git.diff()
                .setNewTree(newTreeIter)
                .setOldTree(oldTreeIter)
                .call();
    } catch (Exception e) {
        System.out.println("Error analyzing commit's diffs");
        e.printStackTrace();
    }
    return diffs;
}

我在远早于 4 的提交中更改了文件,我怀疑我是因为合并/变基历史而得到它们的,但我不太了解它,所以我会能够向自己解释。

感谢您帮助理解差异分析逻辑。

你最好把 rephrasing/this 问题放在更笼统的 Git 上下文中。

尽管如此,以下是我对该主题的了解:与其他 SCM 不同,Git 存储提交的全部内容,而不仅仅是与父提交的差异。每个提交都引用一个所谓的 'tree',它列出提交中的所有文件以及指向相应文件内容的指针。

创建提交时,会获取其父级的树,应用所有分阶段更改(添加、修改、删除),并将生成的(新)树与提交元数据一起存储。关于其内容,每个提交都可以在不参考其父项的情况下重建。

让我们假设您的示例中的每个提交都添加了一个唯一的文件。如果您查看提交 #6,它包含从 1 到 6 的所有文件,以及 9、10、11 的文件。因此,'git diff 4 6' 将比较提交 #4 的树和提交 #6 的树(其中包括您迄今为止历史记录中的所有文件)。

有关 Git 中存储内部结构的更多详细信息,您可能需要阅读这篇文章:http://www.codeaffine.com/2014/10/20/git-internals/ post 附有独立的学习测试以检查结果JGit.