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

时间:2016-09-27 11:20:14

标签: git jgit

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

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

---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的提交中更改了文件,我怀疑由于合并/变基历史而得到它们,但我不太了解它所以我&# 39;能够自己解释一下。

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

1 个答案:

答案 0 :(得分:0)

你可能最好改写/这个问题,把它放在更一般的Git语境中。

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

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

假设您示例中的每个提交都添加了一个唯一文件。如果你看一下commit#6,它包含1到6的所有文件,加上9,10,11的文件。因此,'git diff 4 6'会将commit#4的树与commit#6的树进行比较。 (包括目前为止历史记录中的所有文件)。

有关Git中存储内部的更多详细信息,您可能需要阅读本文:http://www.codeaffine.com/2014/10/20/git-internals/该帖子附带了自包含的学习测试,以便使用JGit检查结果。