Skip to content

Commit 345aaf3

Browse files
committed
Merge branch 'ps/send-pack-unhide-error-in-atomic-push'
"git push --atomic --porcelain" used to ignore failures from the other side, losing the error status from the child process, which has been corrected. * ps/send-pack-unhide-error-in-atomic-push: send-pack: gracefully close the connection for atomic push t5543: atomic push reports exit code failure send-pack: new return code "ERROR_SEND_PACK_BAD_REF_STATUS" t5548: add porcelain push test cases for dry-run mode t5548: add new porcelain test cases t5548: refactor test cases by resetting upstream t5548: refactor to reuse setup_upstream() function t5504: modernize test by moving heredocs into test bodies
2 parents e565f37 + b81f8c8 commit 345aaf3

File tree

6 files changed

+406
-142
lines changed

6 files changed

+406
-142
lines changed

send-pack.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,8 @@ int send_pack(struct repository *r,
632632
reject_atomic_push(remote_refs, args->send_mirror);
633633
error("atomic push failed for ref %s. status: %d",
634634
ref->name, ref->status);
635-
ret = args->porcelain ? 0 : -1;
635+
ret = ERROR_SEND_PACK_BAD_REF_STATUS;
636+
packet_flush(out);
636637
goto out;
637638
}
638639
/* else fallthrough */
@@ -763,19 +764,14 @@ int send_pack(struct repository *r,
763764
if (ret < 0)
764765
goto out;
765766

766-
if (args->porcelain) {
767-
ret = 0;
768-
goto out;
769-
}
770-
771767
for (ref = remote_refs; ref; ref = ref->next) {
772768
switch (ref->status) {
773769
case REF_STATUS_NONE:
774770
case REF_STATUS_UPTODATE:
775771
case REF_STATUS_OK:
776772
break;
777773
default:
778-
ret = -1;
774+
ret = ERROR_SEND_PACK_BAD_REF_STATUS;
779775
goto out;
780776
}
781777
}

send-pack.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ struct repository;
1313
#define SEND_PACK_PUSH_CERT_IF_ASKED 1
1414
#define SEND_PACK_PUSH_CERT_ALWAYS 2
1515

16+
/* At least one reference has been rejected by the remote side. */
17+
#define ERROR_SEND_PACK_BAD_REF_STATUS 1
18+
1619
struct send_pack_args {
1720
const char *url;
1821
unsigned verbose:1,
@@ -36,6 +39,16 @@ struct option;
3639
int option_parse_push_signed(const struct option *opt,
3740
const char *arg, int unset);
3841

42+
/*
43+
* Compute a packfile and write it to a file descriptor. The `fd` array needs
44+
* to contain two file descriptors: `fd[0]` is the file descriptor used as
45+
* input for the packet reader, whereas `fd[1]` is the file descriptor the
46+
* packfile will be written to.
47+
*
48+
* Returns 0 on success, non-zero otherwise. Negative return values indicate a
49+
* generic error, whereas positive return values indicate specific error
50+
* conditions as documented with the `ERROR_SEND_PACK_*` constants.
51+
*/
3952
int send_pack(struct repository *r, struct send_pack_args *args,
4053
int fd[], struct child_process *conn,
4154
struct ref *remote_refs, struct oid_array *extra_have);

t/t5504-fetch-receive-strict.sh

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,6 @@ test_expect_success 'fetch with transfer.fsckobjects' '
6464
)
6565
'
6666

67-
cat >exp <<EOF
68-
To dst
69-
! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects)
70-
Done
71-
EOF
72-
7367
test_expect_success 'push without strict' '
7468
rm -rf dst &&
7569
git init dst &&
@@ -78,6 +72,11 @@ test_expect_success 'push without strict' '
7872
git config fetch.fsckobjects false &&
7973
git config transfer.fsckobjects false
8074
) &&
75+
cat >exp <<-\EOF &&
76+
To dst
77+
! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects)
78+
Done
79+
EOF
8180
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
8281
test_cmp exp act
8382
'
@@ -94,11 +93,6 @@ test_expect_success 'push with !receive.fsckobjects' '
9493
test_cmp exp act
9594
'
9695

97-
cat >exp <<EOF
98-
To dst
99-
! refs/heads/main:refs/heads/test [remote rejected] (unpacker error)
100-
EOF
101-
10296
test_expect_success 'push with receive.fsckobjects' '
10397
rm -rf dst &&
10498
git init dst &&
@@ -107,6 +101,10 @@ test_expect_success 'push with receive.fsckobjects' '
107101
git config receive.fsckobjects true &&
108102
git config transfer.fsckobjects false
109103
) &&
104+
cat >exp <<-\EOF &&
105+
To dst
106+
! refs/heads/main:refs/heads/test [remote rejected] (unpacker error)
107+
EOF
110108
test_must_fail git push --porcelain dst main:refs/heads/test >act &&
111109
test_cmp exp act
112110
'
@@ -129,15 +127,14 @@ test_expect_success 'repair the "corrupt or missing" object' '
129127
git fsck
130128
'
131129

132-
cat >bogus-commit <<EOF
133-
tree $EMPTY_TREE
134-
author Bugs Bunny 1234567890 +0000
135-
committer Bugs Bunny <[email protected]> 1234567890 +0000
136-
137-
This commit object intentionally broken
138-
EOF
139-
140130
test_expect_success 'setup bogus commit' '
131+
cat >bogus-commit <<-EOF &&
132+
tree $EMPTY_TREE
133+
author Bugs Bunny 1234567890 +0000
134+
committer Bugs Bunny <[email protected]> 1234567890 +0000
135+
136+
This commit object intentionally broken
137+
EOF
141138
commit="$(git hash-object --literally -t commit -w --stdin <bogus-commit)"
142139
'
143140

t/t5543-atomic-push.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,4 +280,34 @@ test_expect_success 'atomic push reports (reject by non-ff)' '
280280
test_cmp expect actual
281281
'
282282

283+
test_expect_success 'atomic push reports exit code failure' '
284+
write_script receive-pack-wrapper <<-\EOF &&
285+
git-receive-pack "$@"
286+
exit 1
287+
EOF
288+
test_must_fail git -C workbench push --atomic \
289+
--receive-pack="${SQ}$(pwd)${SQ}/receive-pack-wrapper" \
290+
up HEAD:refs/heads/no-conflict 2>err &&
291+
cat >expect <<-EOF &&
292+
To ../upstream
293+
* [new branch] HEAD -> no-conflict
294+
error: failed to push some refs to ${SQ}../upstream${SQ}
295+
EOF
296+
test_cmp expect err
297+
'
298+
299+
test_expect_success 'atomic push reports exit code failure with porcelain' '
300+
write_script receive-pack-wrapper <<-\EOF &&
301+
git-receive-pack "$@"
302+
exit 1
303+
EOF
304+
test_must_fail git -C workbench push --atomic --porcelain \
305+
--receive-pack="${SQ}$(pwd)${SQ}/receive-pack-wrapper" \
306+
up HEAD:refs/heads/no-conflict-porcelain 2>err &&
307+
cat >expect <<-EOF &&
308+
error: failed to push some refs to ${SQ}../upstream${SQ}
309+
EOF
310+
test_cmp expect err
311+
'
312+
283313
test_done

0 commit comments

Comments
 (0)