Skip to content

Commit 5b6864c

Browse files
committed
Merge branch 'jx/atomic-push'
"git push --atomic" used to show failures for refs that weren't even pushed, which has been corrected. * jx/atomic-push: transport-helper: new method reject_atomic_push() transport-helper: mark failure for atomic push send-pack: mark failure of atomic push properly t5543: never report what we do not push send-pack: fix inconsistent porcelain output
2 parents 8f5dc5a + dfe1b7f commit 5b6864c

File tree

9 files changed

+420
-44
lines changed

9 files changed

+420
-44
lines changed

send-pack.c

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,8 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
190190

191191
if (reader->line[0] == 'o' && reader->line[1] == 'k')
192192
hint->status = REF_STATUS_OK;
193-
else {
193+
else
194194
hint->status = REF_STATUS_REMOTE_REJECT;
195-
ret = -1;
196-
}
197195
hint->remote_status = xstrdup_or_null(msg);
198196
/* start our next search from the next ref */
199197
hint = hint->next;
@@ -322,29 +320,6 @@ static int generate_push_cert(struct strbuf *req_buf,
322320
return update_seen;
323321
}
324322

325-
326-
static int atomic_push_failure(struct send_pack_args *args,
327-
struct ref *remote_refs,
328-
struct ref *failing_ref)
329-
{
330-
struct ref *ref;
331-
/* Mark other refs as failed */
332-
for (ref = remote_refs; ref; ref = ref->next) {
333-
if (!ref->peer_ref && !args->send_mirror)
334-
continue;
335-
336-
switch (ref->status) {
337-
case REF_STATUS_EXPECTING_REPORT:
338-
ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
339-
continue;
340-
default:
341-
break; /* do nothing */
342-
}
343-
}
344-
return error("atomic push failed for ref %s. status: %d\n",
345-
failing_ref->name, failing_ref->status);
346-
}
347-
348323
#define NONCE_LEN_LIMIT 256
349324

350325
static void reject_invalid_nonce(const char *nonce, int len)
@@ -489,7 +464,10 @@ int send_pack(struct send_pack_args *args,
489464
if (use_atomic) {
490465
strbuf_release(&req_buf);
491466
strbuf_release(&cap_buf);
492-
return atomic_push_failure(args, remote_refs, ref);
467+
reject_atomic_push(remote_refs, args->send_mirror);
468+
error("atomic push failed for ref %s. status: %d\n",
469+
ref->name, ref->status);
470+
return args->porcelain ? 0 : -1;
493471
}
494472
/* else fallthrough */
495473
default:

t/t5504-fetch-receive-strict.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ test_expect_success 'fetch with transfer.fsckobjects' '
6565
cat >exp <<EOF
6666
To dst
6767
! refs/heads/master:refs/heads/test [remote rejected] (missing necessary objects)
68+
Done
6869
EOF
6970

7071
test_expect_success 'push without strict' '

t/t5516-fetch-push.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,7 @@ test_expect_success 'push --porcelain rejected' '
10661066
10671067
echo >.git/foo "To testrepo" &&
10681068
echo >>.git/foo "! refs/heads/master:refs/heads/master [remote rejected] (branch is currently checked out)" &&
1069+
echo >>.git/foo "Done" &&
10691070
10701071
test_must_fail git push >.git/bar --porcelain testrepo refs/heads/master:refs/heads/master &&
10711072
test_cmp .git/foo .git/bar

t/t5541-http-push-smart.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ test_expect_success 'push (chunked)' '
177177
test $HEAD = $(git rev-parse --verify HEAD))
178178
'
179179

180+
## References of remote: atomic1(1) master(2) collateral(2) other(2)
181+
## References of local : atomic2(2) master(1) collateral(3) other(2) collateral1(3) atomic(1)
182+
## Atomic push : master(1) collateral(3) atomic(1)
180183
test_expect_success 'push --atomic also prevents branch creation, reports collateral' '
181184
# Setup upstream repo - empty for now
182185
d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
@@ -189,7 +192,8 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
189192
test_commit atomic2 &&
190193
git branch collateral &&
191194
git branch other &&
192-
git push "$up" master collateral other &&
195+
git push "$up" atomic1 master collateral other &&
196+
git tag -d atomic1 &&
193197
194198
# collateral is a valid push, but should be failed by atomic push
195199
git checkout collateral &&
@@ -224,7 +228,11 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
224228
225229
# the collateral failure refs should be indicated to the user
226230
grep "^ ! .*rejected.* atomic -> atomic .*atomic push failed" output &&
227-
grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
231+
grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output &&
232+
233+
# never report what we do not push
234+
! grep "^ ! .*rejected.* atomic1 " output &&
235+
! grep "^ ! .*rejected.* other " output
228236
'
229237

230238
test_expect_success 'push --atomic fails on server-side errors' '

t/t5543-atomic-push.sh

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ test_refs () {
2727
test_cmp expect actual
2828
}
2929

30+
fmt_status_report () {
31+
sed -n \
32+
-e "/^To / { s/ */ /g; p; }" \
33+
-e "/^ ! / { s/ */ /g; p; }"
34+
}
35+
3036
test_expect_success 'atomic push works for a single branch' '
3137
mk_repo_pair &&
3238
(
@@ -191,4 +197,87 @@ test_expect_success 'atomic push is not advertised if configured' '
191197
test_refs master HEAD@{1}
192198
'
193199

200+
# References in upstream : master(1) one(1) foo(1)
201+
# References in workbench: master(2) foo(1) two(2) bar(2)
202+
# Atomic push : master(2) two(2) bar(2)
203+
test_expect_success 'atomic push reports (reject by update hook)' '
204+
mk_repo_pair &&
205+
(
206+
cd workbench &&
207+
test_commit one &&
208+
git branch foo &&
209+
git push up master one foo &&
210+
git tag -d one
211+
) &&
212+
(
213+
mkdir -p upstream/.git/hooks &&
214+
cat >upstream/.git/hooks/update <<-EOF &&
215+
#!/bin/sh
216+
217+
if test "\$1" = "refs/heads/bar"
218+
then
219+
echo >&2 "Pusing to branch bar is prohibited"
220+
exit 1
221+
fi
222+
EOF
223+
chmod a+x upstream/.git/hooks/update
224+
) &&
225+
(
226+
cd workbench &&
227+
test_commit two &&
228+
git branch bar
229+
) &&
230+
test_must_fail git -C workbench \
231+
push --atomic up master two bar >out 2>&1 &&
232+
fmt_status_report <out >actual &&
233+
cat >expect <<-EOF &&
234+
To ../upstream
235+
! [remote rejected] master -> master (atomic push failure)
236+
! [remote rejected] two -> two (atomic push failure)
237+
! [remote rejected] bar -> bar (hook declined)
238+
EOF
239+
test_cmp expect actual
240+
'
241+
242+
# References in upstream : master(1) one(1) foo(1)
243+
# References in workbench: master(2) foo(1) two(2) bar(2)
244+
test_expect_success 'atomic push reports (mirror, but reject by update hook)' '
245+
(
246+
cd workbench &&
247+
git remote remove up &&
248+
git remote add up ../upstream
249+
) &&
250+
test_must_fail git -C workbench \
251+
push --atomic --mirror up >out 2>&1 &&
252+
fmt_status_report <out >actual &&
253+
cat >expect <<-EOF &&
254+
To ../upstream
255+
! [remote rejected] master -> master (atomic push failure)
256+
! [remote rejected] one (atomic push failure)
257+
! [remote rejected] bar -> bar (hook declined)
258+
! [remote rejected] two -> two (atomic push failure)
259+
EOF
260+
test_cmp expect actual
261+
'
262+
263+
# References in upstream : master(2) one(1) foo(1)
264+
# References in workbench: master(1) foo(1) two(2) bar(2)
265+
test_expect_success 'atomic push reports (reject by non-ff)' '
266+
rm upstream/.git/hooks/update &&
267+
(
268+
cd workbench &&
269+
git push up master &&
270+
git reset --hard HEAD^
271+
) &&
272+
test_must_fail git -C workbench \
273+
push --atomic up master foo bar >out 2>&1 &&
274+
fmt_status_report <out >actual &&
275+
cat >expect <<-EOF &&
276+
To ../upstream
277+
! [rejected] master -> master (non-fast-forward)
278+
! [rejected] bar -> bar (atomic push failed)
279+
EOF
280+
test_cmp expect actual
281+
'
282+
194283
test_done

0 commit comments

Comments
 (0)