push: pass ref prefixes when pushing

Construct a list of ref prefixes to be passed to 'get_refs_list()' from the refspec to be used during the push. This list of ref prefixes will be used to allow the server to filter the ref advertisement when communicating using protocol v2. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Brandon Williams committed Mar 15, 2018 at 10:31 UTC 5b872fff187037829fdd3e494acdf4299ff6e80b
1 file changed +28 -1
transport.c
+28 -1
@@ -1028,11 +1028,38 @@ int transport_push(struct transport *transport,
1028 int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
1029 int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
1030 int push_ret, ret, err;
1031 + struct refspec *tmp_rs;
1032 + struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
1033 + int i;
1034
1035 if (check_push_refs(local_refs, refspec_nr, refspec) < 0)
1036 return -1;
1037
1035 - remote_refs = transport->vtable->get_refs_list(transport, 1, NULL);
1038 + tmp_rs = parse_push_refspec(refspec_nr, refspec);
1039 + for (i = 0; i < refspec_nr; i++) {
1040 + const char *prefix = NULL;
1041 +
1042 + if (tmp_rs[i].dst)
1043 + prefix = tmp_rs[i].dst;
1044 + else if (tmp_rs[i].src && !tmp_rs[i].exact_sha1)
1045 + prefix = tmp_rs[i].src;
1046 +
1047 + if (prefix) {
1048 + const char *glob = strchr(prefix, '*');
1049 + if (glob)
1050 + argv_array_pushf(&ref_prefixes, "%.*s",
1051 + (int)(glob - prefix),
1052 + prefix);
1053 + else
1054 + expand_ref_prefix(&ref_prefixes, prefix);
1055 + }
1056 + }
1057 +
1058 + remote_refs = transport->vtable->get_refs_list(transport, 1,
1059 + &ref_prefixes);
1060 +
1061 + argv_array_clear(&ref_prefixes);
1062 + free_refspec(refspec_nr, tmp_rs);
1063
1064 if (flags & TRANSPORT_PUSH_ALL)
1065 match_flags |= MATCH_REFS_ALL;