Skip to content

Commit

Permalink
remove the impression of unexpectedness when access is denied
Browse files Browse the repository at this point in the history
If a server accessed through ssh is denying access git will currently
issue the message

	"fatal: The remote end hung up unexpectedly"

as the last line. This sounds as if something really ugly just happened.
Since this is a quite typical situation in which users regularly get
we do not say that if it happens at the beginning when reading the
remote heads.

If its in the very first beginning of reading the remote heads it is
very likely an authentication error or a missing repository.

If it happens later during reading the remote heads we still indicate
that it happened during this initial contact phase.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
hvoigt authored and gitster committed Jun 19, 2012
1 parent f174a25 commit 46284dd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 16 deletions.
18 changes: 17 additions & 1 deletion connect.c
Expand Up @@ -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
*/
Expand All @@ -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;
Expand All @@ -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')
Expand Down Expand Up @@ -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;
}
Expand Down
32 changes: 26 additions & 6 deletions pkt-line.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions pkt-line.h
Expand Up @@ -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);

Expand Down
16 changes: 7 additions & 9 deletions t/t5512-ls-remote.sh
Expand Up @@ -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 &&
Expand Down

0 comments on commit 46284dd

Please sign in to comment.