@@ -921,25 +921,33 @@ static int repack_without_ref(const char *refname)
921921 return commit_lock_file (& packlock );
922922}
923923
924- int delete_ref (const char * refname , const unsigned char * sha1 )
924+ int delete_ref (const char * refname , const unsigned char * sha1 , int delopt )
925925{
926926 struct ref_lock * lock ;
927- int err , i , ret = 0 , flag = 0 ;
927+ int err , i = 0 , ret = 0 , flag = 0 ;
928928
929929 lock = lock_ref_sha1_basic (refname , sha1 , 0 , & flag );
930930 if (!lock )
931931 return 1 ;
932- if (!(flag & REF_ISPACKED )) {
932+ if (!(flag & REF_ISPACKED ) || flag & REF_ISSYMREF ) {
933933 /* loose */
934- i = strlen (lock -> lk -> filename ) - 5 ; /* .lock */
935- lock -> lk -> filename [i ] = 0 ;
936- err = unlink (lock -> lk -> filename );
934+ const char * path ;
935+
936+ if (!(delopt & REF_NODEREF )) {
937+ i = strlen (lock -> lk -> filename ) - 5 ; /* .lock */
938+ lock -> lk -> filename [i ] = 0 ;
939+ path = lock -> lk -> filename ;
940+ } else {
941+ path = git_path (refname );
942+ }
943+ err = unlink (path );
937944 if (err && errno != ENOENT ) {
938945 ret = 1 ;
939946 error ("unlink(%s) failed: %s" ,
940- lock -> lk -> filename , strerror (errno ));
947+ path , strerror (errno ));
941948 }
942- lock -> lk -> filename [i ] = '.' ;
949+ if (!(delopt & REF_NODEREF ))
950+ lock -> lk -> filename [i ] = '.' ;
943951 }
944952 /* removing the loose one could have resurrected an earlier
945953 * packed one. Also, if it was not loose we need to repack
@@ -964,11 +972,16 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
964972 struct ref_lock * lock ;
965973 struct stat loginfo ;
966974 int log = !lstat (git_path ("logs/%s" , oldref ), & loginfo );
975+ const char * symref = NULL ;
967976
968- if (S_ISLNK (loginfo .st_mode ))
977+ if (log && S_ISLNK (loginfo .st_mode ))
969978 return error ("reflog for %s is a symlink" , oldref );
970979
971- if (!resolve_ref (oldref , orig_sha1 , 1 , & flag ))
980+ symref = resolve_ref (oldref , orig_sha1 , 1 , & flag );
981+ if (flag & REF_ISSYMREF )
982+ return error ("refname %s is a symbolic ref, renaming it is not supported" ,
983+ oldref );
984+ if (!symref )
972985 return error ("refname %s not found" , oldref );
973986
974987 if (!is_refname_available (newref , oldref , get_packed_refs (), 0 ))
@@ -988,12 +1001,12 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
9881001 return error ("unable to move logfile logs/%s to tmp-renamed-log: %s" ,
9891002 oldref , strerror (errno ));
9901003
991- if (delete_ref (oldref , orig_sha1 )) {
1004+ if (delete_ref (oldref , orig_sha1 , REF_NODEREF )) {
9921005 error ("unable to delete old %s" , oldref );
9931006 goto rollback ;
9941007 }
9951008
996- if (resolve_ref (newref , sha1 , 1 , & flag ) && delete_ref (newref , sha1 )) {
1009+ if (resolve_ref (newref , sha1 , 1 , & flag ) && delete_ref (newref , sha1 , REF_NODEREF )) {
9971010 if (errno == EISDIR ) {
9981011 if (remove_empty_directories (git_path ("%s" , newref ))) {
9991012 error ("Directory not empty: %s" , newref );
@@ -1036,7 +1049,6 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
10361049 error ("unable to lock %s for update" , newref );
10371050 goto rollback ;
10381051 }
1039-
10401052 lock -> force_write = 1 ;
10411053 hashcpy (lock -> old_sha1 , orig_sha1 );
10421054 if (write_ref_sha1 (lock , orig_sha1 , logmsg )) {
0 commit comments