diff --git a/CHANGELOG.md b/CHANGELOG.md index 810538c64..8a0ae0e03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,10 @@ support for HTTPS connections insead of OpenSSL. * The index now uses diffs for `add_all()` and `update_all()` which gives it a speed boost and closer semantics to git. +* The ssh transport now reports the stderr output from the server as + the error message, which allows you to get the "repository not + found" messages. + ### API additions @@ -89,6 +93,11 @@ support for HTTPS connections insead of OpenSSL. * `git_stash_pop()` will apply a stashed state (like `git_stash_apply()`) but will remove the stashed state after a successful application. +* A new error code `GIT_EEOF` indicates an early EOF from the + server. This typically indicates an error with the URL or + configuration of the server, and tools can use this to show messages + about failing to communicate with the server. + ### API removals * `git_remote_save()` and `git_remote_clear_refspecs()` has been diff --git a/include/git2/errors.h b/include/git2/errors.h index ef4fabb7d..31fc6035a 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -45,6 +45,7 @@ typedef enum { GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */ GIT_EAPPLIED = -18, /**< Patch/merge has already been applied */ GIT_EPEEL = -19, /**< The requested peel operation is not possible */ + GIT_EEOF = -20, /**< Unexpected EOF */ GIT_PASSTHROUGH = -30, /**< Internal only */ GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */ diff --git a/src/openssl_stream.c b/src/openssl_stream.c index 2ebfac738..78f705e49 100644 --- a/src/openssl_stream.c +++ b/src/openssl_stream.c @@ -55,6 +55,7 @@ static int ssl_set_error(SSL *ssl, int error) break; } giterr_set(GITERR_NET, "SSL error: received early EOF"); + return GIT_EEOF; break; case SSL_ERROR_SSL: e = ERR_get_error(); diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 66f78f73c..0920f2eef 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -52,7 +52,7 @@ int git_smart__store_refs(transport_smart *t, int flushes) if (recvd == 0 && !flush) { giterr_set(GITERR_NET, "early EOF"); - return -1; + return GIT_EEOF; } continue; @@ -770,7 +770,7 @@ static int parse_report(transport_smart *transport, git_push *push) if (recvd == 0) { giterr_set(GITERR_NET, "early EOF"); - return -1; + return GIT_EEOF; } continue; } diff --git a/src/transports/ssh.c b/src/transports/ssh.c index c5b081151..55f715b1d 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -125,10 +125,21 @@ static int ssh_stream_read( return -1; if ((rc = libssh2_channel_read(s->channel, buffer, buf_size)) < LIBSSH2_ERROR_NONE) { - ssh_error(s->session, "SSH could not read data");; + ssh_error(s->session, "SSH could not read data"); return -1; } + /* + * If we can't get anything out of stdout, it's typically a + * not-found error, so read from stderr and signal EOF on + * stderr. + */ + if (rc == 0 && (rc = libssh2_channel_read_stderr(s->channel, buffer, buf_size)) > 0) { + giterr_set(GITERR_SSH, "%*s", rc, buffer); + return GIT_EEOF; + } + + *bytes_read = rc; return 0;