Commit Diff


commit - 64592dff718689c4fb441b52d2b38e8db90089ba
commit + 8e92c55c71ddc358748f608f316cbc53b008f79f
blob - 22c03b9ec660bcf589b5ba045f5c6e3d68a9b5eb
blob + 2606f615bc7170cc9db0d474f7169f2f09784c7a
--- gotd/session.c
+++ gotd/session.c
@@ -1043,6 +1043,17 @@ session_dispatch_client(int fd, short events, void *ar
 		if (err) {
 			if (err->code == GOT_ERR_PRIVSEP_READ)
 				err = NULL;
+			else if (err->code == GOT_ERR_EOF &&
+			    client->state == GOTD_STATE_EXPECT_CAPABILITIES) {
+				/*
+				 * The client has closed its socket before
+				 * sending its capability announcement.
+				 * This can happen when Git clients have
+				 * no ref-updates to send.
+				 */
+				disconnect_on_error(client, err);
+				return;
+			}
 			break;
 		}
 
blob - 340896dbcc22a207db8373da81afa58055c86128
blob + a8dc573fbe5efb0c2de972bc04d6784afba0e705
--- lib/serve.c
+++ lib/serve.c
@@ -1268,7 +1268,10 @@ serve_write(int infd, int outfd, int gotd_sock, const 
 		if (err)
 			goto done;
 		if (n == 0) {
-			if (curstate != STATE_EXPECT_MORE_REF_UPDATES) {
+			if (curstate == STATE_EXPECT_REF_UPDATE) {
+				/* The client will not send us anything. */
+				goto done;
+			} else if (curstate != STATE_EXPECT_MORE_REF_UPDATES) {
 				err = got_error_msg(GOT_ERR_BAD_PACKET,
 				    "unexpected flush packet received");
 				goto done;
blob - daff924b47ca360160665215790f700bf0f8bfda
blob + 4ae6fbc520b21e761719a82232e309e8e3747239
--- regress/gotd/repo_write.sh
+++ regress/gotd/repo_write.sh
@@ -108,6 +108,16 @@ EOF
 	ret=$?
 	if [ $ret -ne 0 ]; then
 		echo "git pull failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	# Verify that git push reports no changes to send and no error.
+	(cd $testroot/repo-clone3 && git push -q > $testroot/stdout \
+		2> $testroot/stderr)
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "git push failed unexpectedly" >&2
 		test_done "$testroot" "1"
 		return 1
 	fi