Merge branch 'hv/remote-end-hung-up'

When we get disconnected while expecting a response from the remote
side because authentication failed, we issued an error message "The
remote side hung up unexpectedly."

Give hint that it may be a permission problem in the message when we
can reasonably suspect it.

* hv/remote-end-hung-up:
  remove the impression of unexpectedness when access is denied
This commit is contained in:
Junio C Hamano 2012-07-04 23:40:11 -07:00
commit 348c44e78e
4 changed files with 51 additions and 16 deletions

View File

@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1
extra->nr++; 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 * Read all the refs from the other end
*/ */
@ -56,6 +66,8 @@ struct ref **get_remote_heads(int in, struct ref **list,
unsigned int flags, unsigned int flags,
struct extra_have_objects *extra_have) struct extra_have_objects *extra_have)
{ {
int got_at_least_one_head = 0;
*list = NULL; *list = NULL;
for (;;) { for (;;) {
struct ref *ref; struct ref *ref;
@ -64,7 +76,10 @@ struct ref **get_remote_heads(int in, struct ref **list,
char *name; char *name;
int len, name_len; 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) if (!len)
break; break;
if (buffer[len-1] == '\n') if (buffer[len-1] == '\n')
@ -95,6 +110,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
hashcpy(ref->old_sha1, old_sha1); hashcpy(ref->old_sha1, old_sha1);
*list = ref; *list = ref;
list = &ref->next; list = &ref->next;
got_at_least_one_head = 1;
} }
return list; return list;
} }

View File

@ -135,13 +135,19 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
strbuf_add(buf, buffer, n); 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); ssize_t ret = read_in_full(fd, buffer, size);
if (ret < 0) if (ret < 0)
die_errno("read error"); 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"); die("The remote end hung up unexpectedly");
}
return ret;
} }
static int packet_length(const char *linelen) static int packet_length(const char *linelen)
@ -169,12 +175,14 @@ static int packet_length(const char *linelen)
return len; 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]; 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); len = packet_length(linelen);
if (len < 0) if (len < 0)
die("protocol error: bad line length character: %.4s", linelen); 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; len -= 4;
if (len >= size) if (len >= size)
die("protocol error: bad line length %d", len); 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; buffer[len] = 0;
packet_trace(buffer, len, 0); packet_trace(buffer, len, 0);
return len; 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, int packet_get_line(struct strbuf *out,
char **src_buf, size_t *src_len) char **src_buf, size_t *src_len)
{ {

View File

@ -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))); 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_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); int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);
ssize_t safe_write(int, const void *, ssize_t); ssize_t safe_write(int, const void *, ssize_t);

View File

@ -87,17 +87,15 @@ test_expect_success 'use branch.<name>.remote if possible' '
test_expect_success 'confuses pattern as remote when no remote specified' ' test_expect_success 'confuses pattern as remote when no remote specified' '
cat >exp <<-\EOF && cat >exp <<-\EOF &&
fatal: '\''refs*master'\'' does not appear to be a git repository 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 EOF
# #
# Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly, # Do not expect "git ls-remote <pattern>" to work; ls-remote needs
# confuses <pattern> for <remote>. Although ugly, this behaviour is akin # <remote> if you want to feed <pattern>, just like you cannot say
# to the confusion of refspecs for remotes by git-fetch and git-push, # fetch <branch>.
# eg:
#
# $ git fetch branch
#
# We could just as easily have used "master"; the "*" emphasizes its # We could just as easily have used "master"; the "*" emphasizes its
# role as a pattern. # role as a pattern.
test_must_fail git ls-remote refs*master >actual 2>&1 && test_must_fail git ls-remote refs*master >actual 2>&1 &&