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

使用JGit将git存储库克隆到InMemoryRepository中,git,jgit,Git,Jgit,我需要将现有的git存储库克隆到一个InMemoryRepository,使用JGit更改文件的内容,并将更改推回到远程存储库 我找不到任何将存储库克隆到内存中存储库的示例 我试过这个: InMemoryRepository.Builder=newinmemoryrepository.Builder(); InMemoryRepository inm=builder.build(); Git.cloneRepository().setURI(“Git@[github_url].Git”).set

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

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

我试过这个:

InMemoryRepository.Builder=newinmemoryrepository.Builder();
InMemoryRepository inm=builder.build();
Git.cloneRepository().setURI(“Git@[github_url].Git”).setDirectory(inm.getDirectory()).call();
这导致了一个错误

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

我检查了MemoryRepository.Builder和Repository类的配置选项,但没有发现任何有用的东西


怎样才能做到呢?在这之后,更改文件内容并将其推送到github(全部来自内存存储库)是否有任何问题?

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

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

例如:

Git.cloneRepository().setURI(…).setDirectory(新文件(“/path/to/empty/dir”).call();

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

有一个合适的解决方案,磁盘上没有任何文件,甚至是临时的:

//示例用法
私有void loadFromGit()引发异常{
ObjectLoader=loadRemote(“https://github.com/msangel/promisified-resource-loader“,”master“,”README.md“;
加载程序.copyTo(系统输出);
}
私有ObjectLoader loadRemote(字符串uri、字符串分支、字符串文件名)引发异常{
DfsRepositoryDescription repoDesc=新建DfsRepositoryDescription();
InMemoryRepository回购=新的InMemoryRepository(Reposec);
吉特=新吉特(回购);
git.fetch()
.setRemote(uri)
.setRefSpecs(新的RefSpec(“+refs/heads/*:refs/heads/*”)
.call();
repo.getObjectDatabase();
ObjectId lastCommitId=报告解析(“参考文件/标题/”+分支);
RevWalk RevWalk=新的RevWalk(回购);
RevCommit-commit=revWalk.parseCommit(lastCommitId);
RevTree-tree=commit.getTree();
TreeWalk TreeWalk=新TreeWalk(回购);
树路。添加树(树);
treeWalk.setRecursive(true);
setFilter(PathFilter.create(filename));
如果(!treeWalk.next()){
返回null;
}
ObjectId ObjectId=treeWalk.getObjectId(0);
ObjectLoader=repo.open(objectId);
返回装载机;
}

因此,实际上这里有TreeWalk(默认为recursive),但您可以更改此选项并手动迭代所有来自repo的内容。

另外,对前面的答案稍加调整:

  • 列出提交中的所有文件
  • 按扩展名筛选文件

    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;
    
    公共函数lastCommitFiles=(扩展)->{
    最终列表路径=新的ArrayList();
    试一试{
    ...
    try(TreeWalk=newtreewalk(inMemoryRepository)){
    walk.addTree(revTree);
    walk.setRecursive(true);
    walk.setPostOrderTraversal(true);
    while(walk.next()){
    if((扩展名!=null&&extension.length()>0)){
    if(walk.getPathString().lastIndexOf(扩展名)!=-1){
    add(walk.getPathString());
    }
    }添加(walk.getPathString());
    }
    }
    返回路径;
    }捕获(GitAPIException | IOE异常){
    log.error(例如getMessage());
    }
    返回路径;
    
    })


如果我没有将目录设置为
CloneCommand
,那么基于文件的存储库保存在哪里?InMemoryRepository中的
是否仅用于新存储库?(显然未保存)如果未设置目录,则
CloneCommand
将选择一个目录(当前程序工作目录加上存储库名称,请参见JavaDoc)。是的,当前状态下的
InMemoryRepository
在实际使用中非常有限,仅用于实验或测试目的。这是因为
inm.getDirectory()
返回空值,因此实际上根本不设置目录。就这么跑了。