@@ -2525,7 +2525,7 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
25252525
25262526 git_buf_puts (out , " to " );
25272527
2528- if (git_reference__is_branch (new ))
2528+ if (git_reference__is_branch (new ) || git_reference__is_tag ( new ) )
25292529 git_buf_puts (out , git_reference__shorthand (new ));
25302530 else
25312531 git_buf_puts (out , new );
@@ -2536,6 +2536,41 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
25362536 return 0 ;
25372537}
25382538
2539+ static int detach (git_repository * repo , const git_oid * id , const char * new )
2540+ {
2541+ int error ;
2542+ git_buf log_message = GIT_BUF_INIT ;
2543+ git_object * object = NULL , * peeled = NULL ;
2544+ git_reference * new_head = NULL , * current = NULL ;
2545+
2546+ assert (repo && id );
2547+
2548+ if ((error = git_reference_lookup (& current , repo , GIT_HEAD_FILE )) < 0 )
2549+ return error ;
2550+
2551+ if ((error = git_object_lookup (& object , repo , id , GIT_OBJ_ANY )) < 0 )
2552+ goto cleanup ;
2553+
2554+ if ((error = git_object_peel (& peeled , object , GIT_OBJ_COMMIT )) < 0 )
2555+ goto cleanup ;
2556+
2557+ if (new == NULL )
2558+ new = git_oid_tostr_s (git_object_id (peeled ));
2559+
2560+ if ((error = checkout_message (& log_message , current , new )) < 0 )
2561+ goto cleanup ;
2562+
2563+ error = git_reference_create (& new_head , repo , GIT_HEAD_FILE , git_object_id (peeled ), true, git_buf_cstr (& log_message ));
2564+
2565+ cleanup :
2566+ git_buf_free (& log_message );
2567+ git_object_free (object );
2568+ git_object_free (peeled );
2569+ git_reference_free (current );
2570+ git_reference_free (new_head );
2571+ return error ;
2572+ }
2573+
25392574int git_repository_set_head (
25402575 git_repository * repo ,
25412576 const char * refname )
@@ -2567,7 +2602,8 @@ int git_repository_set_head(
25672602 error = git_reference_symbolic_create (& new_head , repo , GIT_HEAD_FILE ,
25682603 git_reference_name (ref ), true, git_buf_cstr (& log_message ));
25692604 } else {
2570- error = git_repository_set_head_detached (repo , git_reference_target (ref ));
2605+ error = detach (repo , git_reference_target (ref ),
2606+ git_reference_is_tag (ref ) ? refname : NULL );
25712607 }
25722608 } else if (git_reference__is_branch (refname )) {
25732609 error = git_reference_symbolic_create (& new_head , repo , GIT_HEAD_FILE , refname ,
@@ -2582,41 +2618,6 @@ int git_repository_set_head(
25822618 return error ;
25832619}
25842620
2585- static int detach (git_repository * repo , const git_oid * id , const char * from )
2586- {
2587- int error ;
2588- git_buf log_message = GIT_BUF_INIT ;
2589- git_object * object = NULL , * peeled = NULL ;
2590- git_reference * new_head = NULL , * current = NULL ;
2591-
2592- assert (repo && id );
2593-
2594- if ((error = git_reference_lookup (& current , repo , GIT_HEAD_FILE )) < 0 )
2595- return error ;
2596-
2597- if ((error = git_object_lookup (& object , repo , id , GIT_OBJ_ANY )) < 0 )
2598- goto cleanup ;
2599-
2600- if ((error = git_object_peel (& peeled , object , GIT_OBJ_COMMIT )) < 0 )
2601- goto cleanup ;
2602-
2603- if (from == NULL )
2604- from = git_oid_tostr_s (git_object_id (peeled ));
2605-
2606- if ((error = checkout_message (& log_message , current , from )) < 0 )
2607- goto cleanup ;
2608-
2609- error = git_reference_create (& new_head , repo , GIT_HEAD_FILE , git_object_id (peeled ), true, git_buf_cstr (& log_message ));
2610-
2611- cleanup :
2612- git_buf_free (& log_message );
2613- git_object_free (object );
2614- git_object_free (peeled );
2615- git_reference_free (current );
2616- git_reference_free (new_head );
2617- return error ;
2618- }
2619-
26202621int git_repository_set_head_detached (
26212622 git_repository * repo ,
26222623 const git_oid * commitish )
0 commit comments