Git fetch crashes when using jgit: remote does not have <branchname> available for extraction
I have a bare repo located in main.git and I am trying to get the branch ( foo , say) in another repo, test , which just had git init 'd:
fetchtest/ |- main.git/ |- test/ |- .git/ Using regular git commands, I can do git fetch ../main.git foo:foo and this will make a new branch foo in test/ and extract the objects needed for the branch. Then I want to do the same thing, but programmatically using JGit, that is, not using the CLI git, but using only Java code. I can not use git CLI:
Git git = Git.init().setDirectory(new File("fetchtest/test/")).call(); git.fetch().setRemote(new File("../main.git")) .setRefSpecs(new RefSpec("foo:foo")) .call(); but these are just errors with:
org.eclipse.jgit.api.errors.TransportException: Remote does not have foo available for fetch. at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:137) // ...... Caused by: org.eclipse.jgit.errors.TransportException: Remote does not have foo available for fetch. at org.eclipse.jgit.transport.FetchProcess.expandSingle(FetchProcess.java:349) at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:139) at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:113) at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1069) at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128) How do I make this work?
What should work:
Git git = Git.init().setDirectory(new File("fetchtest/test/")).call(); git.fetch().setRemote(new File("../main.git")) .setRefSpecs(new RefSpec("refs/heads/foo:refs/heads/foo")) .call(); Pay attention to the definition of RefSpec .
At least try in your example:
new RefSpec("refs/heads/foo:refs/heads/foo") RefSpec class mentions:
/** * Parse a ref specification for use during transport operations. * <p> * Specifications are typically one of the following forms: * <ul> * <li><code>refs/head/master</code></li> * <li><code>refs/head/master:refs/remotes/origin/master</code></li> * <li><code>refs/head/*:refs/remotes/origin/*</code></li> * <li><code>+refs/head/master</code></li> * <li><code>+refs/head/master:refs/remotes/origin/master</code></li> * <li><code>+refs/head/*:refs/remotes/origin/*</code></li> * <li><code>:refs/head/master</code></li> * </ul> * * @param spec * string describing the specification. * @throws IllegalArgumentException * the specification is invalid. */ So, " refs/head/ " seems mandatory.
Original answer:
The setRemote() function on api.FetchCommand accepts a name or URI.
And looking at the definition of FetchCommandTest , I prefer to make the remote more visible:
I would prefer to define a named remote (here below: " test ") for your second repo (with a link to your first repo), and then select.
// setup the first repository to fetch from the second repository final StoredConfig config = db.getConfig(); RemoteConfig remoteConfig = new RemoteConfig(config, "test"); URIish uri = new URIish(db2.getDirectory().toURI().toURL()); remoteConfig.addURI(uri); remoteConfig.update(config); config.save(); // create some refs via commits and tag RevCommit commit = git2.commit().setMessage("initial commit").call(); Ref tagRef = git2.tag().setName("tag").call(); Git git1 = new Git(db); RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x"); git1.fetch().setRemote("test").setRefSpecs(spec) .call(); Sometimes Eclipse does not understand the changes until you create your changes. If there are any errors in your project, Eclipse will not create such a project. Make sure you create a project that uses Git and try to resolve any errors in the build path. I do not know about Git, but this seems like an update problem. Try and let me know if this solves your problem or not.