@@ -1403,12 +1403,41 @@ static int show(int argc, const char **argv, const char *prefix,
14031403 return result ;
14041404}
14051405
1406+ static void report_set_head_auto (const char * remote , const char * head_name ,
1407+ struct strbuf * b_local_head , int was_detached ) {
1408+ struct strbuf buf_prefix = STRBUF_INIT ;
1409+ const char * prev_head = NULL ;
1410+
1411+ strbuf_addf (& buf_prefix , "refs/remotes/%s/" , remote );
1412+ skip_prefix (b_local_head -> buf , buf_prefix .buf , & prev_head );
1413+
1414+ if (prev_head && !strcmp (prev_head , head_name ))
1415+ printf (_ ("'%s/HEAD' is unchanged and points to '%s'\n" ),
1416+ remote , head_name );
1417+ else if (prev_head )
1418+ printf (_ ("'%s/HEAD' has changed from '%s' and now points to '%s'\n" ),
1419+ remote , prev_head , head_name );
1420+ else if (!b_local_head -> len )
1421+ printf (_ ("'%s/HEAD' is now created and points to '%s'\n" ),
1422+ remote , head_name );
1423+ else if (was_detached && b_local_head -> len )
1424+ printf (_ ("'%s/HEAD' was detached at '%s' and now points to '%s'\n" ),
1425+ remote , b_local_head -> buf , head_name );
1426+ else
1427+ printf (_ ("'%s/HEAD' used to point to '%s' "
1428+ "(which is not a remote branch), but now points to '%s'\n" ),
1429+ remote , b_local_head -> buf , head_name );
1430+ strbuf_release (& buf_prefix );
1431+ }
1432+
14061433static int set_head (int argc , const char * * argv , const char * prefix ,
14071434 struct repository * repo UNUSED )
14081435{
1409- int i , opt_a = 0 , opt_d = 0 , result = 0 ;
1410- struct strbuf buf = STRBUF_INIT , buf2 = STRBUF_INIT ;
1436+ int i , opt_a = 0 , opt_d = 0 , result = 0 , was_detached ;
1437+ struct strbuf b_head = STRBUF_INIT , b_remote_head = STRBUF_INIT ,
1438+ b_local_head = STRBUF_INIT ;
14111439 char * head_name = NULL ;
1440+ struct ref_store * refs = get_main_ref_store (the_repository );
14121441
14131442 struct option options [] = {
14141443 OPT_BOOL ('a' , "auto" , & opt_a ,
@@ -1420,7 +1449,7 @@ static int set_head(int argc, const char **argv, const char *prefix,
14201449 argc = parse_options (argc , argv , prefix , options ,
14211450 builtin_remote_sethead_usage , 0 );
14221451 if (argc )
1423- strbuf_addf (& buf , "refs/remotes/%s/HEAD" , argv [0 ]);
1452+ strbuf_addf (& b_head , "refs/remotes/%s/HEAD" , argv [0 ]);
14241453
14251454 if (!opt_a && !opt_d && argc == 2 ) {
14261455 head_name = xstrdup (argv [1 ]);
@@ -1439,25 +1468,32 @@ static int set_head(int argc, const char **argv, const char *prefix,
14391468 head_name = xstrdup (states .heads .items [0 ].string );
14401469 free_remote_ref_states (& states );
14411470 } else if (opt_d && !opt_a && argc == 1 ) {
1442- if (refs_delete_ref (get_main_ref_store ( the_repository ) , NULL , buf .buf , NULL , REF_NO_DEREF ))
1443- result |= error (_ ("Could not delete %s" ), buf .buf );
1471+ if (refs_delete_ref (refs , NULL , b_head .buf , NULL , REF_NO_DEREF ))
1472+ result |= error (_ ("Could not delete %s" ), b_head .buf );
14441473 } else
14451474 usage_with_options (builtin_remote_sethead_usage , options );
14461475
1447- if (head_name ) {
1448- strbuf_addf (& buf2 , "refs/remotes/%s/%s" , argv [0 ], head_name );
1449- /* make sure it's valid */
1450- if (!refs_ref_exists (get_main_ref_store (the_repository ), buf2 .buf ))
1451- result |= error (_ ("Not a valid ref: %s" ), buf2 .buf );
1452- else if (refs_update_symref (get_main_ref_store (the_repository ), buf .buf , buf2 .buf , "remote set-head" ))
1453- result |= error (_ ("Could not setup %s" ), buf .buf );
1454- else if (opt_a )
1455- printf ("%s/HEAD set to %s\n" , argv [0 ], head_name );
1456- free (head_name );
1476+ if (!head_name )
1477+ goto cleanup ;
1478+ strbuf_addf (& b_remote_head , "refs/remotes/%s/%s" , argv [0 ], head_name );
1479+ if (!refs_ref_exists (refs , b_remote_head .buf )) {
1480+ result |= error (_ ("Not a valid ref: %s" ), b_remote_head .buf );
1481+ goto cleanup ;
14571482 }
1458-
1459- strbuf_release (& buf );
1460- strbuf_release (& buf2 );
1483+ was_detached = refs_update_symref_extended (refs , b_head .buf , b_remote_head .buf ,
1484+ "remote set-head" , & b_local_head , 0 );
1485+ if (was_detached == -1 ) {
1486+ result |= error (_ ("Could not set up %s" ), b_head .buf );
1487+ goto cleanup ;
1488+ }
1489+ if (opt_a )
1490+ report_set_head_auto (argv [0 ], head_name , & b_local_head , was_detached );
1491+
1492+ cleanup :
1493+ free (head_name );
1494+ strbuf_release (& b_head );
1495+ strbuf_release (& b_remote_head );
1496+ strbuf_release (& b_local_head );
14611497 return result ;
14621498}
14631499
0 commit comments