remove the impression of unexpectedness when access is denied
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>
Heiko Voigt committed
Jun 19, 2012 at 20:24 UTC
46284dd1528d7bff53a4ef7c398648da91ea0842
4 files changed
+51
-16
connect.c
+17
-1
@@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1
49
extra->nr++;
50
}
51
52
+static void die_initial_contact(int got_at_least_one_head)
53
+{
54
+ if (got_at_least_one_head)
55
+ die("The remote end hung up upon initial contact");
56
+ else
57
+ die("Could not read from remote repository.\n\n"
58
+ "Please make sure you have the correct access rights\n"
59
+ "and the repository exists.");
60
+}
61
+
62
/*
63
* Read all the refs from the other end
64
*/
@@ -57,6 +67,8 @@ struct ref **get_remote_heads(int in, struct ref **list,
67
unsigned int flags,
68
struct extra_have_objects *extra_have)
69
{
70
+ int got_at_least_one_head = 0;
71
+
72
*list = NULL;
73
for (;;) {
74
struct ref *ref;
@@ -65,7 +77,10 @@ struct ref **get_remote_heads(int in, struct ref **list,
77
char *name;
78
int len, name_len;
79
68
- len = packet_read_line(in, buffer, sizeof(buffer));
80
+ len = packet_read(in, buffer, sizeof(buffer));
81
+ if (len < 0)
82
+ die_initial_contact(got_at_least_one_head);
83
+
84
if (!len)
85
break;
86
if (buffer[len-1] == '\n')
@@ -98,6 +113,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
113
hashcpy(ref->old_sha1, old_sha1);
114
*list = ref;
115
list = &ref->next;
116
+ got_at_least_one_head = 1;
117
}
118
return list;
119
}
pkt-line.c
+26
-6
@@ -135,13 +135,19 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
135
strbuf_add(buf, buffer, n);
136
}
137
138
-static void safe_read(int fd, void *buffer, unsigned size)
138
+static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail)
139
{
140
ssize_t ret = read_in_full(fd, buffer, size);
141
if (ret < 0)
142
die_errno("read error");
143
- else if (ret < size)
143
+ else if (ret < size) {
144
+ if (return_line_fail)
145
+ return -1;
146
+
147
die("The remote end hung up unexpectedly");
148
+ }
149
+
150
+ return ret;
151
}
152
153
static int packet_length(const char *linelen)
@@ -169,12 +175,14 @@ static int packet_length(const char *linelen)
175
return len;
176
}
177
172
-int packet_read_line(int fd, char *buffer, unsigned size)
178
+static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail)
179
{
174
- int len;
180
+ int len, ret;
181
char linelen[4];
182
177
- safe_read(fd, linelen, 4);
183
+ ret = safe_read(fd, linelen, 4, return_line_fail);
184
+ if (return_line_fail && ret < 0)
185
+ return ret;
186
len = packet_length(linelen);
187
if (len < 0)
188
die("protocol error: bad line length character: %.4s", linelen);
@@ -185,12 +193,24 @@ int packet_read_line(int fd, char *buffer, unsigned size)
193
len -= 4;
194
if (len >= size)
195
die("protocol error: bad line length %d", len);
188
- safe_read(fd, buffer, len);
196
+ ret = safe_read(fd, buffer, len, return_line_fail);
197
+ if (return_line_fail && ret < 0)
198
+ return ret;
199
buffer[len] = 0;
200
packet_trace(buffer, len, 0);
201
return len;
202
}
203
204
+int packet_read(int fd, char *buffer, unsigned size)
205
+{
206
+ return packet_read_internal(fd, buffer, size, 1);
207
+}
208
+
209
+int packet_read_line(int fd, char *buffer, unsigned size)
210
+{
211
+ return packet_read_internal(fd, buffer, size, 0);
212
+}
213
+
214
int packet_get_line(struct strbuf *out,
215
char **src_buf, size_t *src_len)
216
{
pkt-line.h
+1
@@ -13,6 +13,7 @@ void packet_buf_flush(struct strbuf *buf);
13
void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
14
15
int packet_read_line(int fd, char *buffer, unsigned size);
16
+int packet_read(int fd, char *buffer, unsigned size);
17
int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);
18
ssize_t safe_write(int, const void *, ssize_t);
19
t/t5512-ls-remote.sh
+7
-9
@@ -104,18 +104,16 @@ test_expect_success 'use branch.<name>.remote if possible' '
104
105
cat >exp <<EOF
106
fatal: 'refs*master' does not appear to be a git repository
107
-fatal: The remote end hung up unexpectedly
107
+fatal: Could not read from remote repository.
108
+
109
+Please make sure you have the correct access rights
110
+and the repository exists.
111
EOF
112
test_expect_success 'confuses pattern as remote when no remote specified' '
113
#
111
- # Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly,
112
- # confuses <pattern> for <remote>. Although ugly, this behaviour is akin
113
- # to the confusion of refspecs for remotes by git-fetch and git-push,
114
- # eg:
115
- #
116
- # $ git fetch branch
117
- #
118
-
114
+ # Do not expect "git ls-remote <pattern>" to work; ls-remote needs
115
+ # <remote> if you want to feed <pattern>, just like you cannot say
116
+ # fetch <branch>.
117
# We could just as easily have used "master"; the "*" emphasizes its
118
# role as a pattern.
119
test_must_fail git ls-remote refs*master >actual 2>&1 &&