문제

얼마 전 나는 찾고 있었다 Java의 임베드 가능한 분산 버전 제어 시스템그리고 나는 그것을 발견했다고 생각합니다 jgit, 이것은 Git의 순수한 Java 구현입니다. 그러나 샘플 코드 나 튜토리얼의 방식에는별로 없습니다.

JGIT를 사용하여 특정 파일의 헤드 버전을 검색하려면 어떻게해야합니까 ( svn cat 또는 hg cat Whible Do)?

나는 이것이 약간의 rev-tree walking을 포함하고 코드 샘플을 찾고 있다고 생각합니다.

도움이 되었습니까?

해결책

불행히도 Thilo의 답변은 최신 JGIT API에서 작동하지 않습니다. 여기에 내가 찾은 해결책은 다음과 같습니다.

File repoDir = new File("test-git");
// open the repository
Repository repository = new Repository(repoDir);
// find the HEAD
ObjectId lastCommitId = repository.resolve(Constants.HEAD);
// now we have to get the commit
RevWalk revWalk = new RevWalk(repository);
RevCommit commit = revWalk.parseCommit(lastCommitId);
// and using commit's tree find the path
RevTree tree = commit.getTree();
TreeWalk treeWalk = new TreeWalk(repository);
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
treeWalk.setFilter(PathFilter.create(path));
if (!treeWalk.next()) {
  return null;
}
ObjectId objectId = treeWalk.getObjectId(0);
ObjectLoader loader = repository.open(objectId);

// and then one can use either
InputStream in = loader.openStream()
// or
loader.copyTo(out)

나는 그것이 더 간단했으면 좋겠다.

다른 팁

다음은 @Directed Laugh 's의 일부 개념을 사용하고 JGIT 2.2.0으로 테스트 한 @Morisil의 답변보다 간단한 버전입니다.

private String fetchBlob(String revSpec, String path) throws MissingObjectException, IncorrectObjectTypeException,
        IOException {

    // Resolve the revision specification
    final ObjectId id = this.repo.resolve(revSpec);

    // Makes it simpler to release the allocated resources in one go
    ObjectReader reader = this.repo.newObjectReader();

    try {
        // Get the commit object for that revision
        RevWalk walk = new RevWalk(reader);
        RevCommit commit = walk.parseCommit(id);

        // Get the revision's file tree
        RevTree tree = commit.getTree();
        // .. and narrow it down to the single file's path
        TreeWalk treewalk = TreeWalk.forPath(reader, path, tree);

        if (treewalk != null) {
            // use the blob id to read the file's data
            byte[] data = reader.open(treewalk.getObjectId(0)).getBytes();
            return new String(data, "utf-8");
        } else {
            return "";
        }
    } finally {
        reader.release();
    }
}

repo 다른 답변에서 생성 된 저장소 객체입니다.

나는 @thilo와 @morisil의 답변을 따라 JGIT 1.2.0과 호환됩니다.

File repoDir = new File("test-git/.git");
// open the repository
Repository repo = new Repository(repoDir);
// find the HEAD
Commit head = repo.mapCommit(Constants.HEAD);
// retrieve the tree in HEAD
Tree tree = head.getTree();

// 1.2.0 api version here
// find a file (as a TreeEntry, which contains the blob object id)
TreeWalk treewalk = TreeWalk.forPath(repo, "b/test.txt", tree);
// use the blob id to read the file's data
byte[] data = repo.open(treewalk.getObjectId(0)).getBytes();

Java 버전을 테스트하지는 않았지만 작동해야합니다. 그것은에서 번역됩니다

(.getBytes (.open repo (.getObjectId (TreeWalk/forPath repo "b/test.txt" tree) 0)))

Clojure (상단 섹션과 동일한 설정에 따라)에서 작동합니다.

혼자서 알아 냈습니다. API는 매우 낮은 수준이지만 나쁘지는 않습니다.

File repoDir = new File("test-git/.git");
// open the repository
Repository repo = new Repository(repoDir);
// find the HEAD
Commit head = repo.mapCommit(Constants.HEAD);
// retrieve the tree in HEAD
Tree tree = head.getTree();
// find a file (as a TreeEntry, which contains the blob object id)
TreeEntry entry = tree.findBlobMember("b/test.txt");
// use the blob id to read the file's data
byte[] data = repo.openBlob(entry.getId()).getBytes();

나는라는 도서관을 쓰기 시작했다 gitection 여기에는 jgit을 사용하여 멍청이, 커밋 및 나무로 작업하기위한 많은 도우미가 포함되어 있으며 Github에서 미트 라이센스가 있으며 이용 가능합니다.

헤드 커밋으로 파일 콘텐츠를 얻습니다

Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getHeadContent(repo, "src/Buffer.java");

분기에서 파일의 내용을 가져옵니다

Repository repo = new FileRepository("/repos/project/.git");
String content = BlobUtils.getContent(repo, "master", "src/Buffer.java");

두 파일이 다릅니다

Repository repo = new FileRepository("/repos/project/.git");
ObjectId current = BlobUtils.getId(repo, "master", "Main.java");
ObjectId previous = BlobUtils.getId(repo, "master~1", "Main.java");
Collection<Edit> edit = BlobUtils.diff(repo, previous, current);

제공된 유틸리티의 더 많은 예가 자세히 설명되어 있습니다 readme.

몇 가지 정보가 있습니다 JGIT 튜토리얼 (그러나 그것은 또한 그들이 전환 한 이후로 정말 도움이되거나 완전하고 아마도 구식입니다. 아직 문서를 사용할 수없는 경우).

주어진 파일 패스의 내용을 다음과 같이 읽을 수 있습니다. Treewalk가 될 수 있습니다 없는 주어진 나무에서 경로가 발견되지 않은 경우. 따라서 특정 처리가 필요합니다.

public String readFile(RevCommit commit, String filepath) throws IOException {
    try (TreeWalk walk = TreeWalk.forPath(repo, filepath, commit.getTree())) {
        if (walk != null) {
            byte[] bytes = repo.open(walk.getObjectId(0)).getBytes();
            return new String(bytes, StandardCharsets.UTF_8);
        } else {
            throw new IllegalArgumentException("No path found.");
        }
    }
}

예를 들어:

ObjectId head = repo.resolve(Constants.HEAD);
RevCommit last = repo.parseCommit(head);
readFile(last, "docs/README.md")

이 답변은 JGIT 4.8.0으로 작성되었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top