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 <matt@mattmccutchen.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Matt McCutchen committed
Feb 22, 2017 at 11:05 UTC
d56583ded679f2eade3994d855c8d605e2964710
3 files changed
+35
-18
fetch-pack.c
+27
-15
@@ -578,7 +578,7 @@ static void filter_refs(struct fetch_pack_args *args,
578
break; /* definitely do not have it */
579
else if (cmp == 0) {
580
keep = 1; /* definitely have it */
581
- sought[i]->matched = 1;
581
+ sought[i]->match_status = REF_MATCHED;
582
}
583
i++;
584
}
@@ -598,22 +598,24 @@ static void filter_refs(struct fetch_pack_args *args,
598
}
599
600
/* 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];
603
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;
611
614
- ref->matched = 1;
612
+ if ((allow_unadvertised_object_request &
613
+ (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
614
+ ref->match_status = REF_MATCHED;
615
*newtail = copy_ref(ref);
616
newtail = &(*newtail)->next;
617
+ } else {
618
+ ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
619
}
620
}
621
*refs = newlist;
@@ -1100,9 +1102,19 @@ int report_unmatched_refs(struct ref **sought, int nr_sought)
1102
int i, ret = 0;
1103
1104
for (i = 0; i < nr_sought; i++) {
1103
- if (!sought[i] || sought[i]->matched)
1105
+ if (!sought[i])
1106
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
+ }
1118
ret = 1;
1119
}
1120
return ret;
remote.h
+7
-2
@@ -89,8 +89,13 @@ struct ref {
89
force:1,
90
forced_update:1,
91
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;
99
100
/*
101
* Order is important here, as we write to FETCH_HEAD
t/t5516-fetch-push.sh
+1
-1
@@ -1099,7 +1099,7 @@ test_expect_success 'fetch exact SHA1' '
1099
1100
# fetching the hidden object should fail by default
1101
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 &&
1103
test_must_fail git rev-parse --verify refs/heads/copy &&
1104
1105
# the server side can allow it to succeed