Клонировать репозиторий 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;
    

    };

Другие вопросы по тегам