@@ -1702,6 +1702,42 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks)
17021702 return error ;
17031703}
17041704
1705+ static int update_ref (
1706+ const git_remote * remote ,
1707+ const char * ref_name ,
1708+ git_oid * id ,
1709+ const char * msg ,
1710+ const git_remote_callbacks * callbacks )
1711+ {
1712+ git_reference * ref ;
1713+ git_oid old_id ;
1714+ int error ;
1715+
1716+ error = git_reference_name_to_id (& old_id , remote -> repo , ref_name );
1717+
1718+ if (error < 0 && error != GIT_ENOTFOUND )
1719+ return error ;
1720+ else if (error == 0 && git_oid_equal (& old_id , id ))
1721+ return 0 ;
1722+
1723+ /* If we did find a current reference, make sure we haven't lost a race */
1724+ if (error )
1725+ error = git_reference_create (& ref , remote -> repo , ref_name , id , true, msg );
1726+ else
1727+ error = git_reference_create_matching (& ref , remote -> repo , ref_name , id , true, & old_id , msg );
1728+
1729+ git_reference_free (ref );
1730+
1731+ if (error < 0 )
1732+ return error ;
1733+
1734+ if (callbacks && callbacks -> update_tips &&
1735+ (error = callbacks -> update_tips (ref_name , & old_id , id , callbacks -> payload )) < 0 )
1736+ return error ;
1737+
1738+ return 0 ;
1739+ }
1740+
17051741static int update_tips_for_spec (
17061742 git_remote * remote ,
17071743 const git_remote_callbacks * callbacks ,
@@ -1908,14 +1944,12 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call
19081944 size_t i , j , k ;
19091945 git_refspec * spec ;
19101946 git_remote_head * head ;
1911- git_reference * ref ;
19121947 git_str refname = GIT_STR_INIT ;
19131948 int error = 0 ;
19141949
19151950 i = j = k = 0 ;
19161951
19171952 while ((error = next_head (remote , refs , & spec , & head , & i , & j , & k )) == 0 ) {
1918- git_oid old = {{ 0 }};
19191953 /*
19201954 * If we got here, there is a refspec which was used
19211955 * for fetching which matches the source of one of the
@@ -1925,29 +1959,9 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call
19251959 */
19261960
19271961 git_str_clear (& refname );
1928- if ((error = git_refspec__transform (& refname , spec , head -> name )) < 0 )
1929- goto cleanup ;
1930-
1931- error = git_reference_name_to_id (& old , remote -> repo , refname .ptr );
1932- if (error < 0 && error != GIT_ENOTFOUND )
1962+ if ((error = git_refspec__transform (& refname , spec , head -> name )) < 0 ||
1963+ (error = update_ref (remote , refname .ptr , & head -> oid , msg , callbacks )) < 0 )
19331964 goto cleanup ;
1934-
1935- if (!git_oid_cmp (& old , & head -> oid ))
1936- continue ;
1937-
1938- /* If we did find a current reference, make sure we haven't lost a race */
1939- if (error )
1940- error = git_reference_create (& ref , remote -> repo , refname .ptr , & head -> oid , true, msg );
1941- else
1942- error = git_reference_create_matching (& ref , remote -> repo , refname .ptr , & head -> oid , true, & old , msg );
1943- git_reference_free (ref );
1944- if (error < 0 )
1945- goto cleanup ;
1946-
1947- if (callbacks && callbacks -> update_tips != NULL ) {
1948- if (callbacks -> update_tips (refname .ptr , & old , & head -> oid , callbacks -> payload ) < 0 )
1949- goto cleanup ;
1950- }
19511965 }
19521966
19531967 if (error == GIT_ITEROVER )
@@ -2018,7 +2032,7 @@ int git_remote_update_tips(
20182032 goto out ;
20192033 }
20202034
2021- /* Only try to do opportunistic updates if the refpec lists differ. */
2035+ /* Only try to do opportunistic updates if the refspec lists differ. */
20222036 if (remote -> passed_refspecs )
20232037 error = opportunistic_updates (remote , callbacks , & refs , reflog_message );
20242038
0 commit comments