Skip to content

Commit 1702ae6

Browse files
jiangxingitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c6a6a01 commit 1702ae6

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,14 @@ test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
7878
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
7979
make_user_friendly_and_stable_output <out >actual &&
8080
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
8284
EOF
8385
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
8589
'
8690

8791
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)" '
151155
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
152156
make_user_friendly_and_stable_output <out >actual &&
153157
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
155161
EOF
156162
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
158166
'
159167

160168
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)" '
210218
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
211219
make_user_friendly_and_stable_output <out >actual &&
212220
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
214223
EOF
215224
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
217227
'

transport.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,28 +437,49 @@ int transport_refs_pushed(struct ref *ref)
437437
return 0;
438438
}
439439

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)
441443
{
442444
struct refspec_item rs;
443445

444-
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
445-
return;
446-
447-
rs.src = ref->name;
446+
rs.src = refname;
448447
rs.dst = NULL;
449448

450449
if (!remote_find_tracking(remote, &rs)) {
451450
if (verbose)
452451
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
453-
if (ref->deletion) {
452+
if (deletion)
454453
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,
457456
NULL, 0, 0);
458457
free(rs.dst);
459458
}
460459
}
461460

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+
462483
static void print_ref_status(char flag, const char *summary,
463484
struct ref *to, struct ref *from, const char *msg,
464485
struct ref_push_report *report,

0 commit comments

Comments
 (0)