Skip to content

Commit

Permalink
remote-curl: Fix push status report when all branches fail
Browse files Browse the repository at this point in the history
The protocol between transport-helper.c and remote-curl requires
remote-curl to always print a blank line after the push command
has run. If the blank line is ommitted, transport-helper kills its
container process (the git push the user started) with exit(128)
and no message indicating a problem, assuming the helper already
printed reasonable error text to the console.

However if the remote rejects all branches with "ng" commands in the
report-status reply, send-pack terminates with non-zero status, and
in turn remote-curl exited with non-zero status before outputting
the blank line after the helper status printed by send-pack. No
error messages reach the user.

This caused users to see the following from git push over HTTP
when the remote side's update hook rejected the branch:

  $ git push http://... master
  Counting objects: 4, done.
  Delta compression using up to 6 threads.
  Compressing objects: 100% (2/2), done.
  Writing objects: 100% (3/3), 301 bytes, done.
  Total 3 (delta 0), reused 0 (delta 0)
  $

Always print a blank line after the send-pack process terminates,
ensuring the helper status report (if it was output) will be
correctly parsed by the calling transport-helper.c. This ensures
the helper doesn't abort before the status report can be shown to
the user.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
spearce authored and gitster committed Jan 20, 2012
1 parent 04f6785 commit 5238cbf
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
9 changes: 5 additions & 4 deletions remote-curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ static int push(int nr_spec, char **specs)
static void parse_push(struct strbuf *buf)
{
char **specs = NULL;
int alloc_spec = 0, nr_spec = 0, i;
int alloc_spec = 0, nr_spec = 0, i, ret;

do {
if (!prefixcmp(buf->buf, "push ")) {
Expand All @@ -814,12 +814,13 @@ static void parse_push(struct strbuf *buf)
break;
} while (1);

if (push(nr_spec, specs))
exit(128); /* error already reported */

ret = push(nr_spec, specs);
printf("\n");
fflush(stdout);

if (ret)
exit(128); /* error already reported */

free_specs:
for (i = 0; i < nr_spec; i++)
free(specs[i]);
Expand Down
28 changes: 28 additions & 0 deletions t/t5541-http-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ test_expect_success 'create and delete remote branch' '
test_must_fail git show-ref --verify refs/remotes/origin/dev
'

cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
#!/bin/sh
exit 1
EOF
chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"

cat >exp <<EOF
remote: error: hook declined to update refs/heads/dev2
To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
! [remote rejected] dev2 -> dev2 (hook declined)
error: failed to push some refs to 'http://127.0.0.1:5541/smart/test_repo.git'
EOF

test_expect_success 'rejected update prints status' '
cd "$ROOT_PATH"/test_repo_clone &&
git checkout -b dev2 &&
: >path4 &&
git add path4 &&
test_tick &&
git commit -m dev2 &&
test_must_fail git push origin dev2 2>act &&
sed -e "/^remote: /s/ *$//" <act >cmp &&
test_cmp exp cmp
'
rm -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"

cat >exp <<EOF
GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
Expand All @@ -106,6 +132,8 @@ GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
EOF
test_expect_success 'used receive-pack service' '
sed -e "
Expand Down

0 comments on commit 5238cbf

Please sign in to comment.