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>
This commit is contained in:
Brandon Williams 2018-05-16 16:48:21 -07:00 коммит произвёл Junio C Hamano
Родитель 60fba4bf16
Коммит 6373cb598e
4 изменённых файлов: 35 добавлений и 32 удалений

Просмотреть файл

@ -351,18 +351,7 @@ static struct ref *get_ref_map(struct transport *transport,
const struct ref *remote_refs;
for (i = 0; i < rs->nr; i++) {
const struct refspec_item *item = &rs->items[i];
if (!item->exact_sha1) {
const char *glob = strchr(item->src, '*');
if (glob)
argv_array_pushf(&ref_prefixes, "%.*s",
(int)(glob - item->src),
item->src);
else
expand_ref_prefix(&ref_prefixes, item->src);
}
}
refspec_ref_prefixes(rs, &ref_prefixes);
remote_refs = transport_get_remote_refs(transport, &ref_prefixes);

Просмотреть файл

@ -1,4 +1,5 @@
#include "cache.h"
#include "argv-array.h"
#include "refs.h"
#include "refspec.h"
@ -192,3 +193,31 @@ int valid_fetch_refspec(const char *fetch_refspec_str)
refspec_item_clear(&refspec);
return ret;
}
void refspec_ref_prefixes(const struct refspec *rs,
struct argv_array *ref_prefixes)
{
int i;
for (i = 0; i < rs->nr; i++) {
const struct refspec_item *item = &rs->items[i];
const char *prefix = NULL;
if (rs->fetch == REFSPEC_FETCH)
prefix = item->src;
else if (item->dst)
prefix = item->dst;
else if (item->src && !item->exact_sha1)
prefix = item->src;
if (prefix) {
if (item->pattern) {
const char *glob = strchr(prefix, '*');
argv_array_pushf(ref_prefixes, "%.*s",
(int)(glob - prefix),
prefix);
} else {
expand_ref_prefix(ref_prefixes, prefix);
}
}
}
}

Просмотреть файл

@ -41,4 +41,8 @@ void refspec_clear(struct refspec *rs);
int valid_fetch_refspec(const char *refspec);
struct argv_array;
void refspec_ref_prefixes(const struct refspec *rs,
struct argv_array *ref_prefixes);
#endif /* REFSPEC_H */

Просмотреть файл

@ -1088,30 +1088,11 @@ int transport_push(struct transport *transport,
int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
int push_ret, ret, err;
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
int i;
if (check_push_refs(local_refs, rs) < 0)
return -1;
for (i = 0; i < rs->nr; i++) {
const struct refspec_item *item = &rs->items[i];
const char *prefix = NULL;
if (item->dst)
prefix = item->dst;
else if (item->src && !item->exact_sha1)
prefix = item->src;
if (prefix) {
const char *glob = strchr(prefix, '*');
if (glob)
argv_array_pushf(&ref_prefixes, "%.*s",
(int)(glob - prefix),
prefix);
else
expand_ref_prefix(&ref_prefixes, prefix);
}
}
refspec_ref_prefixes(rs, &ref_prefixes);
remote_refs = transport->vtable->get_refs_list(transport, 1,
&ref_prefixes);