1

I am working with jGit in Java and I have managed to clone an entire repository. But I can not find a way to download a single file inside a repository. I have tried:

  • Change the URL specifying the path of the file.
  • Change the URL by specifying a subdirectory.

Neither of them worked.

My code (clone whole repository) is as follows:

public File cloneRepository(String url, String path) throws GitAPIException {

    File download = new File (path);
    if (download.exists()){
        System.out.println("Error");
        return null;
    }
    else{
        CloneCommand clone = Git.cloneRepository()      
                .setURI(url)
                .setDirectory(download);
        try (Git repositorio = clone.call()) {
            return repositorio.getRepository().getWorkTree();
        }
    }
}

How could it be changed to download a single file?

user5872256
  • 69
  • 11
  • You tagged your question with "github", does that mean that you want to know for a repository on github? Because you don't need jgit for that, URL/URLConnection can handle it for you. Otherwise, if there is no web interface on the repository, it's hard. Check out https://stackoverflow.com/questions/1125476/retrieve-a-single-file-from-a-repository – Erwin Bolwidt Feb 05 '18 at 09:58
  • I know the repository. But I want to do it with jGit – user5872256 Feb 05 '18 at 10:15
  • 1
    @user5872256 Erwin is asking you **why** you put up the *github* tag. Only use tags that really matter for your question. And for the record: you understand that **cloning** a repository basically means to **download** the complete content? git is **not** like SVN where you can (easily) do sparse checkouts and end up with just **one** single file (there is always a .git directory, that contains your **full** repository). – GhostCat Feb 05 '18 at 10:31
  • 1
    You have accepted an answer that looks like (on my phone so can’t verify) it clones and downloads the entire repository and then gives you the contents of a single file in it - let me know if I’m mistaken about that. If it’s true though, that doesn’t answer your question about downloading just a single file. – Erwin Bolwidt Feb 05 '18 at 10:50

2 Answers2

0
  1. Create an empty local git repository
  2. Add remote to the repo where the file is you want
  3. Fetch the remote repository
  4. Do a checkout addressing your file

This code is working for me:

Git git = Git.init().setDirectory(targetDirectory).call();

FetchCommand fetchCommand = git.fetch().setTransportConfigCallback((transport -> {
    SshTransport sshTransport = (SshTransport)transport;
    sshTransport.setSshSessionFactory(sshSessionFactory);
}));

RemoteAddCommand remoteAddCommand = git.remoteAdd();
remoteAddCommand.setName("fork");
remoteAddCommand.setUri(new URIish(repoUrl));
remoteAddCommand.call();

fetchCommand.setRemote("fork").setInitialBranch(branchName).setDepth(1).call();

CheckoutCommand checkoutCommand = git.checkout()
                                     .addPaths(Arrays.asList("<your file>"))
                                     .setCreateBranch(true)
                                     .setName("fork_branch")
                                     .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
                                     .setStartPoint("fork/" + branchName);
checkoutCommand.call();

workingDirectoryUtils.forceDeleteDirectory(new File(targetDirectory, "/.git"));
git.close();
KLHauser
  • 856
  • 5
  • 11
-1

you just need to walk the file tree to find file you need Here is a code sample

// Clone remote repository
CloneCommand cloneCommand = Git.cloneRepository();
cloneCommand.setDirectory(localRepository.toFile());
cloneCommand.setBare(false);
cloneCommand.setURI(remoteRepository.toString());
cloneCommand.setTransportConfigCallback(transportConfigCallback);
Repository repository = cloneCommand.call().getRepository();
ObjectId ref = repository.resolve("your commit or branch");
// Resolve commit hash
RevWalk revWalk = new RevWalk(repository);
RevCommit revCommit = revWalk.parseCommit(ref);
Commit commit = new Commit(revCommit);
TreeWalk tree = new TreeWalk(repository);
tree.addTree(revCommit.getTree());
tree.setRecursive(true);
// Set path filter, to show files on matching path
tree.setFilter(PathFilter.create("path to file"));

try (ObjectReader objectReader = repository.newObjectReader()) {
    while (tree.next()) {
        String fileName = tree.getPathString();
        byte[] fileBytes = objectReader.open(tree.getObjectId(0)).getBytes();        
    }
}
return paths;
Boris Chistov
  • 940
  • 1
  • 9
  • 16