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

ari*_*abc 5 git jgit

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

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

我尝试了这个:

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

导致错误

“目标路径“ .git”已存在,并且不是空目录”。

我检查了InMemoryRepository.BuilderRepository类的配置选项,但没有发现任何有用的东西。

怎么做到呢?然后,从内存中存储库更改文件的内容并将其推送到github是否存在任何问题?

msa*_*gel 7

有一个正确的解决方案,磁盘上没有任何文件,即使是临时文件:

    // 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;
    }

Run Code Online (Sandbox Code Playgroud)

所以,实际上你在这里有 TreeWalk (默认为递归),但你可以更改它并从存储库手动迭代所有内容。


Rüd*_*ann 4

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

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

例如:

Git.cloneRepository().setURI( ... ).setDirectory( new File("/path/to/empty/dir" ) ).call();  
Run Code Online (Sandbox Code Playgroud)

JGitInMemoryRepository中仍然需要一个工作目录来进行结帐等操作。只有通常在该.git目录中找到的对象数据库才会存储在内存中

  • 如果没有设置目录,`CloneCommand`将选择一个目录(当前程序工作目录加上存储库名称,请参阅JavaDoc)。是的,当前状态下的“InMemoryRepository”在实际用途中非常有限,仅用于实验或测试目的。 (2认同)