2727
2828bool git_reference__enable_symbolic_ref_target_validation = true;
2929
30- #define DEFAULT_NESTING_LEVEL 5
31- #define MAX_NESTING_LEVEL 10
32-
3330enum {
3431 GIT_PACKREF_HAS_PEEL = 1 ,
3532 GIT_PACKREF_WAS_LOOSE = 2
@@ -1131,40 +1128,6 @@ int git_reference_cmp(
11311128 return git_oid__cmp (& ref1 -> target .oid , & ref2 -> target .oid );
11321129}
11331130
1134- /**
1135- * Get the end of a chain of references. If the final one is not
1136- * found, we return the reference just before that.
1137- */
1138- static int get_terminal (git_reference * * out , git_repository * repo , const char * ref_name , int nesting )
1139- {
1140- git_reference * ref ;
1141- int error = 0 ;
1142-
1143- if (nesting > MAX_NESTING_LEVEL ) {
1144- git_error_set (GIT_ERROR_REFERENCE , "reference chain too deep (%d)" , nesting );
1145- return GIT_ENOTFOUND ;
1146- }
1147-
1148- /* set to NULL to let the caller know that they're at the end of the chain */
1149- if ((error = git_reference_lookup (& ref , repo , ref_name )) < 0 ) {
1150- * out = NULL ;
1151- return error ;
1152- }
1153-
1154- if (git_reference_type (ref ) == GIT_REFERENCE_DIRECT ) {
1155- * out = ref ;
1156- error = 0 ;
1157- } else {
1158- error = get_terminal (out , repo , git_reference_symbolic_target (ref ), nesting + 1 );
1159- if (error == GIT_ENOTFOUND && !* out )
1160- * out = ref ;
1161- else
1162- git_reference_free (ref );
1163- }
1164-
1165- return error ;
1166- }
1167-
11681131/*
11691132 * Starting with the reference given by `ref_name`, follows symbolic
11701133 * references until a direct reference is found and updated the OID
@@ -1179,31 +1142,37 @@ int git_reference__update_terminal(
11791142{
11801143 git_reference * ref = NULL , * ref2 = NULL ;
11811144 git_signature * who = NULL ;
1145+ git_refdb * refdb = NULL ;
11821146 const git_signature * to_use ;
11831147 int error = 0 ;
11841148
11851149 if (!sig && (error = git_reference__log_signature (& who , repo )) < 0 )
1186- return error ;
1150+ goto out ;
11871151
11881152 to_use = sig ? sig : who ;
1189- error = get_terminal (& ref , repo , ref_name , 0 );
11901153
1191- /* found a dangling symref */
1192- if (error == GIT_ENOTFOUND && ref ) {
1193- assert (git_reference_type (ref ) == GIT_REFERENCE_SYMBOLIC );
1194- git_error_clear ();
1154+ if ((error = git_repository_refdb__weakptr (& refdb , repo )) < 0 )
1155+ goto out ;
1156+
1157+ if ((error = git_refdb_resolve (& ref , refdb , ref_name , -1 )) < 0 ) {
1158+ if (error == GIT_ENOTFOUND ) {
1159+ git_error_clear ();
1160+ error = reference__create (& ref2 , repo , ref_name , oid , NULL , 0 , to_use ,
1161+ log_message , NULL , NULL );
1162+ }
1163+ goto out ;
1164+ }
1165+
1166+ /* In case the resolved reference is symbolic, then it's a dangling symref. */
1167+ if (git_reference_type (ref ) == GIT_REFERENCE_SYMBOLIC ) {
11951168 error = reference__create (& ref2 , repo , ref -> target .symbolic , oid , NULL , 0 , to_use ,
11961169 log_message , NULL , NULL );
1197- } else if (error == GIT_ENOTFOUND ) {
1198- git_error_clear ();
1199- error = reference__create (& ref2 , repo , ref_name , oid , NULL , 0 , to_use ,
1200- log_message , NULL , NULL );
1201- } else if (error == 0 ) {
1202- assert (git_reference_type (ref ) == GIT_REFERENCE_DIRECT );
1170+ } else {
12031171 error = reference__create (& ref2 , repo , ref -> name , oid , NULL , 1 , to_use ,
12041172 log_message , & ref -> target .oid , NULL );
12051173 }
12061174
1175+ out :
12071176 git_reference_free (ref2 );
12081177 git_reference_free (ref );
12091178 git_signature_free (who );
0 commit comments