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.
我正在尝试使用 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.