我正在尝试在工作副本中检测上次提交后发生的可能的文件重命名。 在我的例子中,我有一个干净的工作副本,我这样做:
git mv old.txt new.txt
正在运行$ git status
会显示预期结果:
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: old.txt -> new.txt
使用StatusCommand
,我可以在已删除的列表中看到 old.txt ,并在添加的列表中看到 new.txt 。
但我找不到将它们联系在一起的方法。
我知道RenameDetector
的存在,但它使用DiffEntry
,我不知道如何在 HEAD 和工作副本。
答案 0 :(得分:7)
TreeWalk tw = new TreeWalk(repository);
tw.setRecursive(true);
tw.addTree(CommitUtils.getHead(repository).getTree());
tw.addTree(new FileTreeIterator(repository));
RenameDetector rd = new RenameDetector(repository);
rd.addAll(DiffEntry.scan(tw));
List<DiffEntry> lde = rd.compute(tw.getObjectReader(), null);
for (DiffEntry de : lde) {
if (de.getScore() >= rd.getRenameScore()) {
System.out.println("file: " + de.getOldPath() + " copied/moved to: " + de.getNewPath());
}
}
(此代码段也使用Gitective库)
答案 1 :(得分:0)
如果有人想在获取DiffEntry时使用路径过滤器,则应提供新旧路径。
List<DiffEntry> diffs = git.diff()
.setOldTree(prepareTreeParser(repository, oldCommit))
.setNewTree(prepareTreeParser(repository, newCommit))
.setPathFilter(PathFilterGroup.createFromStrings(new String[]{"new/b.txt","b.txt"}))
.call();
RenameDetector rd = new RenameDetector(repository);
rd.addAll(diffs);
diffs = rd.compute();
如果你想要树解析器方法的代码:
private static AbstractTreeIterator prepareTreeParser(Repository repository, String objectId) throws IOException {
try (RevWalk walk = new RevWalk(repository)) {
RevCommit commit = walk.parseCommit(repository.resolve(objectId));
RevTree tree = walk.parseTree(commit.getTree().getId());
CanonicalTreeParser treeParser = new CanonicalTreeParser();
try (ObjectReader reader = repository.newObjectReader()) {
treeParser.reset(reader, tree.getId());
}
walk.dispose();
return treeParser;
}
}