Git fork

send-pack: gracefully close the connection for atomic push

Patrick reported an issue that the exit code of git-receive-pack(1) is
ignored during atomic push with "--porcelain" flag, and added new test
cases in t5543.

This issue originated from commit 7dcbeaa0df (send-pack: fix
inconsistent porcelain output, 2020-04-17). At that time, I chose to
ignore the exit code of "finish_connect()" without investigating the
root cause of the abnormal termination of git-receive-pack. That was an
incorrect solution.

The root cause is that an atomic push operation terminates early without
sending a flush packet to git-receive-pack. As a result,
git-receive-pack continues waiting for commands without exiting. By
sending a flush packet at the appropriate location in "send_pack()", we
ensure that the git-receive-pack process closes properly, avoiding an
erroneous exit code for git-push. At the same time, revert the changes
to the "transport.c" file made in commit 7dcbeaa0df.

Reported-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Jiang Xin and committed by
Junio C Hamano
b81f8c8d 60c208db

+4 -11
+1
send-pack.c
··· 633 633 error("atomic push failed for ref %s. status: %d", 634 634 ref->name, ref->status); 635 635 ret = ERROR_SEND_PACK_BAD_REF_STATUS; 636 + packet_flush(out); 636 637 goto out; 637 638 } 638 639 /* else fallthrough */
+2 -2
t/t5543-atomic-push.sh
··· 280 280 test_cmp expect actual 281 281 ' 282 282 283 - test_expect_failure 'atomic push reports exit code failure' ' 283 + test_expect_success 'atomic push reports exit code failure' ' 284 284 write_script receive-pack-wrapper <<-\EOF && 285 285 git-receive-pack "$@" 286 286 exit 1 ··· 296 296 test_cmp expect err 297 297 ' 298 298 299 - test_expect_failure 'atomic push reports exit code failure with porcelain' ' 299 + test_expect_success 'atomic push reports exit code failure with porcelain' ' 300 300 write_script receive-pack-wrapper <<-\EOF && 301 301 git-receive-pack "$@" 302 302 exit 1
+1 -9
transport.c
··· 948 948 949 949 close(data->fd[1]); 950 950 close(data->fd[0]); 951 - /* 952 - * Atomic push may abort the connection early and close the pipe, 953 - * which may cause an error for `finish_connect()`. Ignore this error 954 - * for atomic git-push. 955 - */ 956 - if (ret || args.atomic) 957 - finish_connect(data->conn); 958 - else 959 - ret = finish_connect(data->conn); 951 + ret |= finish_connect(data->conn); 960 952 data->conn = NULL; 961 953 data->finished_handshake = 0; 962 954