diff options
-rw-r--r-- | connect.c | 18 | ||||
-rw-r--r-- | pkt-line.c | 32 | ||||
-rw-r--r-- | pkt-line.h | 1 | ||||
-rwxr-xr-x | t/t5512-ls-remote.sh | 16 |
4 files changed, 51 insertions, 16 deletions
@@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1 extra->nr++; } +static void die_initial_contact(int got_at_least_one_head) +{ + if (got_at_least_one_head) + die("The remote end hung up upon initial contact"); + else + die("Could not read from remote repository.\n\n" + "Please make sure you have the correct access rights\n" + "and the repository exists."); +} + /* * Read all the refs from the other end */ @@ -57,6 +67,8 @@ struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *extra_have) { + int got_at_least_one_head = 0; + *list = NULL; for (;;) { struct ref *ref; @@ -65,7 +77,10 @@ struct ref **get_remote_heads(int in, struct ref **list, char *name; int len, name_len; - len = packet_read_line(in, buffer, sizeof(buffer)); + len = packet_read(in, buffer, sizeof(buffer)); + if (len < 0) + die_initial_contact(got_at_least_one_head); + if (!len) break; if (buffer[len-1] == '\n') @@ -98,6 +113,7 @@ struct ref **get_remote_heads(int in, struct ref **list, hashcpy(ref->old_sha1, old_sha1); *list = ref; list = &ref->next; + got_at_least_one_head = 1; } return list; } diff --git a/pkt-line.c b/pkt-line.c index 5a04984ea3..eaba15f124 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -135,13 +135,19 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...) strbuf_add(buf, buffer, n); } -static void safe_read(int fd, void *buffer, unsigned size) +static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail) { ssize_t ret = read_in_full(fd, buffer, size); if (ret < 0) die_errno("read error"); - else if (ret < size) + else if (ret < size) { + if (return_line_fail) + return -1; + die("The remote end hung up unexpectedly"); + } + + return ret; } static int packet_length(const char *linelen) @@ -169,12 +175,14 @@ static int packet_length(const char *linelen) return len; } -int packet_read_line(int fd, char *buffer, unsigned size) +static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail) { - int len; + int len, ret; char linelen[4]; - safe_read(fd, linelen, 4); + ret = safe_read(fd, linelen, 4, return_line_fail); + if (return_line_fail && ret < 0) + return ret; len = packet_length(linelen); if (len < 0) die("protocol error: bad line length character: %.4s", linelen); @@ -185,12 +193,24 @@ int packet_read_line(int fd, char *buffer, unsigned size) len -= 4; if (len >= size) die("protocol error: bad line length %d", len); - safe_read(fd, buffer, len); + ret = safe_read(fd, buffer, len, return_line_fail); + if (return_line_fail && ret < 0) + return ret; buffer[len] = 0; packet_trace(buffer, len, 0); return len; } +int packet_read(int fd, char *buffer, unsigned size) +{ + return packet_read_internal(fd, buffer, size, 1); +} + +int packet_read_line(int fd, char *buffer, unsigned size) +{ + return packet_read_internal(fd, buffer, size, 0); +} + int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len) { diff --git a/pkt-line.h b/pkt-line.h index 1e5dcfe87c..8cfeb0c31c 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -13,6 +13,7 @@ void packet_buf_flush(struct strbuf *buf); void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); int packet_read_line(int fd, char *buffer, unsigned size); +int packet_read(int fd, char *buffer, unsigned size); int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len); ssize_t safe_write(int, const void *, ssize_t); diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 5c546c99a5..2ab66d6e33 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -104,18 +104,16 @@ test_expect_success 'use branch.<name>.remote if possible' ' cat >exp <<EOF fatal: 'refs*master' does not appear to be a git repository -fatal: The remote end hung up unexpectedly +fatal: Could not read from remote repository. + +Please make sure you have the correct access rights +and the repository exists. EOF test_expect_success 'confuses pattern as remote when no remote specified' ' # - # Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly, - # confuses <pattern> for <remote>. Although ugly, this behaviour is akin - # to the confusion of refspecs for remotes by git-fetch and git-push, - # eg: - # - # $ git fetch branch - # - + # Do not expect "git ls-remote <pattern>" to work; ls-remote needs + # <remote> if you want to feed <pattern>, just like you cannot say + # fetch <branch>. # We could just as easily have used "master"; the "*" emphasizes its # role as a pattern. test_must_fail git ls-remote refs*master >actual 2>&1 && |