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>
This commit is contained in:

committed by
Junio C Hamano

parent
c6a6a01c4a
commit
1702ae6f61
@ -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 &&
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
make_user_friendly_and_stable_output <out >actual &&
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
cat >expect <<-EOF &&
|
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
|
EOF
|
||||||
test_cmp expect actual &&
|
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)" '
|
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 &&
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
make_user_friendly_and_stable_output <out >actual &&
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
cat >expect <<-EOF &&
|
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
|
EOF
|
||||||
test_cmp expect actual &&
|
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)" '
|
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 &&
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
make_user_friendly_and_stable_output <out >actual &&
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
cat >expect <<-EOF &&
|
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
|
EOF
|
||||||
test_cmp expect actual &&
|
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
|
||||||
'
|
'
|
||||||
|
37
transport.c
37
transport.c
@ -437,28 +437,49 @@ int transport_refs_pushed(struct ref *ref)
|
|||||||
return 0;
|
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;
|
struct refspec_item rs;
|
||||||
|
|
||||||
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
rs.src = refname;
|
||||||
return;
|
|
||||||
|
|
||||||
rs.src = ref->name;
|
|
||||||
rs.dst = NULL;
|
rs.dst = NULL;
|
||||||
|
|
||||||
if (!remote_find_tracking(remote, &rs)) {
|
if (!remote_find_tracking(remote, &rs)) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
|
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
|
||||||
if (ref->deletion) {
|
if (deletion)
|
||||||
delete_ref(NULL, rs.dst, NULL, 0);
|
delete_ref(NULL, rs.dst, NULL, 0);
|
||||||
} else
|
else
|
||||||
update_ref("update by push", rs.dst, &ref->new_oid,
|
update_ref("update by push", rs.dst, new_oid,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
free(rs.dst);
|
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,
|
static void print_ref_status(char flag, const char *summary,
|
||||||
struct ref *to, struct ref *from, const char *msg,
|
struct ref *to, struct ref *from, const char *msg,
|
||||||
struct ref_push_report *report,
|
struct ref_push_report *report,
|
||||||
|
Reference in New Issue
Block a user