Java JGit:在分支中的提交时读取文件内容

Java JGit:在分支中的提交时读取文件内容,java,jgit,Java,Jgit,我想在某个分支的某个提交处读取文件的内容:我目前正在使用此代码在某个提交处读取文件的内容,而忽略该分支 public static String readContentOfFileAtCommit(String commitStr, String fileName) throws IOException { String content = null; ObjectId lastCommitId = currentRepo.resolve(commitS

我想在某个分支的某个提交处读取文件的内容:我目前正在使用此代码在某个提交处读取文件的内容,而忽略该分支

    public static String readContentOfFileAtCommit(String commitStr, String fileName)
        throws IOException {

    String content = null;
    ObjectId lastCommitId = currentRepo.resolve(commitStr);

    try (RevWalk revWalk = new RevWalk(currentRepo)) {
        RevCommit commit = revWalk.parseCommit(lastCommitId);
        RevTree tree = commit.getTree();

        try (TreeWalk treeWalk = new TreeWalk(currentRepo)) {
            treeWalk.addTree(tree);
            treeWalk.setRecursive(true);
            treeWalk.setFilter(PathFilter.create(fileName));
            if (!treeWalk.next()) {
                throw new IllegalStateException("Did not find expected file:" + fileName);
            }

            ObjectId objectId = treeWalk.getObjectId(0);
            ObjectLoader loader = currentRepo.open(objectId);
            content = new String(loader.getBytes());
        }

        revWalk.dispose();
    }

    return content;
}

我的目标是在某个分支上完成的某个提交中获取文件的内容。

与大多数旧的VCS工具分支不同,Git中的分支只是指向这些提交之一的轻量级可移动指针。它本身不“包含”任何提交。换句话说,它只是一个简单的文件,包含它所指向的提交的40个字符的SHA-1校验和。还有一个很好的例子:

正如Rüdiger Herrmann所说,虽然提交通常是在分支上创建的,但不能说提交是在事实发生之后“在分支上完成的”。之后可以添加、删除、重命名或更新分支。例如,即使分支或标记
v1.0
被删除,提交
98ca9
34ac2
f30ab
仍然存在,并且可以通过
master
访问。我建议你阅读更多细节

对于JGit,以下是我对特定提交的读取路径的实现:

private String getContent(RevCommit commit, String path) throws IOException {
  try (TreeWalk treeWalk = TreeWalk.forPath(git.getRepository(), path, commit.getTree())) {
    ObjectId blobId = treeWalk.getObjectId(0);
    try (ObjectReader objectReader = repo.newObjectReader()) {
      ObjectLoader objectLoader = objectReader.open(blobId);
      byte[] bytes = objectLoader.getBytes();
      return new String(bytes, StandardCharsets.UTF_8);
    }
  }
}

与大多数旧的VCS工具分支不同,Git中的分支只是指向这些提交之一的轻量级可移动指针。它本身不“包含”任何提交。换句话说,它只是一个简单的文件,包含它所指向的提交的40个字符的SHA-1校验和。还有一个很好的例子:

正如Rüdiger Herrmann所说,虽然提交通常是在分支上创建的,但不能说提交是在事实发生之后“在分支上完成的”。之后可以添加、删除、重命名或更新分支。例如,即使分支或标记
v1.0
被删除,提交
98ca9
34ac2
f30ab
仍然存在,并且可以通过
master
访问。我建议你阅读更多细节

对于JGit,以下是我对特定提交的读取路径的实现:

private String getContent(RevCommit commit, String path) throws IOException {
  try (TreeWalk treeWalk = TreeWalk.forPath(git.getRepository(), path, commit.getTree())) {
    ObjectId blobId = treeWalk.getObjectId(0);
    try (ObjectReader objectReader = repo.newObjectReader()) {
      ObjectLoader objectLoader = objectReader.open(blobId);
      byte[] bytes = objectLoader.getBytes();
      return new String(bytes, StandardCharsets.UTF_8);
    }
  }
}

请澄清你的问题。代码段的预期结果是什么?实际结果是什么?更新了问题虽然提交通常是在分支上创建的,但您不能说提交“是在分支上完成的”。分支可以在其后添加、删除、重命名或更新。唯一可以确定的是,在给定的时间,可以从一个或多个分支访问给定的提交。
NameRevCommand
列出了可以从中进行提交的所有分支。顺便说一句
revWalk.dispose()
是不必要的,因为revWalk是在资源块try with中隐式调用的
close()
方法中处理的。请澄清您的问题。代码段的预期结果是什么?实际结果是什么?更新了问题虽然提交通常是在分支上创建的,但您不能说提交“是在分支上完成的”。分支可以在其后添加、删除、重命名或更新。唯一可以确定的是,在给定的时间,可以从一个或多个分支访问给定的提交。
NameRevCommand
列出了提交可以从中到达的所有分支。顺便说一句
revWalk.dispose()
是不必要的,因为revWalk是在资源块try with中隐式调用的
close()
方法中释放的