Skip to content

Commit d56583d

Browse files
mattmccutchengitster
authored andcommitted
fetch-pack: add specific error for fetching an unadvertised object
Enhance filter_refs (which decides whether a request for an unadvertised object should be sent to the server) to record a new match status on the "struct ref" when a request is not allowed, and have report_unmatched_refs check for this status and print a special error message, "Server does not allow request for unadvertised object". Signed-off-by: Matt McCutchen <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e70a65c commit d56583d

File tree

3 files changed

+35
-18
lines changed

3 files changed

+35
-18
lines changed

fetch-pack.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ static void filter_refs(struct fetch_pack_args *args,
578578
break; /* definitely do not have it */
579579
else if (cmp == 0) {
580580
keep = 1; /* definitely have it */
581-
sought[i]->matched = 1;
581+
sought[i]->match_status = REF_MATCHED;
582582
}
583583
i++;
584584
}
@@ -598,22 +598,24 @@ static void filter_refs(struct fetch_pack_args *args,
598598
}
599599

600600
/* Append unmatched requests to the list */
601-
if ((allow_unadvertised_object_request &
602-
(ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
603-
for (i = 0; i < nr_sought; i++) {
604-
unsigned char sha1[20];
601+
for (i = 0; i < nr_sought; i++) {
602+
unsigned char sha1[20];
605603

606-
ref = sought[i];
607-
if (ref->matched)
608-
continue;
609-
if (get_sha1_hex(ref->name, sha1) ||
610-
ref->name[40] != '\0' ||
611-
hashcmp(sha1, ref->old_oid.hash))
612-
continue;
604+
ref = sought[i];
605+
if (ref->match_status != REF_NOT_MATCHED)
606+
continue;
607+
if (get_sha1_hex(ref->name, sha1) ||
608+
ref->name[40] != '\0' ||
609+
hashcmp(sha1, ref->old_oid.hash))
610+
continue;
613611

614-
ref->matched = 1;
612+
if ((allow_unadvertised_object_request &
613+
(ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
614+
ref->match_status = REF_MATCHED;
615615
*newtail = copy_ref(ref);
616616
newtail = &(*newtail)->next;
617+
} else {
618+
ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
617619
}
618620
}
619621
*refs = newlist;
@@ -1100,9 +1102,19 @@ int report_unmatched_refs(struct ref **sought, int nr_sought)
11001102
int i, ret = 0;
11011103

11021104
for (i = 0; i < nr_sought; i++) {
1103-
if (!sought[i] || sought[i]->matched)
1105+
if (!sought[i])
11041106
continue;
1105-
error(_("no such remote ref %s"), sought[i]->name);
1107+
switch (sought[i]->match_status) {
1108+
case REF_MATCHED:
1109+
continue;
1110+
case REF_NOT_MATCHED:
1111+
error(_("no such remote ref %s"), sought[i]->name);
1112+
break;
1113+
case REF_UNADVERTISED_NOT_ALLOWED:
1114+
error(_("Server does not allow request for unadvertised object %s"),
1115+
sought[i]->name);
1116+
break;
1117+
}
11061118
ret = 1;
11071119
}
11081120
return ret;

remote.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,13 @@ struct ref {
8989
force:1,
9090
forced_update:1,
9191
expect_old_sha1:1,
92-
deletion:1,
93-
matched:1;
92+
deletion:1;
93+
94+
enum {
95+
REF_NOT_MATCHED = 0, /* initial value */
96+
REF_MATCHED,
97+
REF_UNADVERTISED_NOT_ALLOWED
98+
} match_status;
9499

95100
/*
96101
* Order is important here, as we write to FETCH_HEAD

t/t5516-fetch-push.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ test_expect_success 'fetch exact SHA1' '
10991099
11001100
# fetching the hidden object should fail by default
11011101
test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
1102-
test_i18ngrep "no such remote ref" err &&
1102+
test_i18ngrep "Server does not allow request for unadvertised object" err &&
11031103
test_must_fail git rev-parse --verify refs/heads/copy &&
11041104
11051105
# the server side can allow it to succeed

0 commit comments

Comments
 (0)