Как "поместить" файл в JGit?

В то время как я искал встроенную систему управления распределенной версией в Java, и я думаю, что нашел его в JGit, который является чистой реализацией Java git. Тем не менее, не так много примеров кода или учебников.

Как я могу использовать JGit для извлечения версии HEAD определенного файла (так же, как svn cat или hg cat)?

Я предполагаю, что это связано с некоторой реверсивной ходьбой, и я ищу образец кода.

Ответ 1

К сожалению, ответ Thilo не работает с последним API JGit. Вот решение, которое я нашел:

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

Я бы хотел, чтобы это было проще.

Ответ 2

Здесь более простая версия ответа @morisil, использующая некоторые концепции из @directed, смеяться и проверяться с помощью JGit 2.2.0:

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 file tree
        RevTree tree = commit.getTree();
        // .. and narrow it down to the single file path
        TreeWalk treewalk = TreeWalk.forPath(reader, path, tree);

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

repo - объект репозитория, созданный в других ответах.

Ответ 3

Я последовал за @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 data
byte[] data = repo.open(treewalk.getObjectId(0)).getBytes();

Я не тестировал версию Java, но должен работать. Он переводится с

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

в clojure (следуя той же настройке, что и верхняя часть), которая работает.

Ответ 4

Подумал сам. 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 data
byte[] data = repo.openBlob(entry.getId()).getBytes();

Ответ 5

Я начал писать библиотеку под названием gitective, которая содержит много помощников для работы с блобами, коммитами и деревьями с помощью JGit и является MIT лицензирован и доступен на GitHub.

Получить содержимое файла в фиксации HEAD

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.

Ответ 6

Существует некоторая информация в JGit Tutorial (но это также не очень полезно, не является полным и, вероятно, устаревшим, поскольку они переключились на eclipse, где еще нет документации).