我尝试使用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;能够自己解释一下。
感谢您协助理解差异分析逻辑。
答案 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检查结果。