Клонировать репозиторий git в репозиторий InMemory с помощью JGit
Мне нужно клонировать существующий репозиторий git в InMemoryRepository
, используя JGit, измените содержимое файла и отправьте изменения обратно в удаленный репозиторий.
Я не смог найти никаких примеров клонирования хранилища в хранилище в памяти.
Я попробовал это:
InMemoryRepository.Builder builder = new InMemoryRepository.Builder();
InMemoryRepository inm = builder.build();
Git.cloneRepository().setURI("git@[github_url].git").setDirectory(inm.getDirectory()).call();
Что привело к ошибке:
"Путь назначения".git"уже существует и не является пустым каталогом".
Я проверил параметры конфигурации для InMemoryRepository.Builder
а также Repository
занятия, но не нашли ничего полезного.
Как это можно сделать? И после этого, есть ли проблема с изменением содержимого файла и отправкой его в github, все из хранилища в памяти?
1 ответ
CloneCommand
всегда будет создавать файловый репозиторий. Строки из вашего поста, которые создают InMemoryRepository
не влияет на команду клонирования.
Я предлагаю клонировать во временное местоположение, если вам нужно только хранилище, чтобы внести изменения и выдвинуть результат.
Например:
Git.cloneRepository().setURI( ... ).setDirectory( new File("/path/to/empty/dir" ) ).call();
InMemoryRepository
в JGit по-прежнему требуется рабочий каталог для таких операций, как оформление заказа и т. д. Только объектная база данных, которая обычно находится в .git
каталог хранится в памяти
Существует правильное решение без каких-либо файлов на диске, даже временных:
// sample usage
private void loadFromGit() throws Exception {
ObjectLoader loader = loadRemote("https://github.com/msangel/promisified-resource-loader", "master", "README.md");
loader.copyTo(System.out);
}
private ObjectLoader loadRemote(String uri, String branch, String filename) throws Exception {
DfsRepositoryDescription repoDesc = new DfsRepositoryDescription();
InMemoryRepository repo = new InMemoryRepository(repoDesc);
Git git = new Git(repo);
git.fetch()
.setRemote(uri)
.setRefSpecs(new RefSpec("+refs/heads/*:refs/heads/*"))
.call();
repo.getObjectDatabase();
ObjectId lastCommitId = repo.resolve("refs/heads/"+ branch);
RevWalk revWalk = new RevWalk(repo);
RevCommit commit = revWalk.parseCommit(lastCommitId);
RevTree tree = commit.getTree();
TreeWalk treeWalk = new TreeWalk(repo);
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
treeWalk.setFilter(PathFilter.create(filename));
if (!treeWalk.next()) {
return null;
}
ObjectId objectId = treeWalk.getObjectId(0);
ObjectLoader loader = repo.open(objectId);
return loader;
}
Итак, на самом деле у вас есть TreeWalk здесь (который по умолчанию рекурсивный), но вы можете изменить это и вручную выполнить итерацию всего из репо.
Кроме того, с небольшой настройкой предыдущего ответа:
- Вывод всех файлов в коммите
Фильтрация файлов по расширению
public Function<String, List<String>> lastCommitFiles = (extension) -> { final List<String> paths = new ArrayList<>(); try { ... try (TreeWalk walk = new TreeWalk(inMemoryRepository)) { walk.addTree(revTree); walk.setRecursive(true); walk.setPostOrderTraversal(true); while (walk.next()) { if ((extension != null && extension.length() > 0)) { if (walk.getPathString().lastIndexOf(extension) != -1) { paths.add(walk.getPathString()); } } else paths.add(walk.getPathString()); } } return paths; } catch (GitAPIException | IOException e) { log.error(e.getMessage()); } return paths;
};