@@ -252,8 +252,18 @@ static int connect_setup(struct transport *transport, int for_push)
252252 return 0 ;
253253}
254254
255- static struct ref * get_refs_via_connect (struct transport * transport , int for_push ,
256- const struct argv_array * ref_prefixes )
255+ /*
256+ * Obtains the protocol version from the transport and writes it to
257+ * transport->data->version, first connecting if not already connected.
258+ *
259+ * If the protocol version is one that allows skipping the listing of remote
260+ * refs, and must_list_refs is 0, the listing of remote refs is skipped and
261+ * this function returns NULL. Otherwise, this function returns the list of
262+ * remote refs.
263+ */
264+ static struct ref * handshake (struct transport * transport , int for_push ,
265+ const struct argv_array * ref_prefixes ,
266+ int must_list_refs )
257267{
258268 struct git_transport_data * data = transport -> data ;
259269 struct ref * refs = NULL ;
@@ -268,8 +278,10 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
268278 data -> version = discover_version (& reader );
269279 switch (data -> version ) {
270280 case protocol_v2 :
271- get_remote_refs (data -> fd [1 ], & reader , & refs , for_push ,
272- ref_prefixes , transport -> server_options );
281+ if (must_list_refs )
282+ get_remote_refs (data -> fd [1 ], & reader , & refs , for_push ,
283+ ref_prefixes ,
284+ transport -> server_options );
273285 break ;
274286 case protocol_v1 :
275287 case protocol_v0 :
@@ -283,9 +295,18 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
283295 }
284296 data -> got_remote_heads = 1 ;
285297
298+ if (reader .line_peeked )
299+ BUG ("buffer must be empty at the end of handshake()" );
300+
286301 return refs ;
287302}
288303
304+ static struct ref * get_refs_via_connect (struct transport * transport , int for_push ,
305+ const struct argv_array * ref_prefixes )
306+ {
307+ return handshake (transport , for_push , ref_prefixes , 1 );
308+ }
309+
289310static int fetch_refs_via_pack (struct transport * transport ,
290311 int nr_heads , struct ref * * to_fetch )
291312{
@@ -320,8 +341,17 @@ static int fetch_refs_via_pack(struct transport *transport,
320341 args .server_options = transport -> server_options ;
321342 args .negotiation_tips = data -> options .negotiation_tips ;
322343
323- if (!data -> got_remote_heads )
324- refs_tmp = get_refs_via_connect (transport , 0 , NULL );
344+ if (!data -> got_remote_heads ) {
345+ int i ;
346+ int must_list_refs = 0 ;
347+ for (i = 0 ; i < nr_heads ; i ++ ) {
348+ if (!to_fetch [i ]-> exact_oid ) {
349+ must_list_refs = 1 ;
350+ break ;
351+ }
352+ }
353+ refs_tmp = handshake (transport , 0 , NULL , must_list_refs );
354+ }
325355
326356 switch (data -> version ) {
327357 case protocol_v2 :
@@ -703,6 +733,7 @@ static int disconnect_git(struct transport *transport)
703733}
704734
705735static struct transport_vtable taken_over_vtable = {
736+ 1 ,
706737 NULL ,
707738 get_refs_via_connect ,
708739 fetch_refs_via_pack ,
@@ -852,6 +883,7 @@ void transport_check_allowed(const char *type)
852883}
853884
854885static struct transport_vtable bundle_vtable = {
886+ 0 ,
855887 NULL ,
856888 get_refs_from_bundle ,
857889 fetch_refs_from_bundle ,
@@ -861,6 +893,7 @@ static struct transport_vtable bundle_vtable = {
861893};
862894
863895static struct transport_vtable builtin_smart_vtable = {
896+ 1 ,
864897 NULL ,
865898 get_refs_via_connect ,
866899 fetch_refs_via_pack ,
@@ -1227,6 +1260,15 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
12271260 struct ref * * heads = NULL ;
12281261 struct ref * rm ;
12291262
1263+ if (!transport -> vtable -> fetch_without_list )
1264+ /*
1265+ * Some transports (e.g. the built-in bundle transport and the
1266+ * transport helper interface) do not work when fetching is
1267+ * done immediately after transport creation. List the remote
1268+ * refs anyway (if not already listed) as a workaround.
1269+ */
1270+ transport_get_remote_refs (transport , NULL );
1271+
12301272 for (rm = refs ; rm ; rm = rm -> next ) {
12311273 nr_refs ++ ;
12321274 if (rm -> peer_ref &&
0 commit comments