summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xt/t5530-upload-pack-error.sh17
-rw-r--r--upload-pack.c13
2 files changed, 29 insertions, 1 deletions
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh
index 205a2631e7..9dd2d2457a 100755
--- a/t/t5530-upload-pack-error.sh
+++ b/t/t5530-upload-pack-error.sh
@@ -88,6 +88,23 @@ test_expect_success 'upload-pack fails due to error in pack-objects enumeration'
grep "pack-objects died" output.err
'
+test_expect_success 'upload-pack tolerates EOF just after stateless client wants' '
+ test_commit initial &&
+ head=$(git rev-parse HEAD) &&
+
+ {
+ packetize "want $head" &&
+ packetize "shallow $head" &&
+ packetize "deepen 1" &&
+ printf "0000"
+ } >request &&
+
+ printf "0000" >expect &&
+
+ git upload-pack --stateless-rpc . <request >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'create empty repository' '
mkdir foo &&
diff --git a/upload-pack.c b/upload-pack.c
index 3b858eb457..5dc8e1f844 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -1344,7 +1344,18 @@ void upload_pack(struct upload_pack_options *options)
PACKET_READ_DIE_ON_ERR_PACKET);
receive_needs(&data, &reader);
- if (data.want_obj.nr) {
+
+ /*
+ * An EOF at this exact point in negotiation should be
+ * acceptable from stateless clients as they will consume the
+ * shallow list before doing subsequent rpc with haves/etc.
+ */
+ if (data.stateless_rpc)
+ reader.options |= PACKET_READ_GENTLE_ON_EOF;
+
+ if (data.want_obj.nr &&
+ packet_reader_peek(&reader) != PACKET_READ_EOF) {
+ reader.options &= ~PACKET_READ_GENTLE_ON_EOF;
get_common_commits(&data, &reader);
create_pack_file(&data, NULL);
}