aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Xin <zhiyou.jx@alibaba-inc.com>2025-02-03 07:29:38 +0100
committerJunio C Hamano <gitster@pobox.com>2025-02-03 15:24:58 -0800
commitb81f8c8dd3ec81a8d622e2d3d6b2af426ca53f05 (patch)
tree756d9f9f158c11f81d63289462b004996e4305fa
parentt5543: atomic push reports exit code failure (diff)
downloadgit-b81f8c8dd3ec81a8d622e2d3d6b2af426ca53f05.tar.gz
git-b81f8c8dd3ec81a8d622e2d3d6b2af426ca53f05.zip
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>
-rw-r--r--send-pack.c1
-rwxr-xr-xt/t5543-atomic-push.sh4
-rw-r--r--transport.c10
3 files changed, 4 insertions, 11 deletions
diff --git a/send-pack.c b/send-pack.c
index 4448c081cc..856a65d5f5 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -633,6 +633,7 @@ int send_pack(struct repository *r,
error("atomic push failed for ref %s. status: %d",
ref->name, ref->status);
ret = ERROR_SEND_PACK_BAD_REF_STATUS;
+ packet_flush(out);
goto out;
}
/* else fallthrough */
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 32181b9afb..3a700b0676 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -280,7 +280,7 @@ test_expect_success 'atomic push reports (reject by non-ff)' '
test_cmp expect actual
'
-test_expect_failure 'atomic push reports exit code failure' '
+test_expect_success 'atomic push reports exit code failure' '
write_script receive-pack-wrapper <<-\EOF &&
git-receive-pack "$@"
exit 1
@@ -296,7 +296,7 @@ test_expect_failure 'atomic push reports exit code failure' '
test_cmp expect err
'
-test_expect_failure 'atomic push reports exit code failure with porcelain' '
+test_expect_success 'atomic push reports exit code failure with porcelain' '
write_script receive-pack-wrapper <<-\EOF &&
git-receive-pack "$@"
exit 1
diff --git a/transport.c b/transport.c
index d064aff33e..b0c6c339f4 100644
--- a/transport.c
+++ b/transport.c
@@ -948,15 +948,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
close(data->fd[1]);
close(data->fd[0]);
- /*
- * Atomic push may abort the connection early and close the pipe,
- * which may cause an error for `finish_connect()`. Ignore this error
- * for atomic git-push.
- */
- if (ret || args.atomic)
- finish_connect(data->conn);
- else
- ret = finish_connect(data->conn);
+ ret |= finish_connect(data->conn);
data->conn = NULL;
data->finished_handshake = 0;