@@ -364,13 +364,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
364364 closedir (dir );
365365}
366366
367- static const struct ref * clone_local (const char * src_repo ,
368- const char * dest_repo )
367+ static void clone_local (const char * src_repo , const char * dest_repo )
369368{
370- const struct ref * ret ;
371- struct remote * remote ;
372- struct transport * transport ;
373-
374369 if (option_shared ) {
375370 struct strbuf alt = STRBUF_INIT ;
376371 strbuf_addf (& alt , "%s/objects" , src_repo );
@@ -386,13 +381,8 @@ static const struct ref *clone_local(const char *src_repo,
386381 strbuf_release (& dest );
387382 }
388383
389- remote = remote_get (src_repo );
390- transport = transport_get (remote , src_repo );
391- ret = transport_get_remote_refs (transport );
392- transport_disconnect (transport );
393384 if (0 <= option_verbosity )
394385 printf (_ ("done.\n" ));
395- return ret ;
396386}
397387
398388static const char * junk_work_tree ;
@@ -619,6 +609,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
619609 struct strbuf key = STRBUF_INIT , value = STRBUF_INIT ;
620610 struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
621611 struct transport * transport = NULL ;
612+ struct remote * remote ;
622613 int err = 0 ;
623614
624615 struct refspec * refspec ;
@@ -773,13 +764,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
773764
774765 strbuf_reset (& value );
775766
776- if (is_local ) {
777- refs = clone_local (path , git_dir );
778- mapped_refs = wanted_peer_refs (refs , refspec );
779- } else {
780- struct remote * remote = remote_get (option_origin );
781- transport = transport_get (remote , remote -> url [0 ]);
767+ remote = remote_get (option_origin );
768+ transport = transport_get (remote , remote -> url [0 ]);
782769
770+ if (!is_local ) {
783771 if (!transport -> get_refs_list || !transport -> fetch )
784772 die (_ ("Don't know how to clone %s" ), transport -> url );
785773
@@ -796,14 +784,23 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
796784 if (option_upload_pack )
797785 transport_set_option (transport , TRANS_OPT_UPLOADPACK ,
798786 option_upload_pack );
799-
800- refs = transport_get_remote_refs (transport );
801- if (refs ) {
802- mapped_refs = wanted_peer_refs (refs , refspec );
803- transport_fetch_refs (transport , mapped_refs );
804- }
805787 }
806788
789+ refs = transport_get_remote_refs (transport );
790+ mapped_refs = refs ? wanted_peer_refs (refs , refspec ) : NULL ;
791+
792+ /*
793+ * mapped_refs may be updated if transport-helper is used so
794+ * we need fetch it early because remote_head code below
795+ * relies on it.
796+ *
797+ * for normal clones, transport_get_remote_refs() should
798+ * return reliable ref set, we can delay cloning until after
799+ * remote HEAD check.
800+ */
801+ if (!is_local && remote -> foreign_vcs && refs )
802+ transport_fetch_refs (transport , mapped_refs );
803+
807804 if (refs ) {
808805 remote_head = find_ref_by_name (refs , "HEAD" );
809806 remote_head_points_at =
@@ -838,15 +835,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
838835 "refs/heads/master" );
839836 }
840837
838+ if (is_local )
839+ clone_local (path , git_dir );
840+ else if (refs && !remote -> foreign_vcs )
841+ transport_fetch_refs (transport , mapped_refs );
842+
841843 update_remote_refs (refs , mapped_refs , remote_head_points_at ,
842844 branch_top .buf , reflog_msg .buf );
843845
844846 update_head (our_head_points_at , remote_head , reflog_msg .buf );
845847
846- if (transport ) {
847- transport_unlock_pack (transport );
848- transport_disconnect (transport );
849- }
848+ transport_unlock_pack (transport );
849+ transport_disconnect (transport );
850850
851851 err = checkout ();
852852
0 commit comments