@matheusbsbs / matheus-bagliano / commits / 1702ae6f61
Fork 0

transport: parse report options for tracking refs

When pushing a pseudo reference (such as "refs/for/master/topic"), may create or update one or more references. The real names of the references will be stored in the report options. Parse report options to create or update remote-tracking branches properly. Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jiang Xin committed Aug 27, 2020 at 11:45 UTC 1702ae6f61412fa7d858701a7724a5cbf4aeea3e
2 files changed +45 -14
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
+16 -6
@@ -78,10 +78,14 @@ test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
78 grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
79 make_user_friendly_and_stable_output <out >actual &&
80 cat >expect <<-EOF &&
81 - <COMMIT-A> refs/t/for/master/topic
81 + <COMMIT-A> refs/t/changes/24/124/1
82 + <COMMIT-B> refs/t/changes/25/125/1
83 + <COMMIT-B> refs/t/for/master/topic
84 EOF
85 test_cmp expect actual &&
84 - git -C workbench update-ref -d refs/t/for/master/topic
86 + git -C workbench update-ref -d refs/t/for/master/topic &&
87 + git -C workbench update-ref -d refs/t/changes/24/124/1 &&
88 + git -C workbench update-ref -d refs/t/changes/25/125/1
89 '
90
91 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL)" '
@@ -151,10 +155,14 @@ test_expect_success "proc-receive: check remote-tracking #2 ($PROTOCOL)" '
155 grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
156 make_user_friendly_and_stable_output <out >actual &&
157 cat >expect <<-EOF &&
154 - <COMMIT-A> refs/t/for/master/topic
158 + <COMMIT-A> refs/t/changes/24/124/1
159 + <COMMIT-A> refs/t/changes/25/125/1
160 + <COMMIT-B> refs/t/for/master/topic
161 EOF
162 test_cmp expect actual &&
157 - git -C workbench update-ref -d refs/t/for/master/topic
163 + git -C workbench update-ref -d refs/t/for/master/topic &&
164 + git -C workbench update-ref -d refs/t/changes/24/124/1 &&
165 + git -C workbench update-ref -d refs/t/changes/25/125/1
166 '
167
168 test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL)" '
@@ -210,8 +218,10 @@ test_expect_success "proc-receive: check remote-tracking #3 ($PROTOCOL)" '
218 grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
219 make_user_friendly_and_stable_output <out >actual &&
220 cat >expect <<-EOF &&
213 - <COMMIT-A> refs/t/for/master/topic
221 + <COMMIT-A> refs/t/changes/23/123/1
222 + <COMMIT-B> refs/t/changes/24/124/2
223 EOF
224 test_cmp expect actual &&
216 - git -C workbench update-ref -d refs/t/for/master/topic
225 + git -C workbench update-ref -d refs/t/changes/24/124/1 &&
226 + git -C workbench update-ref -d refs/t/changes/25/125/2
227 '
transport.c
+29 -8
@@ -437,28 +437,49 @@ int transport_refs_pushed(struct ref *ref)
437 return 0;
438 }
439
440 -void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
440 +static void update_one_tracking_ref(struct remote *remote, char *refname,
441 + struct object_id *new_oid, int deletion,
442 + int verbose)
443 {
444 struct refspec_item rs;
445
444 - if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
445 - return;
446 -
447 - rs.src = ref->name;
446 + rs.src = refname;
447 rs.dst = NULL;
448
449 if (!remote_find_tracking(remote, &rs)) {
450 if (verbose)
451 fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
453 - if (ref->deletion) {
452 + if (deletion)
453 delete_ref(NULL, rs.dst, NULL, 0);
455 - } else
456 - update_ref("update by push", rs.dst, &ref->new_oid,
454 + else
455 + update_ref("update by push", rs.dst, new_oid,
456 NULL, 0, 0);
457 free(rs.dst);
458 }
459 }
460
461 +void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
462 +{
463 + char *refname;
464 + struct object_id *new_oid;
465 + struct ref_push_report *report;
466 +
467 + if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
468 + return;
469 +
470 + report = ref->report;
471 + if (!report)
472 + update_one_tracking_ref(remote, ref->name, &ref->new_oid,
473 + ref->deletion, verbose);
474 + else
475 + for (; report; report = report->next) {
476 + refname = report->ref_name ? (char *)report->ref_name : ref->name;
477 + new_oid = report->new_oid ? report->new_oid : &ref->new_oid;
478 + update_one_tracking_ref(remote, refname, new_oid,
479 + is_null_oid(new_oid), verbose);
480 + }
481 +}
482 +
483 static void print_ref_status(char flag, const char *summary,
484 struct ref *to, struct ref *from, const char *msg,
485 struct ref_push_report *report,