6

上下文

我正在尝试在工作副本中检测上次提交后可能发生的文件重命名。在我的例子中,我有一个干净的工作副本,我这样做:

git mv old.txt new.txt

运行$ git status显示预期结果:

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    old.txt -> new.txt

我试过了

使用 a StatusCommand,我可以在删除的列表中看到old.txt ,在添加的列表中看到new.txt。但我找不到将它们联系在一起的方法。

我知道 的存在RenameDetector,但它可以使用DiffEntry,而且我不知道如何在HEAD工作副本之间获取 DiffEntries 。

4

2 回答 2

8

没关系,找到答案了。JGit 的 API 很复杂..

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 库)

于 2013-06-25T15:59:05.030 回答
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;
    }
}
于 2018-05-29T17:50:31.920 回答