使用JGit将git存储库克隆到InMemoryRepository中

时间:2015-07-07 14:22:20

标签: git jgit

我需要使用JGit将现有的git存储库克隆到InMemoryRepository,更改文件的内容并将更改推送回远程存储库。

我无法找到将存储库克隆到内存存储库的任何示例。

我试过了:

InMemoryRepository.Builder builder = new InMemoryRepository.Builder();  
InMemoryRepository inm = builder.build(); 
Git.cloneRepository().setURI("git@[github_url].git").setDirectory(inm.getDirectory()).call();  

导致错误

  

'目的地路径" .git"已经存在并且不是空的   目录'

我检查了InMemoryRepository.BuilderRepository类的配置选项,但没有找到任何有用的内容。

怎么做?在那之后,更改文件的内容并将其推送到github是否有任何问题,所有这些都来自内存存储库?

3 个答案:

答案 0 :(得分:2)

CloneCommand将始终创建基于文件的存储库。创建InMemoryRepository的帖子中的行对克隆命令没有影响。

如果您只需要存储库进行更改并推送结果,我建议将其克隆到临时位置。

例如:

Git.cloneRepository().setURI( ... ).setDirectory( new File("/path/to/empty/dir" ) ).call();  

JGit中的InMemoryRepository仍然需要一个工作目录来执行checkout等操作。只有通常在.git目录中找到的对象数据库存储在内存中

答案 1 :(得分:1)

有一个适当的解决方案,即使磁盘上没有任何文件,也没有临时文件:

    // 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(默认为递归),但是您可以更改它并手动从repo中手动迭代所有内容。

答案 2 :(得分:0)

此外,对先前的答案进行了一些细微调整:

  • 列出提交中的所有文件
  • 按扩展名过滤文件

    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;
    

    };