{"thread":{"id":"30761","subject":"[PATCH] lessen the impression of unexpectedness on remote hangup","startedAt":"2012-06-10T18:23:10Z","lastAt":"2013-05-07T18:39:37Z","messageCount":13,"participants":["Heiko Voigt","Jonathan Nieder","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"193275","messageId":"20120610182310.GB2427@book.hvoigt.net","threadId":"30761","inReplyTo":null,"subject":"[PATCH] lessen the impression of unexpectedness on remote hangup","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-10T18:23:10Z","receivedAt":"2012-06-10T18:23:10Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"If a server accessed through ssh is denying access git will currently\nissue the message\n\n\t\"fatal: The remote end hung up unexpectedly\"\n\nas the last line. This sounds as if something really ugly just happened.\nSince this is a quite typical situation in which users regularly get\nlets just say:\n\n\t\"fatal: The remote end hung up\"\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\nWe just got this bug report in msysgit\n\nhttps://github.com/msysgit/msysgit/issues/28\n\nand IIRC there have been more people questioning that line.\n\n pkt-line.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/pkt-line.c b/pkt-line.c\nindex 5a04984..d2b8267 100644\n--- a/pkt-line.c\n+++ b/pkt-line.c\n@@ -141,7 +141,7 @@ static void safe_read(int fd, void *buffer, unsigned size)\n \tif (ret < 0)\n \t\tdie_errno(\"read error\");\n \telse if (ret < size)\n-\t\tdie(\"The remote end hung up unexpectedly\");\n+\t\tdie(\"The remote end hung up\");\n }\n \n static int packet_length(const char *linelen)\n-- \n1.7.11.rc2.3.g15e800d\n"},{"id":"193277","messageId":"20120610184410.GA1115@burratino","threadId":"30761","inReplyTo":"20120610182310.GB2427@book.hvoigt.net","subject":"Re: [PATCH] lessen the impression of unexpectedness on remote hangup","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-06-10T18:44:10Z","receivedAt":"2012-06-10T18:44:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nHeiko Voigt wrote:\n\n> --- a/pkt-line.c\n> +++ b/pkt-line.c\n> @@ -141,7 +141,7 @@ static void safe_read(int fd, void *buffer, unsigned size)\n>  \tif (ret < 0)\n>  \t\tdie_errno(\"read error\");\n>  \telse if (ret < size)\n> -\t\tdie(\"The remote end hung up unexpectedly\");\n> +\t\tdie(\"The remote end hung up\");\n\nLooks good.  Incidentally, maybe this would be a good excuse to\nrevisit [1].\n\nIf I remember correctly, the conclusion of that discussion was that\n--informative-errors is a good default for the git daemon as long as\n\n - there is some warning when using it without --base-path\n - there is an easy way to turn it off\n - we communicate the change clearly and in advance\n\nHope that helps,\nJonathan\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/183604\n"},{"id":"193325","messageId":"7vmx497qd5.fsf@alter.siamese.dyndns.org","threadId":"30761","inReplyTo":"20120610182310.GB2427@book.hvoigt.net","subject":"Re: [PATCH] lessen the impression of unexpectedness on remote hangup","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-11T16:41:42Z","receivedAt":"2012-06-11T16:41:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Heiko Voigt <hvoigt@hvoigt.net> writes:\n\n> If a server accessed through ssh is denying access git will currently\n> issue the message\n>\n> \t\"fatal: The remote end hung up unexpectedly\"\n>\n> as the last line. This sounds as if something really ugly just happened.\n> Since this is a quite typical situation in which users regularly get\n> lets just say:\n>\n> \t\"fatal: The remote end hung up\"\n>\n> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> ---\n\nThis change makes sense, but you would need to adjust tests for the\nchange, perhaps at least these:\n\n t/t5512-ls-remote.sh    | 2 +-\n t/t5522-pull-symlink.sh | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh\nindex 5c546c9..a24eb42 100755\n--- a/t/t5512-ls-remote.sh\n+++ b/t/t5512-ls-remote.sh\n@@ -104,7 +104,7 @@ test_expect_success 'use branch.<name>.remote if possible' '\n \n cat >exp <<EOF\n fatal: 'refs*master' does not appear to be a git repository\n-fatal: The remote end hung up unexpectedly\n+fatal: The remote end hung up\n EOF\n test_expect_success 'confuses pattern as remote when no remote specified' '\n \t#\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex 8e9b204..f06ffb4 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -46,7 +46,7 @@ test_expect_success SYMLINKS 'pulling from real subdir' '\n # Instead, the error pull gave was:\n #\n #   fatal: 'origin': unable to chdir or not a git archive\n-#   fatal: The remote end hung up unexpectedly\n+#   fatal: The remote end hung up\n #\n # because git would find the .git/config for the \"trash directory\"\n # repo, not for the clone-repo repo.  The \"trash directory\" repo\n"},{"id":"193354","messageId":"20120611190207.GA20889@sigill.intra.peff.net","threadId":"30761","inReplyTo":"20120610182310.GB2427@book.hvoigt.net","subject":"Re: [PATCH] lessen the impression of unexpectedness on remote hangup","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-06-11T19:02:07Z","receivedAt":"2012-06-11T19:02:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jun 10, 2012 at 08:23:10PM +0200, Heiko Voigt wrote:\n\n> If a server accessed through ssh is denying access git will currently\n> issue the message\n> \n> \t\"fatal: The remote end hung up unexpectedly\"\n> \n> as the last line. This sounds as if something really ugly just happened.\n> Since this is a quite typical situation in which users regularly get\n> lets just say:\n> \n> \t\"fatal: The remote end hung up\"\n> \n> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> ---\n> We just got this bug report in msysgit\n> \n> https://github.com/msysgit/msysgit/issues/28\n> \n> and IIRC there have been more people questioning that line.\n\nThis does not seem like it would lessen the surprise all that much. I\nwonder if we could use some context about where we are in the protocol\nto tell more. For example, if the remote end hangs up before advertising\nits refs, it is probably an authentication error or a missing\nrepository. And we should say that. If it happens during ref negotiation\nor during the pack file, then it really is unexpected; the other end has\nbroken protocol, and it probably makes sense to say so.\n\n-Peff\n"},{"id":"193595","messageId":"20120613212805.GA19146@book.hvoigt.net","threadId":"30761","inReplyTo":"20120611190207.GA20889@sigill.intra.peff.net","subject":"Re: [PATCH] lessen the impression of unexpectedness on remote hangup","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-13T21:28:05Z","receivedAt":"2012-06-13T21:28:05Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Mon, Jun 11, 2012 at 03:02:07PM -0400, Jeff King wrote:\n> On Sun, Jun 10, 2012 at 08:23:10PM +0200, Heiko Voigt wrote:\n> \n> > If a server accessed through ssh is denying access git will currently\n> > issue the message\n> > \n> > \t\"fatal: The remote end hung up unexpectedly\"\n> > \n> > as the last line. This sounds as if something really ugly just happened.\n> > Since this is a quite typical situation in which users regularly get\n> > lets just say:\n> > \n> > \t\"fatal: The remote end hung up\"\n> > \n> > Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> > ---\n> > We just got this bug report in msysgit\n> > \n> > https://github.com/msysgit/msysgit/issues/28\n> > \n> > and IIRC there have been more people questioning that line.\n> \n> This does not seem like it would lessen the surprise all that much. I\n> wonder if we could use some context about where we are in the protocol\n> to tell more. For example, if the remote end hangs up before advertising\n> its refs, it is probably an authentication error or a missing\n> repository. And we should say that. If it happens during ref negotiation\n> or during the pack file, then it really is unexpected; the other end has\n> broken protocol, and it probably makes sense to say so.\n\nI agree that would be better. I will have a look if I can cook something\nup. In the meantime I think changing the message is better than\nunnecessarily worrying the user.\n\nCheers Heiko\n"},{"id":"193619","messageId":"20120614071259.GA51076@book.hvoigt.net","threadId":"30761","inReplyTo":"20120611190207.GA20889@sigill.intra.peff.net","subject":"[PATCH] remove the impression of unexpectedness when access is denied","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-14T07:13:06Z","receivedAt":"2012-06-14T07:13:06Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"If a server accessed through ssh is denying access git will currently\nissue the message\n\n\t\"fatal: The remote end hung up unexpectedly\"\n\nas the last line. This sounds as if something really ugly just happened.\nSince this is a quite typical situation in which users regularly get\nlets say:\n\n\t\"fatal: Could not read remote heads\"\n\nIf it happens at the beginning when reading the remote heads. Since\nthis is the first the client does it is very likely an authentication\nerror or a missing repository.\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\nOn Mon, Jun 11, 2012 at 03:02:07PM -0400, Jeff King wrote:\n> On Sun, Jun 10, 2012 at 08:23:10PM +0200, Heiko Voigt wrote:\n> > We just got this bug report in msysgit\n> > \n> > https://github.com/msysgit/msysgit/issues/28\n> > \n> > and IIRC there have been more people questioning that line.\n> \n> This does not seem like it would lessen the surprise all that much. I\n> wonder if we could use some context about where we are in the protocol\n> to tell more. For example, if the remote end hangs up before advertising\n> its refs, it is probably an authentication error or a missing\n> repository. And we should say that. If it happens during ref negotiation\n> or during the pack file, then it really is unexpected; the other end has\n> broken protocol, and it probably makes sense to say so.\n\nThis is the shortest I was currently able to come up with. Should we\nadd an explanation to the die like:\n\n\tThis error very likely occurred because the remote repository\n\tpath is wrong or access was denied.\n\nThis time I ran the testsuite and it passes with this patch.\n\nCheers Heiko\n\n\n builtin/archive.c        |  4 ++--\n builtin/fetch-pack.c     |  8 ++++----\n builtin/receive-pack.c   |  2 +-\n builtin/send-pack.c      |  4 ++--\n builtin/upload-archive.c |  2 +-\n connect.c                | 12 +++++++++++-\n daemon.c                 |  2 +-\n pkt-line.c               | 21 +++++++++++++++------\n pkt-line.h               |  2 +-\n remote-curl.c            |  6 +++---\n sideband.c               |  2 +-\n t/t5512-ls-remote.sh     |  2 +-\n upload-pack.c            |  4 ++--\n 13 files changed, 45 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex 931956d..2e4a784 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -53,7 +53,7 @@ static int run_remote_archiver(int argc, const char **argv,\n \t\tpacket_write(fd[1], \"argument %s\\n\", argv[i]);\n \tpacket_flush(fd[1]);\n \n-\tlen = packet_read_line(fd[0], buf, sizeof(buf));\n+\tlen = packet_read_line(fd[0], buf, sizeof(buf), 0);\n \tif (!len)\n \t\tdie(_(\"git archive: expected ACK/NAK, got EOF\"));\n \tif (buf[len-1] == '\\n')\n@@ -66,7 +66,7 @@ static int run_remote_archiver(int argc, const char **argv,\n \t\tdie(_(\"git archive: protocol error\"));\n \t}\n \n-\tlen = packet_read_line(fd[0], buf, sizeof(buf));\n+\tlen = packet_read_line(fd[0], buf, sizeof(buf), 0);\n \tif (len)\n \t\tdie(_(\"git archive: expected a flush\"));\n \ndiff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c\nindex 149db88..4f0778d 100644\n--- a/builtin/fetch-pack.c\n+++ b/builtin/fetch-pack.c\n@@ -179,7 +179,7 @@ static void consume_shallow_list(int fd)\n \t\t * is a block of have lines exchanged.\n \t\t */\n \t\tchar line[1000];\n-\t\twhile (packet_read_line(fd, line, sizeof(line))) {\n+\t\twhile (packet_read_line(fd, line, sizeof(line), 0)) {\n \t\t\tif (!prefixcmp(line, \"shallow \"))\n \t\t\t\tcontinue;\n \t\t\tif (!prefixcmp(line, \"unshallow \"))\n@@ -222,7 +222,7 @@ static int write_shallow_commits(struct strbuf *out, int use_pack_protocol)\n static enum ack_type get_ack(int fd, unsigned char *result_sha1)\n {\n \tstatic char line[1000];\n-\tint len = packet_read_line(fd, line, sizeof(line));\n+\tint len = packet_read_line(fd, line, sizeof(line), 0);\n \n \tif (!len)\n \t\tdie(\"git fetch-pack: expected ACK/NAK, got EOF\");\n@@ -352,7 +352,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,\n \t\tunsigned char sha1[20];\n \n \t\tsend_request(fd[1], &req_buf);\n-\t\twhile (packet_read_line(fd[0], line, sizeof(line))) {\n+\t\twhile (packet_read_line(fd[0], line, sizeof(line), 0)) {\n \t\t\tif (!prefixcmp(line, \"shallow \")) {\n \t\t\t\tif (get_sha1_hex(line + 8, sha1))\n \t\t\t\t\tdie(\"invalid shallow line: %s\", line);\n@@ -990,7 +990,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)\n \t\t\t */\n \t\t\tstatic char line[1000];\n \t\t\tfor (;;) {\n-\t\t\t\tint n = packet_read_line(0, line, sizeof(line));\n+\t\t\t\tint n = packet_read_line(0, line, sizeof(line), 0);\n \t\t\t\tif (!n)\n \t\t\t\t\tbreak;\n \t\t\t\tif (line[n-1] == '\\n')\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 0afb8b2..2267dac 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -743,7 +743,7 @@ static struct command *read_head_info(void)\n \t\tchar *refname;\n \t\tint len, reflen;\n \n-\t\tlen = packet_read_line(0, line, sizeof(line));\n+\t\tlen = packet_read_line(0, line, sizeof(line), 0);\n \t\tif (!len)\n \t\t\tbreak;\n \t\tif (line[len-1] == '\\n')\ndiff --git a/builtin/send-pack.c b/builtin/send-pack.c\nindex d5d7105..7a8c21e 100644\n--- a/builtin/send-pack.c\n+++ b/builtin/send-pack.c\n@@ -113,7 +113,7 @@ static int receive_status(int in, struct ref *refs)\n \tstruct ref *hint;\n \tchar line[1000];\n \tint ret = 0;\n-\tint len = packet_read_line(in, line, sizeof(line));\n+\tint len = packet_read_line(in, line, sizeof(line), 0);\n \tif (len < 10 || memcmp(line, \"unpack \", 7))\n \t\treturn error(\"did not receive remote status\");\n \tif (memcmp(line, \"unpack ok\\n\", 10)) {\n@@ -127,7 +127,7 @@ static int receive_status(int in, struct ref *refs)\n \twhile (1) {\n \t\tchar *refname;\n \t\tchar *msg;\n-\t\tlen = packet_read_line(in, line, sizeof(line));\n+\t\tlen = packet_read_line(in, line, sizeof(line), 0);\n \t\tif (!len)\n \t\t\tbreak;\n \t\tif (len < 3 ||\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex b928beb..e0e4d0c 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -40,7 +40,7 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)\n \tsent_argv[0] = \"git-upload-archive\";\n \tfor (p = buf;;) {\n \t\t/* This will die if not enough free space in buf */\n-\t\tlen = packet_read_line(0, p, (buf + sizeof buf) - p);\n+\t\tlen = packet_read_line(0, p, (buf + sizeof buf) - p, 0);\n \t\tif (len == 0)\n \t\t\tbreak;\t/* got a flush */\n \t\tif (sent_argc > MAX_ARGS - 2)\ndiff --git a/connect.c b/connect.c\nindex 912cdde..19e73d5 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -56,6 +56,8 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\t\t      unsigned int flags,\n \t\t\t      struct extra_have_objects *extra_have)\n {\n+\tint got_at_least_one_head = 0;\n+\n \t*list = NULL;\n \tfor (;;) {\n \t\tstruct ref *ref;\n@@ -64,7 +66,14 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\tchar *name;\n \t\tint len, name_len;\n \n-\t\tlen = packet_read_line(in, buffer, sizeof(buffer));\n+\t\tlen = packet_read_line(in, buffer, sizeof(buffer), 1);\n+\t\tif (len < 0) {\n+\t\t\tif (got_at_least_one_head)\n+\t\t\t\tdie(\"The remote end hung up unexpectedly\");\n+\t\t\telse\n+\t\t\t\tdie(\"Could not read remote heads\");\n+\t\t}\n+\n \t\tif (!len)\n \t\t\tbreak;\n \t\tif (buffer[len-1] == '\\n')\n@@ -95,6 +104,7 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\thashcpy(ref->old_sha1, old_sha1);\n \t\t*list = ref;\n \t\tlist = &ref->next;\n+\t\tgot_at_least_one_head = 1;\n \t}\n \treturn list;\n }\ndiff --git a/daemon.c b/daemon.c\nindex ab21e66..a6bbfa4 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -539,7 +539,7 @@ static int execute(void)\n \t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n \talarm(init_timeout ? init_timeout : timeout);\n-\tpktlen = packet_read_line(0, line, sizeof(line));\n+\tpktlen = packet_read_line(0, line, sizeof(line), 0);\n \talarm(0);\n \n \tlen = strlen(line);\ndiff --git a/pkt-line.c b/pkt-line.c\nindex 5a04984..533f1f6 100644\n--- a/pkt-line.c\n+++ b/pkt-line.c\n@@ -135,13 +135,18 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)\n \tstrbuf_add(buf, buffer, n);\n }\n \n-static void safe_read(int fd, void *buffer, unsigned size)\n+static int safe_read(int fd, void *buffer, unsigned size, int return_read_fail)\n {\n \tssize_t ret = read_in_full(fd, buffer, size);\n \tif (ret < 0)\n \t\tdie_errno(\"read error\");\n \telse if (ret < size)\n-\t\tdie(\"The remote end hung up unexpectedly\");\n+\t\tif (return_read_fail)\n+\t\t\treturn -1;\n+\t\telse\n+\t\t\tdie(\"The remote end hung up unexpectedly\");\n+\n+\treturn ret;\n }\n \n static int packet_length(const char *linelen)\n@@ -169,12 +174,14 @@ static int packet_length(const char *linelen)\n \treturn len;\n }\n \n-int packet_read_line(int fd, char *buffer, unsigned size)\n+int packet_read_line(int fd, char *buffer, unsigned size, int return_read_fail)\n {\n-\tint len;\n+\tint len, ret;\n \tchar linelen[4];\n \n-\tsafe_read(fd, linelen, 4);\n+\tret = safe_read(fd, linelen, 4, return_read_fail);\n+\tif (return_read_fail && ret < 0)\n+\t\treturn ret;\n \tlen = packet_length(linelen);\n \tif (len < 0)\n \t\tdie(\"protocol error: bad line length character: %.4s\", linelen);\n@@ -185,7 +192,9 @@ int packet_read_line(int fd, char *buffer, unsigned size)\n \tlen -= 4;\n \tif (len >= size)\n \t\tdie(\"protocol error: bad line length %d\", len);\n-\tsafe_read(fd, buffer, len);\n+\tret = safe_read(fd, buffer, len, return_read_fail);\n+\tif (return_read_fail && ret < 0)\n+\t\treturn ret;\n \tbuffer[len] = 0;\n \tpacket_trace(buffer, len, 0);\n \treturn len;\ndiff --git a/pkt-line.h b/pkt-line.h\nindex 1e5dcfe..277dc9d 100644\n--- a/pkt-line.h\n+++ b/pkt-line.h\n@@ -12,7 +12,7 @@ void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2\n void packet_buf_flush(struct strbuf *buf);\n void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));\n \n-int packet_read_line(int fd, char *buffer, unsigned size);\n+int packet_read_line(int fd, char *buffer, unsigned size, int return_read_fail);\n int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);\n ssize_t safe_write(int, const void *, ssize_t);\n \ndiff --git a/remote-curl.c b/remote-curl.c\nindex 04a9d62..40f6b2d 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -314,7 +314,7 @@ static size_t rpc_out(void *ptr, size_t eltsize,\n \n \tif (!avail) {\n \t\trpc->initial_buffer = 0;\n-\t\tavail = packet_read_line(rpc->out, rpc->buf, rpc->alloc);\n+\t\tavail = packet_read_line(rpc->out, rpc->buf, rpc->alloc, 0);\n \t\tif (!avail)\n \t\t\treturn 0;\n \t\trpc->pos = 0;\n@@ -429,7 +429,7 @@ static int post_rpc(struct rpc_state *rpc)\n \t\t\tbreak;\n \t\t}\n \n-\t\tn = packet_read_line(rpc->out, buf, left);\n+\t\tn = packet_read_line(rpc->out, buf, left, 0);\n \t\tif (!n)\n \t\t\tbreak;\n \t\trpc->len += n;\n@@ -568,7 +568,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)\n \trpc->hdr_accept = strbuf_detach(&buf, NULL);\n \n \twhile (!err) {\n-\t\tint n = packet_read_line(rpc->out, rpc->buf, rpc->alloc);\n+\t\tint n = packet_read_line(rpc->out, rpc->buf, rpc->alloc, 0);\n \t\tif (!n)\n \t\t\tbreak;\n \t\trpc->pos = 0;\ndiff --git a/sideband.c b/sideband.c\nindex d5ffa1c..1e86a6b 100644\n--- a/sideband.c\n+++ b/sideband.c\n@@ -37,7 +37,7 @@ int recv_sideband(const char *me, int in_stream, int out)\n \n \twhile (1) {\n \t\tint band, len;\n-\t\tlen = packet_read_line(in_stream, buf + pf, LARGE_PACKET_MAX);\n+\t\tlen = packet_read_line(in_stream, buf + pf, LARGE_PACKET_MAX, 0);\n \t\tif (len == 0)\n \t\t\tbreak;\n \t\tif (len < 1) {\ndiff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh\nindex 6764d51..7f165ec 100755\n--- a/t/t5512-ls-remote.sh\n+++ b/t/t5512-ls-remote.sh\n@@ -87,7 +87,7 @@ test_expect_success 'use branch.<name>.remote if possible' '\n test_expect_success 'confuses pattern as remote when no remote specified' '\n \tcat >exp <<-\\EOF &&\n \tfatal: '\\''refs*master'\\'' does not appear to be a git repository\n-\tfatal: The remote end hung up unexpectedly\n+\tfatal: Could not read remote heads\n \tEOF\n \t#\n \t# Do not expect \"git ls-remote <pattern>\" to work; ls-remote, correctly,\ndiff --git a/upload-pack.c b/upload-pack.c\nindex bb08e2e..a690f63 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -426,7 +426,7 @@ static int get_common_commits(void)\n \tsave_commit_buffer = 0;\n \n \tfor (;;) {\n-\t\tint len = packet_read_line(0, line, sizeof(line));\n+\t\tint len = packet_read_line(0, line, sizeof(line), 0);\n \t\treset_timeout();\n \n \t\tif (!len) {\n@@ -587,7 +587,7 @@ static void receive_needs(void)\n \t\tstruct object *o;\n \t\tconst char *features;\n \t\tunsigned char sha1_buf[20];\n-\t\tlen = packet_read_line(0, line, sizeof(line));\n+\t\tlen = packet_read_line(0, line, sizeof(line), 0);\n \t\treset_timeout();\n \t\tif (!len)\n \t\t\tbreak;\n-- \n1.7.11.rc2.4.g4f85a3f\n"},{"id":"193622","messageId":"20120614073917.GA51232@book.hvoigt.net","threadId":"30761","inReplyTo":"20120614071259.GA51076@book.hvoigt.net","subject":"Re: [PATCH] remove the impression of unexpectedness when access is denied","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-14T07:39:17Z","receivedAt":"2012-06-14T07:39:17Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Hi,\n\nOn Thu, Jun 14, 2012 at 09:13:06AM +0200, Heiko Voigt wrote:\n> This is the shortest I was currently able to come up with.\n\nBTW, I could probably just add another function named e.g.\n\n\tpacket_read_line_allow_shorter(...\n\nand do an internal static function for handling this.\n\nCheers Heiko\n"},{"id":"193661","messageId":"7v395xg6oh.fsf@alter.siamese.dyndns.org","threadId":"30761","inReplyTo":"20120614071259.GA51076@book.hvoigt.net","subject":"Re: [PATCH] remove the impression of unexpectedness when access is denied","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-14T17:11:10Z","receivedAt":"2012-06-14T17:11:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Heiko Voigt <hvoigt@hvoigt.net> writes:\n\n> diff --git a/connect.c b/connect.c\n> index 912cdde..19e73d5 100644\n> --- a/connect.c\n> +++ b/connect.c\n> @@ -56,6 +56,8 @@ struct ref **get_remote_heads(int in, struct ref **list,\n>  \t\t\t      unsigned int flags,\n>  \t\t\t      struct extra_have_objects *extra_have)\n>  {\n> +\tint got_at_least_one_head = 0;\n> +\n>  \t*list = NULL;\n>  \tfor (;;) {\n>  \t\tstruct ref *ref;\n> @@ -64,7 +66,14 @@ struct ref **get_remote_heads(int in, struct ref **list,\n>  \t\tchar *name;\n>  \t\tint len, name_len;\n>  \n> -\t\tlen = packet_read_line(in, buffer, sizeof(buffer));\n> +\t\tlen = packet_read_line(in, buffer, sizeof(buffer), 1);\n> +\t\tif (len < 0) {\n> +\t\t\tif (got_at_least_one_head)\n> +\t\t\t\tdie(\"The remote end hung up unexpectedly\");\n> +\t\t\telse\n> +\t\t\t\tdie(\"Could not read remote heads\");\n> +\t\t}\n\nI do not think it is particularly interesting to know we have (or\nhaven't) read one packet before we got an error. It would be an\nimprovement if the message lets the user know at what stage of the\nexchange the remote threw you a garbage, but using the same \"The\nremote end hung up unexpectedly\" as all the other packet_read_line()\nerrors show makes it less useful.\n\nHow about getting rid of the new boolean variable and say\n\n\tlen = packet_read(in, buffer, sizeof(buffer));\n        if (len < 0)\n\t\tdie(\"The remote end hung up upon initial contact\");\n\nor something?\n\n>  \t\tif (!len)\n>  \t\t\tbreak;\n>  \t\tif (buffer[len-1] == '\\n')\n> @@ -95,6 +104,7 @@ struct ref **get_remote_heads(int in, struct ref **list,\n>  \t\thashcpy(ref->old_sha1, old_sha1);\n>  \t\t*list = ref;\n>  \t\tlist = &ref->next;\n> +\t\tgot_at_least_one_head = 1;\n>  \t}\n>  \treturn list;\n>  }\n\nIt seems that all callers other than this one after this patch\nbehave identically as before like this patch. It would be far more\npreferable to introduce a new function that does not die on errors\n(including but not necessarily limited to short read situation you\nare interested in this patch), and update this caller that wants to\nhandle these error cases to call that new function.  Perhaps\n\n\tlen = packet_read(in, buffer, sizeof(buffer));\n\nthat returns negative error numbers when it sees an error, with\n\n\t#define PKTREAD_UNKNOWN_ERROR (-1)\n        #define PKTREAD_SHORT_READ (-2)\n        ...\n\nand then over time we should consider converting remaining callers\nof packet_read_line() to packet_read().\n"},{"id":"193674","messageId":"20120614203712.GA51783@book.hvoigt.net","threadId":"30761","inReplyTo":"7v395xg6oh.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] remove the impression of unexpectedness when access is denied","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-14T20:37:14Z","receivedAt":"2012-06-14T20:37:14Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Hi,\n\nOn Thu, Jun 14, 2012 at 10:11:10AM -0700, Junio C Hamano wrote:\n> Heiko Voigt <hvoigt@hvoigt.net> writes:\n> \n> > diff --git a/connect.c b/connect.c\n> > index 912cdde..19e73d5 100644\n> > --- a/connect.c\n> > +++ b/connect.c\n> > @@ -56,6 +56,8 @@ struct ref **get_remote_heads(int in, struct ref **list,\n> >  \t\t\t      unsigned int flags,\n> >  \t\t\t      struct extra_have_objects *extra_have)\n> >  {\n> > +\tint got_at_least_one_head = 0;\n> > +\n> >  \t*list = NULL;\n> >  \tfor (;;) {\n> >  \t\tstruct ref *ref;\n> > @@ -64,7 +66,14 @@ struct ref **get_remote_heads(int in, struct ref **list,\n> >  \t\tchar *name;\n> >  \t\tint len, name_len;\n> >  \n> > -\t\tlen = packet_read_line(in, buffer, sizeof(buffer));\n> > +\t\tlen = packet_read_line(in, buffer, sizeof(buffer), 1);\n> > +\t\tif (len < 0) {\n> > +\t\t\tif (got_at_least_one_head)\n> > +\t\t\t\tdie(\"The remote end hung up unexpectedly\");\n> > +\t\t\telse\n> > +\t\t\t\tdie(\"Could not read remote heads\");\n> > +\t\t}\n> \n> I do not think it is particularly interesting to know we have (or\n> haven't) read one packet before we got an error. It would be an\n> improvement if the message lets the user know at what stage of the\n> exchange the remote threw you a garbage, but using the same \"The\n> remote end hung up unexpectedly\" as all the other packet_read_line()\n> errors show makes it less useful.\n\nWell I thought about the case of \"access denied\" or \"no repository\nhere\". I wanted to distinguish between this quite typical situation\nwhere you did not get anything and the situation when you already got\nsomething from the server. AFAIK its not so typical to hang up after you\ngot the first ref or is it?\n\nSo maybe something along the lines:\n\n\tif (got_at_least_one_head)\n\t\tdie(\"The remote end hung up upon initial contact\");\n\telse\n\t\tdie(\"Could not read from remote repository.\\n\"\n\t\t    \"\\nPlease make sure you have the correct access\"\n\t\t    \"rights and the repository exists.\");\n\nto give the user some suggestion what might have gone wrong?\n\nIf I understand the loop correctly it reads one remote head per\niteration doesn't it?\n\n> It seems that all callers other than this one after this patch\n> behave identically as before like this patch. It would be far more\n> preferable to introduce a new function that does not die on errors\n> (including but not necessarily limited to short read situation you\n> are interested in this patch), and update this caller that wants to\n> handle these error cases to call that new function.  Perhaps\n> \n> \tlen = packet_read(in, buffer, sizeof(buffer));\n> \n> that returns negative error numbers when it sees an error, with\n> \n> \t#define PKTREAD_UNKNOWN_ERROR (-1)\n>         #define PKTREAD_SHORT_READ (-2)\n>         ...\n> \n> and then over time we should consider converting remaining callers\n> of packet_read_line() to packet_read().\n\nYes I agree thats what I realized to late after sending the patch. Will\nimplement that in the next iteration of my patch.\n\nCheers Heiko\n"},{"id":"193855","messageId":"20120619182449.GA99957@book.hvoigt.net","threadId":"30761","inReplyTo":"20120614203712.GA51783@book.hvoigt.net","subject":"[PATCH v2] remove the impression of unexpectedness when access is denied","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2012-06-19T18:24:50Z","receivedAt":"2012-06-19T18:24:50Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"If a server accessed through ssh is denying access git will currently\nissue the message\n\n\t\"fatal: The remote end hung up unexpectedly\"\n\nas the last line. This sounds as if something really ugly just happened.\nSince this is a quite typical situation in which users regularly get\nwe do not say that if it happens at the beginning when reading the\nremote heads.\n\nIf its in the very first beginning of reading the remote heads it is\nvery likely an authentication error or a missing repository.\n\nIf it happens later during reading the remote heads we still indicate\nthat it happened during this initial contact phase.\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n connect.c            | 18 +++++++++++++++++-\n pkt-line.c           | 32 ++++++++++++++++++++++++++------\n pkt-line.h           |  1 +\n t/t5512-ls-remote.sh |  5 ++++-\n 4 files changed, 48 insertions(+), 8 deletions(-)\n\ndiff --git a/connect.c b/connect.c\nindex 912cdde..3e19d67 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1\n \textra->nr++;\n }\n \n+static void die_initial_contact(int got_at_least_one_head)\n+{\n+\tif (got_at_least_one_head)\n+\t\tdie(\"The remote end hung up upon initial contact\");\n+\telse\n+\t\tdie(\"Could not read from remote repository.\\n\\n\"\n+\t\t    \"Please make sure you have the correct access rights\\n\"\n+\t\t    \"and the repository exists.\");\n+}\n+\n /*\n  * Read all the refs from the other end\n  */\n@@ -56,6 +66,8 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\t\t      unsigned int flags,\n \t\t\t      struct extra_have_objects *extra_have)\n {\n+\tint got_at_least_one_head = 0;\n+\n \t*list = NULL;\n \tfor (;;) {\n \t\tstruct ref *ref;\n@@ -64,7 +76,10 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\tchar *name;\n \t\tint len, name_len;\n \n-\t\tlen = packet_read_line(in, buffer, sizeof(buffer));\n+\t\tlen = packet_read(in, buffer, sizeof(buffer));\n+\t\tif (len < 0)\n+\t\t\tdie_initial_contact(got_at_least_one_head);\n+\n \t\tif (!len)\n \t\t\tbreak;\n \t\tif (buffer[len-1] == '\\n')\n@@ -95,6 +110,7 @@ struct ref **get_remote_heads(int in, struct ref **list,\n \t\thashcpy(ref->old_sha1, old_sha1);\n \t\t*list = ref;\n \t\tlist = &ref->next;\n+\t\tgot_at_least_one_head = 1;\n \t}\n \treturn list;\n }\ndiff --git a/pkt-line.c b/pkt-line.c\nindex 5a04984..eaba15f 100644\n--- a/pkt-line.c\n+++ b/pkt-line.c\n@@ -135,13 +135,19 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)\n \tstrbuf_add(buf, buffer, n);\n }\n \n-static void safe_read(int fd, void *buffer, unsigned size)\n+static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail)\n {\n \tssize_t ret = read_in_full(fd, buffer, size);\n \tif (ret < 0)\n \t\tdie_errno(\"read error\");\n-\telse if (ret < size)\n+\telse if (ret < size) {\n+\t\tif (return_line_fail)\n+\t\t\treturn -1;\n+\n \t\tdie(\"The remote end hung up unexpectedly\");\n+\t}\n+\n+\treturn ret;\n }\n \n static int packet_length(const char *linelen)\n@@ -169,12 +175,14 @@ static int packet_length(const char *linelen)\n \treturn len;\n }\n \n-int packet_read_line(int fd, char *buffer, unsigned size)\n+static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail)\n {\n-\tint len;\n+\tint len, ret;\n \tchar linelen[4];\n \n-\tsafe_read(fd, linelen, 4);\n+\tret = safe_read(fd, linelen, 4, return_line_fail);\n+\tif (return_line_fail && ret < 0)\n+\t\treturn ret;\n \tlen = packet_length(linelen);\n \tif (len < 0)\n \t\tdie(\"protocol error: bad line length character: %.4s\", linelen);\n@@ -185,12 +193,24 @@ int packet_read_line(int fd, char *buffer, unsigned size)\n \tlen -= 4;\n \tif (len >= size)\n \t\tdie(\"protocol error: bad line length %d\", len);\n-\tsafe_read(fd, buffer, len);\n+\tret = safe_read(fd, buffer, len, return_line_fail);\n+\tif (return_line_fail && ret < 0)\n+\t\treturn ret;\n \tbuffer[len] = 0;\n \tpacket_trace(buffer, len, 0);\n \treturn len;\n }\n \n+int packet_read(int fd, char *buffer, unsigned size)\n+{\n+\treturn packet_read_internal(fd, buffer, size, 1);\n+}\n+\n+int packet_read_line(int fd, char *buffer, unsigned size)\n+{\n+\treturn packet_read_internal(fd, buffer, size, 0);\n+}\n+\n int packet_get_line(struct strbuf *out,\n \tchar **src_buf, size_t *src_len)\n {\ndiff --git a/pkt-line.h b/pkt-line.h\nindex 1e5dcfe..8cfeb0c 100644\n--- a/pkt-line.h\n+++ b/pkt-line.h\n@@ -13,6 +13,7 @@ void packet_buf_flush(struct strbuf *buf);\n void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));\n \n int packet_read_line(int fd, char *buffer, unsigned size);\n+int packet_read(int fd, char *buffer, unsigned size);\n int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);\n ssize_t safe_write(int, const void *, ssize_t);\n \ndiff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh\nindex 6764d51..2af5c2a 100755\n--- a/t/t5512-ls-remote.sh\n+++ b/t/t5512-ls-remote.sh\n@@ -87,7 +87,10 @@ test_expect_success 'use branch.<name>.remote if possible' '\n test_expect_success 'confuses pattern as remote when no remote specified' '\n \tcat >exp <<-\\EOF &&\n \tfatal: '\\''refs*master'\\'' does not appear to be a git repository\n-\tfatal: The remote end hung up unexpectedly\n+\tfatal: Could not read from remote repository.\n+\n+\tPlease make sure you have the correct access rights\n+\tand the repository exists.\n \tEOF\n \t#\n \t# Do not expect \"git ls-remote <pattern>\" to work; ls-remote, correctly,\n-- \n1.7.11.rc2.3.g49b071d\n"},{"id":"216398","messageId":"20130504031001.GA3734@elie.Belkin","threadId":"30761","inReplyTo":"20120619182449.GA99957@book.hvoigt.net","subject":"Re: [PATCH v2] remove the impression of unexpectedness when access is denied","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2013-05-04T03:10:01Z","receivedAt":"2013-05-04T03:10:01Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nHeiko Voigt wrote:\n\n> --- a/connect.c\n> +++ b/connect.c\n> @@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1\n>  \textra->nr++;\n>  }\n>  \n> +static void die_initial_contact(int got_at_least_one_head)\n> +{\n> +\tif (got_at_least_one_head)\n> +\t\tdie(\"The remote end hung up upon initial contact\");\n> +\telse\n> +\t\tdie(\"Could not read from remote repository.\\n\\n\"\n> +\t\t    \"Please make sure you have the correct access rights\\n\"\n> +\t\t    \"and the repository exists.\");\n> +}\n[...]\n\nI ran into this message for the first time today.\n\n $ git fetch --all\n Fetching origin\n remote: Counting objects: 368, done.\n[...]\n Fetching gitk\n fatal: Could not read from remote repository.\n\n Please make sure you have the correct access rights\n and the repository exists.\n error: Could not fetch gitk\n Fetching debian\n Fetching pape\n[...]\n\nThe \"gitk\" remote refers to git://git.kernel.org/pub/scm/gitk/gitk.\nUsing ls-remote to contact it produces the same result.  The message\nis correct: the repository does not exist.\n\nImpressions:\n\n * Looking at \"Could not read\", it is not clear what could not read\n   and why.  GIT_TRACE_PACKET tells me the interaction was\n\n\tme> git-upload-pack /pub/scm/gitk/gitk\\0host=git.kernel.org\\0\n\tthem> (hangup)\n\n   Would it make sense for the server to send an \"ERR\" packet to give\n   a more helpful diagnosis?\n\n * The spacing and capitalization is odd and makes it not flow well\n   with the rest of the output.  I suspect it would be easier to read\n   with the error separated from hints:\n\n\tFetching gitk\n\tfatal: the remote server sent an empty response\n\thint: does the repository exist?\n\thint: do you have the correct access rights?\n\terror: Could not fetch gitk\n\tFetching debian\n\n   If a server is misconfigured and just decides to send an empty\n   response for no good reason, the output would still be true.\n\n * The error message is the same whether the server returned no\n   response or an incomplete pkt-line.  Maybe in the latter case it\n   should print the \"hung up unexpectedly\" thing.\n\nThoughts?\n\nJonathan\n"},{"id":"216496","messageId":"7vr4hktddq.fsf@alter.siamese.dyndns.org","threadId":"30761","inReplyTo":"20130504031001.GA3734@elie.Belkin","subject":"Re: [PATCH v2] remove the impression of unexpectedness when access is denied","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-06T14:02:41Z","receivedAt":"2013-05-06T14:02:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> I ran into this message for the first time today.\n>\n>  $ git fetch --all\n>  Fetching origin\n>  remote: Counting objects: 368, done.\n> [...]\n>  Fetching gitk\n>  fatal: Could not read from remote repository.\n>\n>  Please make sure you have the correct access rights\n>  and the repository exists.\n>  error: Could not fetch gitk\n>  Fetching debian\n>  Fetching pape\n> [...]\n>\n> The \"gitk\" remote refers to git://git.kernel.org/pub/scm/gitk/gitk.\n> Using ls-remote to contact it produces the same result.  The message\n> is correct: the repository does not exist.\n>\n> Impressions:\n>\n>  * Looking at \"Could not read\", it is not clear what could not read\n>    and why.  GIT_TRACE_PACKET tells me the interaction was\n>\n> \tme> git-upload-pack /pub/scm/gitk/gitk\\0host=git.kernel.org\\0\n> \tthem> (hangup)\n>\n>    Would it make sense for the server to send an \"ERR\" packet to give\n>    a more helpful diagnosis?\n\nI think git-daemon does so (or at least attempts to do so);\npath_ok() uses enter_repo() to check if the given path is a\nrepository, returns NULL to run_service(), whichh in turn calls\ndaemon_error() that does the ERR thing.\n\n>  * The spacing and capitalization is odd and makes it not flow well\n>    with the rest of the output.  I suspect it would be easier to read\n>    with the error separated from hints:\n>\n> \tFetching gitk\n> \tfatal: the remote server sent an empty response\n> \thint: does the repository exist?\n> \thint: do you have the correct access rights?\n> \terror: Could not fetch gitk\n> \tFetching debian\n>\n>    If a server is misconfigured and just decides to send an empty\n>    response for no good reason, the output would still be true.\n\nIt does sound better. Also s/Could not fetch/could not fetch/.\n\n>  * The error message is the same whether the server returned no\n>    response or an incomplete pkt-line.  Maybe in the latter case it\n>    should print the \"hung up unexpectedly\" thing.\n\nOK.\n"},{"id":"216632","messageId":"20130507183937.GA5776@sigill.intra.peff.net","threadId":"30761","inReplyTo":"7vr4hktddq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2] remove the impression of unexpectedness when access is denied","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-05-07T18:39:37Z","receivedAt":"2013-05-07T18:39:37Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, May 06, 2013 at 07:02:41AM -0700, Junio C Hamano wrote:\n\n> >    Would it make sense for the server to send an \"ERR\" packet to give\n> >    a more helpful diagnosis?\n> \n> I think git-daemon does so (or at least attempts to do so);\n> path_ok() uses enter_repo() to check if the given path is a\n> repository, returns NULL to run_service(), whichh in turn calls\n> daemon_error() that does the ERR thing.\n\nYeah, that went into v1.7.8. Do we have any simple way to find out which\nversion kernel.org is running? They should probably also turn on the\n--informative-errors option, as they do not (AFAIK) have any private\nrepos whose information could be leaked by better error messages.\n\nIf they are running v1.7.8 and it is not producing an ERR message, then\nI think there is a bug.\n\n> >  * The error message is the same whether the server returned no\n> >    response or an incomplete pkt-line.  Maybe in the latter case it\n> >    should print the \"hung up unexpectedly\" thing.\n> \n> OK.\n\nI made a stab at this some time ago:\n\n  http://article.gmane.org/gmane.comp.version-control.git/112189\n\nThere were some follow-up comments, and I remember trying to make\nsomething work with processing remote stderr, but running into\ncomplications. Alas, I don't remember any more details than that. But\nmaybe it helps.\n\n-Peff\n"}]}