]> git.ipfire.org Git - thirdparty/git.git/commitdiff
transport: parse report options for tracking refs
authorJiang Xin <zhiyou.jx@alibaba-inc.com>
Thu, 27 Aug 2020 15:45:50 +0000 (11:45 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 27 Aug 2020 19:48:47 +0000 (12:48 -0700)
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>
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
transport.c

index 8eec3a1ed8c0e9731314fd2eff4661028c6c2dcc..73283d81e8a3312b3418c7b793c00d33ef2490f8 100644 (file)
@@ -78,10 +78,14 @@ test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
                grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
        make_user_friendly_and_stable_output <out >actual &&
        cat >expect <<-EOF &&
-       <COMMIT-A> refs/t/for/master/topic
+       <COMMIT-A> refs/t/changes/24/124/1
+       <COMMIT-B> refs/t/changes/25/125/1
+       <COMMIT-B> refs/t/for/master/topic
        EOF
        test_cmp expect actual &&
-       git -C workbench update-ref -d refs/t/for/master/topic
+       git -C workbench update-ref -d refs/t/for/master/topic &&
+       git -C workbench update-ref -d refs/t/changes/24/124/1 &&
+       git -C workbench update-ref -d refs/t/changes/25/125/1
 '
 
 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)" '
                grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
        make_user_friendly_and_stable_output <out >actual &&
        cat >expect <<-EOF &&
-       <COMMIT-A> refs/t/for/master/topic
+       <COMMIT-A> refs/t/changes/24/124/1
+       <COMMIT-A> refs/t/changes/25/125/1
+       <COMMIT-B> refs/t/for/master/topic
        EOF
        test_cmp expect actual &&
-       git -C workbench update-ref -d refs/t/for/master/topic
+       git -C workbench update-ref -d refs/t/for/master/topic &&
+       git -C workbench update-ref -d refs/t/changes/24/124/1 &&
+       git -C workbench update-ref -d refs/t/changes/25/125/1
 '
 
 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)" '
                grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
        make_user_friendly_and_stable_output <out >actual &&
        cat >expect <<-EOF &&
-       <COMMIT-A> refs/t/for/master/topic
+       <COMMIT-A> refs/t/changes/23/123/1
+       <COMMIT-B> refs/t/changes/24/124/2
        EOF
        test_cmp expect actual &&
-       git -C workbench update-ref -d refs/t/for/master/topic
+       git -C workbench update-ref -d refs/t/changes/24/124/1 &&
+       git -C workbench update-ref -d refs/t/changes/25/125/2
 '
index e146de6c4eba4bedd577933a97e95929f2c0d123..a69f2cf806b278c739bd4e5fe11ba77ce9ff6f94 100644 (file)
@@ -437,28 +437,49 @@ int transport_refs_pushed(struct ref *ref)
        return 0;
 }
 
-void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
+static void update_one_tracking_ref(struct remote *remote, char *refname,
+                                   struct object_id *new_oid, int deletion,
+                                   int verbose)
 {
        struct refspec_item rs;
 
-       if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
-               return;
-
-       rs.src = ref->name;
+       rs.src = refname;
        rs.dst = NULL;
 
        if (!remote_find_tracking(remote, &rs)) {
                if (verbose)
                        fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
-               if (ref->deletion) {
+               if (deletion)
                        delete_ref(NULL, rs.dst, NULL, 0);
-               else
-                       update_ref("update by push", rs.dst, &ref->new_oid,
+               else
+                       update_ref("update by push", rs.dst, new_oid,
                                   NULL, 0, 0);
                free(rs.dst);
        }
 }
 
+void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
+{
+       char *refname;
+       struct object_id *new_oid;
+       struct ref_push_report *report;
+
+       if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
+               return;
+
+       report = ref->report;
+       if (!report)
+               update_one_tracking_ref(remote, ref->name, &ref->new_oid,
+                                       ref->deletion, verbose);
+       else
+               for (; report; report = report->next) {
+                       refname = report->ref_name ? (char *)report->ref_name : ref->name;
+                       new_oid = report->new_oid ? report->new_oid : &ref->new_oid;
+                       update_one_tracking_ref(remote, refname, new_oid,
+                                               is_null_oid(new_oid), verbose);
+               }
+}
+
 static void print_ref_status(char flag, const char *summary,
                             struct ref *to, struct ref *from, const char *msg,
                             struct ref_push_report *report,