@@ -2532,7 +2532,9 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
25322532
25332533 git_buf_puts (out , " to " );
25342534
2535- if (git_reference__is_branch (new ))
2535+ if (git_reference__is_branch (new ) ||
2536+ git_reference__is_tag (new ) ||
2537+ git_reference__is_remote (new ))
25362538 git_buf_puts (out , git_reference__shorthand (new ));
25372539 else
25382540 git_buf_puts (out , new );
@@ -2543,6 +2545,41 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
25432545 return 0 ;
25442546}
25452547
2548+ static int detach (git_repository * repo , const git_oid * id , const char * new )
2549+ {
2550+ int error ;
2551+ git_buf log_message = GIT_BUF_INIT ;
2552+ git_object * object = NULL , * peeled = NULL ;
2553+ git_reference * new_head = NULL , * current = NULL ;
2554+
2555+ assert (repo && id );
2556+
2557+ if ((error = git_reference_lookup (& current , repo , GIT_HEAD_FILE )) < 0 )
2558+ return error ;
2559+
2560+ if ((error = git_object_lookup (& object , repo , id , GIT_OBJ_ANY )) < 0 )
2561+ goto cleanup ;
2562+
2563+ if ((error = git_object_peel (& peeled , object , GIT_OBJ_COMMIT )) < 0 )
2564+ goto cleanup ;
2565+
2566+ if (new == NULL )
2567+ new = git_oid_tostr_s (git_object_id (peeled ));
2568+
2569+ if ((error = checkout_message (& log_message , current , new )) < 0 )
2570+ goto cleanup ;
2571+
2572+ error = git_reference_create (& new_head , repo , GIT_HEAD_FILE , git_object_id (peeled ), true, git_buf_cstr (& log_message ));
2573+
2574+ cleanup :
2575+ git_buf_free (& log_message );
2576+ git_object_free (object );
2577+ git_object_free (peeled );
2578+ git_reference_free (current );
2579+ git_reference_free (new_head );
2580+ return error ;
2581+ }
2582+
25462583int git_repository_set_head (
25472584 git_repository * repo ,
25482585 const char * refname )
@@ -2576,7 +2613,8 @@ int git_repository_set_head(
25762613 error = git_reference_symbolic_create (& new_head , repo , GIT_HEAD_FILE ,
25772614 git_reference_name (ref ), true, git_buf_cstr (& log_message ));
25782615 } else {
2579- error = git_repository_set_head_detached (repo , git_reference_target (ref ));
2616+ error = detach (repo , git_reference_target (ref ),
2617+ git_reference_is_tag (ref ) || git_reference_is_remote (ref ) ? refname : NULL );
25802618 }
25812619 } else if (git_reference__is_branch (refname )) {
25822620 error = git_reference_symbolic_create (& new_head , repo , GIT_HEAD_FILE , refname ,
@@ -2591,41 +2629,6 @@ int git_repository_set_head(
25912629 return error ;
25922630}
25932631
2594- static int detach (git_repository * repo , const git_oid * id , const char * from )
2595- {
2596- int error ;
2597- git_buf log_message = GIT_BUF_INIT ;
2598- git_object * object = NULL , * peeled = NULL ;
2599- git_reference * new_head = NULL , * current = NULL ;
2600-
2601- assert (repo && id );
2602-
2603- if ((error = git_reference_lookup (& current , repo , GIT_HEAD_FILE )) < 0 )
2604- return error ;
2605-
2606- if ((error = git_object_lookup (& object , repo , id , GIT_OBJ_ANY )) < 0 )
2607- goto cleanup ;
2608-
2609- if ((error = git_object_peel (& peeled , object , GIT_OBJ_COMMIT )) < 0 )
2610- goto cleanup ;
2611-
2612- if (from == NULL )
2613- from = git_oid_tostr_s (git_object_id (peeled ));
2614-
2615- if ((error = checkout_message (& log_message , current , from )) < 0 )
2616- goto cleanup ;
2617-
2618- error = git_reference_create (& new_head , repo , GIT_HEAD_FILE , git_object_id (peeled ), true, git_buf_cstr (& log_message ));
2619-
2620- cleanup :
2621- git_buf_free (& log_message );
2622- git_object_free (object );
2623- git_object_free (peeled );
2624- git_reference_free (current );
2625- git_reference_free (new_head );
2626- return error ;
2627- }
2628-
26292632int git_repository_set_head_detached (
26302633 git_repository * repo ,
26312634 const git_oid * commitish )
0 commit comments