I'm using JGit 6.5.x with Java 17. I have a remote repository that is huge (gigabytes), but I only need temporary access to a single subdirectory (e.g. foo/bar/
) for processing. The single subdirectory is really small (hundreds of kilobytes). Cloning a shallow, bare repository is relatively small as well:
try (final Git git = Git.cloneRepository()
.setURI(REMOTE_REPOSITORY_URI.toASCIIString())
.setDirectory(LOCAL_RESPOSITORY_PATH.toFile())
.setBare(true)
.setDepth(1)
.call()) {
System.out.println("cloned shallow, bare repository");
}
Is there a way to clone a shallow, bare repository like that (or any other minimal version of the repository), and then check out just the single subdirectory foo/bar
to some other directory temporarily so that I can process those files using the normal Java file system API?
Note that I just now succeeded in the the clone above and haven't started looking into how I might check out just a single subdirectory from this bare repository.
Inspired by another answer I was able get a single-depth clone and check out only a single path without needing to do a bare clone, while using similar minimal file system space. The benefit to this approach is that only a single top-level directory is needed; the bare repository approach on the other hand requires a manual traversal and saving to a separate drop-level directory.
The key is to use setNoCheckout(true)
(in addition to setDepth(1)
), and then after cloning manually perform a separate checkout specifying the requested path. Note that you must specify setStartPoint("HEAD")
or specify a hash starting point, as there will be no branch because there is not yet a checkout.
try (final Git git = Git.cloneRepository()
.setURI(REMOTE_REPOSITORY_URI.toASCIIString())
.setDirectory(LOCAL_RESPOSITORY_PATH.toFile())
.setNoCheckout(true)
.setDepth(1)
.call()) {
gitRepository.checkout()
.setStartPoint("HEAD")
.addPath("foo/bar")
.call();
}
This seems to work very nicely! I would imagine it uses something similar to Satyajit Bhatt's answer under the hood.