I need to clone an existing git repository into an InMemoryRepository
, using JGit, change a file's content and push the changes back to the remote repository.
I couldn't find any examples of cloning a repository into an in-memory repository.
I tried this:
InMemoryRepository.Builder builder = new InMemoryRepository.Builder();
InMemoryRepository inm = builder.build();
Git.cloneRepository().setURI("git@[github_url].git").setDirectory(inm.getDirectory()).call();
Which resulted in an error:
'Destination path ".git" already exists and is not an empty directory'.
I checked the configuration options for InMemoryRepository.Builder
and Repository
classes, but haven't found anything useful.
How can it be done? And after that, is there any problem with changing a file's content and pushing it to github, all from the in-memory repository?
Download and install the TortoiseGit client. Configure an HTTPS password. On the CodeHub homepage, click the name of a repository in the repository list. On the repository details page displayed, click Clone/Download, click Clone with HTTPS, and copy the repository address.
There is a proper solution without any files on disk, even temporary:
// 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;
}
So, actually you have TreeWalk here (which is default to recursive), but you can change this and manually iterate all from repo.
The CloneCommand
will always create a file-based repository. The lines from your post that create an InMemoryRepository
have no effect on the clone command.
I suggest to clone into a temporary location if you only need the repository to make a change and push the result.
For example:
Git.cloneRepository().setURI( ... ).setDirectory( new File("/path/to/empty/dir" ) ).call();
An InMemoryRepository
in JGit still requires a work directory for operations like checkout, etc. Only the object database which is usually found in the .git
directory is stored in memory
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With