@@ -701,41 +701,47 @@ void delete(RefDirectoryUpdate update) throws IOException {
701701 }
702702 String name = dst .getName ();
703703
704- // Write the packed-refs file using an atomic update. We might
705- // wind up reading it twice, before and after the lock, to ensure
706- // we don't miss an edit made externally.
707- PackedRefList packed = getPackedRefs ();
708- if (packed .contains (name )) {
709- inProcessPackedRefsLock .lock ();
704+ // Get and keep the packed-refs lock while updating packed-refs and
705+ // removing any loose ref
706+ inProcessPackedRefsLock .lock ();
707+ try {
708+ LockFile lck = lockPackedRefsOrThrow ();
710709 try {
711- LockFile lck = lockPackedRefsOrThrow ();
712- try {
710+ // Write the packed-refs file using an atomic update. We might
711+ // wind up reading it twice, before and after checking if the
712+ // ref to delete is included or not, to ensure
713+ // we don't rely on a PackedRefList that is a result of in-memory
714+ // or NFS caching.
715+ PackedRefList packed = getPackedRefs ();
716+ if (packed .contains (name )) {
717+ // Force update our packed-refs snapshot before writing
713718 packed = refreshPackedRefs ();
714719 int idx = packed .find (name );
715720 if (0 <= idx ) {
716721 commitPackedRefs (lck , packed .remove (idx ), packed , true );
717722 }
718- } finally {
719- lck .unlock ();
720723 }
721- } finally {
722- inProcessPackedRefsLock .unlock ();
723- }
724- }
725724
726- RefList <LooseRef > curLoose , newLoose ;
727- do {
728- curLoose = looseRefs .get ();
729- int idx = curLoose .find (name );
730- if (idx < 0 )
731- break ;
732- newLoose = curLoose .remove (idx );
733- } while (!looseRefs .compareAndSet (curLoose , newLoose ));
725+ RefList <LooseRef > curLoose , newLoose ;
726+ do {
727+ curLoose = looseRefs .get ();
728+ int idx = curLoose .find (name );
729+ if (idx < 0 ) {
730+ break ;
731+ }
732+ newLoose = curLoose .remove (idx );
733+ } while (!looseRefs .compareAndSet (curLoose , newLoose ));
734734
735- int levels = levelsIn (name ) - 2 ;
736- delete (logFor (name ), levels );
737- if (dst .getStorage ().isLoose ()) {
738- deleteAndUnlock (fileFor (name ), levels , update );
735+ int levels = levelsIn (name ) - 2 ;
736+ delete (logFor (name ), levels );
737+ if (dst .getStorage ().isLoose ()) {
738+ deleteAndUnlock (fileFor (name ), levels , update );
739+ }
740+ } finally {
741+ lck .unlock ();
742+ }
743+ } finally {
744+ inProcessPackedRefsLock .unlock ();
739745 }
740746
741747 modCnt .incrementAndGet ();
0 commit comments