refspec: consolidate ref-prefix generation logic

When using protocol v2 a client constructs a list of ref-prefixes which are sent across the wire so that the server can do server-side filtering of the ref-advertisement. The logic that does this exists for both fetch and push (even though no push support for v2 currently exists yet) and is roughly the same so lets consolidate this logic and make it general enough that it can be used for both the push and fetch cases. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Brandon Williams committed May 16, 2018 at 16:48 UTC 6373cb598e1a4e0340583ad75d5abba01ff79774
4 files changed +35 -32
builtin/fetch.c
+1 -12
@@ -351,18 +351,7 @@ static struct ref *get_ref_map(struct transport *transport,
351
352 const struct ref *remote_refs;
353
354 - for (i = 0; i < rs->nr; i++) {
355 - const struct refspec_item *item = &rs->items[i];
356 - if (!item->exact_sha1) {
357 - const char *glob = strchr(item->src, '*');
358 - if (glob)
359 - argv_array_pushf(&ref_prefixes, "%.*s",
360 - (int)(glob - item->src),
361 - item->src);
362 - else
363 - expand_ref_prefix(&ref_prefixes, item->src);
364 - }
365 - }
354 + refspec_ref_prefixes(rs, &ref_prefixes);
355
356 remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
357
refspec.c
+29
@@ -1,4 +1,5 @@
1 #include "cache.h"
2 +#include "argv-array.h"
3 #include "refs.h"
4 #include "refspec.h"
5
@@ -192,3 +193,31 @@ int valid_fetch_refspec(const char *fetch_refspec_str)
193 refspec_item_clear(&refspec);
194 return ret;
195 }
196 +
197 +void refspec_ref_prefixes(const struct refspec *rs,
198 + struct argv_array *ref_prefixes)
199 +{
200 + int i;
201 + for (i = 0; i < rs->nr; i++) {
202 + const struct refspec_item *item = &rs->items[i];
203 + const char *prefix = NULL;
204 +
205 + if (rs->fetch == REFSPEC_FETCH)
206 + prefix = item->src;
207 + else if (item->dst)
208 + prefix = item->dst;
209 + else if (item->src && !item->exact_sha1)
210 + prefix = item->src;
211 +
212 + if (prefix) {
213 + if (item->pattern) {
214 + const char *glob = strchr(prefix, '*');
215 + argv_array_pushf(ref_prefixes, "%.*s",
216 + (int)(glob - prefix),
217 + prefix);
218 + } else {
219 + expand_ref_prefix(ref_prefixes, prefix);
220 + }
221 + }
222 + }
223 +}
refspec.h
+4
@@ -41,4 +41,8 @@ void refspec_clear(struct refspec *rs);
41
42 int valid_fetch_refspec(const char *refspec);
43
44 +struct argv_array;
45 +void refspec_ref_prefixes(const struct refspec *rs,
46 + struct argv_array *ref_prefixes);
47 +
48 #endif /* REFSPEC_H */
transport.c
+1 -20
@@ -1088,30 +1088,11 @@ int transport_push(struct transport *transport,
1088 int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
1089 int push_ret, ret, err;
1090 struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
1091 - int i;
1091
1092 if (check_push_refs(local_refs, rs) < 0)
1093 return -1;
1094
1096 - for (i = 0; i < rs->nr; i++) {
1097 - const struct refspec_item *item = &rs->items[i];
1098 - const char *prefix = NULL;
1099 -
1100 - if (item->dst)
1101 - prefix = item->dst;
1102 - else if (item->src && !item->exact_sha1)
1103 - prefix = item->src;
1104 -
1105 - if (prefix) {
1106 - const char *glob = strchr(prefix, '*');
1107 - if (glob)
1108 - argv_array_pushf(&ref_prefixes, "%.*s",
1109 - (int)(glob - prefix),
1110 - prefix);
1111 - else
1112 - expand_ref_prefix(&ref_prefixes, prefix);
1113 - }
1114 - }
1095 + refspec_ref_prefixes(rs, &ref_prefixes);
1096
1097 remote_refs = transport->vtable->get_refs_list(transport, 1,
1098 &ref_prefixes);