If we are pushing to a remote repository the reason why we get no refs may be because push is not permitted, or it is a bad URI and points to a non-existant repository. To get a good error message for the user we need to open a fetch connection to see if fetch also fails. If it failed we know the URI is invalid; if fetch succeeds we know that the repository is there but the user is just not allowed to push to it over this transport. With this change we now get useful error messages: $ ./jgit.sh push git://repo.or.cz/egit.git refs/heads/master fatal: git://repo.or.cz/egit.git: push not permitted $ ./jgit.sh push git://repo.or.cz/fake.git refs/heads/master fatal: git://repo.or.cz/fake.git: not found. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../spearce/jgit/transport/BasePackConnection.java | 19 ++++++++------- .../jgit/transport/BasePackPushConnection.java | 25 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java index de0c7b6..e35f850 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java @@ -72,6 +72,9 @@ /** Remote repository location. */ protected final URIish uri; + /** A transport connected to {@link #uri}. */ + protected final PackTransport transport; + /** Buffered input stream reading from the remote. */ protected InputStream in; @@ -93,6 +96,7 @@ BasePackConnection(final PackTransport packTransport) { local = packTransport.local; uri = packTransport.uri; + transport = packTransport; } protected void init(final InputStream myIn, final OutputStream myOut) { @@ -129,15 +133,8 @@ private void readAdvertisedRefsImpl() throws IOException { try { line = pckIn.readString(); } catch (EOFException eof) { - if (avail.isEmpty()) { - String service = "unknown"; - if (this instanceof PushConnection) - service = "push"; - else if (this instanceof FetchConnection) - service = "fetch"; - throw new NoRemoteRepositoryException(uri, service - + " service not found."); - } + if (avail.isEmpty()) + throw noRepository(); throw eof; } @@ -185,6 +182,10 @@ else if (this instanceof FetchConnection) available(avail); } + protected TransportException noRepository() { + return new NoRemoteRepositoryException(uri, "not found."); + } + protected boolean isCapableOf(final String option) { return remoteCapablities.contains(option); } diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java index a2d5b6f..a6ab9c4 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java @@ -43,6 +43,8 @@ import java.util.Collection; import java.util.Map; +import org.spearce.jgit.errors.NoRemoteRepositoryException; +import org.spearce.jgit.errors.NotSupportedException; import org.spearce.jgit.errors.PackProtocolException; import org.spearce.jgit.errors.TransportException; import org.spearce.jgit.lib.ObjectId; @@ -98,6 +100,29 @@ public void push(final ProgressMonitor monitor, doPush(monitor, refUpdates); } + @Override + protected TransportException noRepository() { + // Sadly we cannot tell the "invalid URI" case from "push not allowed". + // Opening a fetch connection can help us tell the difference, as any + // useful repository is going to support fetch if it also would allow + // push. So if fetch throws NoRemoteRepositoryException we know the + // URI is wrong. Otherwise we can correctly state push isn't allowed + // as the fetch connection opened successfully. + // + try { + transport.openFetch().close(); + } catch (NotSupportedException e) { + // Fall through. + } catch (NoRemoteRepositoryException e) { + // Fetch concluded the repository doesn't exist. + // + return e; + } catch (TransportException e) { + // Fall through. + } + return new TransportException(uri, "push not permitted"); + } + protected void doPush(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { -- 1.6.0.174.gd789c -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html