@@ -1577,6 +1577,80 @@ static int backfill_tags(struct display_state *display_state,
15771577 return retcode ;
15781578}
15791579
1580+ static void report_set_head (const char * remote , const char * head_name ,
1581+ struct strbuf * buf_prev ) {
1582+ struct strbuf buf_prefix = STRBUF_INIT ;
1583+ const char * prev_head = NULL ;
1584+
1585+ strbuf_addf (& buf_prefix , "refs/remotes/%s/" , remote );
1586+ skip_prefix (buf_prev -> buf , buf_prefix .buf , & prev_head );
1587+
1588+ if (prev_head && strcmp (prev_head , head_name )) {
1589+ printf ("'HEAD' at '%s' has changed from '%s' to '%s'\n" ,
1590+ remote , prev_head , head_name );
1591+ printf ("Run 'git remote set-head %s %s' to follow the change.\n" ,
1592+ remote , head_name );
1593+ }
1594+ }
1595+
1596+ static const char * strip_refshead (const char * name ){
1597+ skip_prefix (name , "refs/heads/" , & name );
1598+ return name ;
1599+ }
1600+
1601+ static int set_head (const struct ref * remote_refs )
1602+ {
1603+ int result = 0 ;
1604+ struct strbuf b_head = STRBUF_INIT , b_remote_head = STRBUF_INIT ,
1605+ b_local_head = STRBUF_INIT ;
1606+ const char * remote = gtransport -> remote -> name ;
1607+ char * head_name = NULL ;
1608+ struct ref * ref , * matches ;
1609+ struct ref * fetch_map = NULL , * * fetch_map_tail = & fetch_map ;
1610+ struct refspec_item refspec = {
1611+ .force = 0 ,
1612+ .pattern = 1 ,
1613+ .src = (char * ) "refs/heads/*" ,
1614+ .dst = (char * ) "refs/heads/*" ,
1615+ };
1616+ struct string_list heads = STRING_LIST_INIT_DUP ;
1617+ struct ref_store * refs = get_main_ref_store (the_repository );
1618+
1619+ get_fetch_map (remote_refs , & refspec , & fetch_map_tail , 0 );
1620+ matches = guess_remote_head (find_ref_by_name (remote_refs , "HEAD" ),
1621+ fetch_map , 1 );
1622+ for (ref = matches ; ref ; ref = ref -> next ) {
1623+ string_list_append (& heads , strip_refshead (ref -> name ));
1624+ }
1625+
1626+
1627+ if (!heads .nr )
1628+ result = 1 ;
1629+ else if (heads .nr > 1 )
1630+ result = 1 ;
1631+ else
1632+ head_name = xstrdup (heads .items [0 ].string );
1633+ if (head_name ) {
1634+ strbuf_addf (& b_head , "refs/remotes/%s/HEAD" , remote );
1635+ strbuf_addf (& b_remote_head , "refs/remotes/%s/%s" , remote , head_name );
1636+ /* make sure it's valid */
1637+ if (!refs_ref_exists (refs , b_remote_head .buf ))
1638+ result = 1 ;
1639+ else if (refs_update_symref (refs , b_head .buf , b_remote_head .buf ,
1640+ "remote set-head" , & b_local_head , 1 ))
1641+ result = 1 ;
1642+ else
1643+ report_set_head (remote , head_name , & b_local_head );
1644+
1645+ free (head_name );
1646+ }
1647+
1648+ strbuf_release (& b_head );
1649+ strbuf_release (& b_local_head );
1650+ strbuf_release (& b_remote_head );
1651+ return result ;
1652+ }
1653+
15801654static int do_fetch (struct transport * transport ,
15811655 struct refspec * rs ,
15821656 const struct fetch_config * config )
@@ -1646,6 +1720,8 @@ static int do_fetch(struct transport *transport,
16461720 "refs/tags/" );
16471721 }
16481722
1723+ strvec_push (& transport_ls_refs_options .ref_prefixes , "HEAD" );
1724+
16491725 if (must_list_refs ) {
16501726 trace2_region_enter ("fetch" , "remote_refs" , the_repository );
16511727 remote_refs = transport_get_remote_refs (transport ,
@@ -1790,6 +1866,12 @@ static int do_fetch(struct transport *transport,
17901866 "you need to specify exactly one branch with the --set-upstream option" ));
17911867 }
17921868 }
1869+ if (set_head (remote_refs ))
1870+ ;
1871+ /*
1872+ * Way too many cases where this can go wrong
1873+ * so let's just fail silently for now.
1874+ */
17931875
17941876cleanup :
17951877 if (retcode ) {
0 commit comments