@@ -683,41 +683,47 @@ void delete(RefDirectoryUpdate update) throws IOException {
683683 }
684684 String name = dst .getName ();
685685
686- // Write the packed-refs file using an atomic update. We might
687- // wind up reading it twice, before and after the lock, to ensure
688- // we don't miss an edit made externally.
689- PackedRefList packed = getPackedRefs ();
690- if (packed .contains (name )) {
691- inProcessPackedRefsLock .lock ();
686+ // Get and keep the packed-refs lock while updating packed-refs and
687+ // removing any loose ref
688+ inProcessPackedRefsLock .lock ();
689+ try {
690+ LockFile lck = lockPackedRefsOrThrow ();
692691 try {
693- LockFile lck = lockPackedRefsOrThrow ();
694- try {
692+ // Write the packed-refs file using an atomic update. We might
693+ // wind up reading it twice, before and after checking if the
694+ // ref to delete is included or not, to ensure
695+ // we don't rely on a PackedRefList that is a result of in-memory
696+ // or NFS caching.
697+ PackedRefList packed = getPackedRefs ();
698+ if (packed .contains (name )) {
699+ // Force update our packed-refs snapshot before writing
695700 packed = refreshPackedRefs ();
696701 int idx = packed .find (name );
697702 if (0 <= idx ) {
698703 commitPackedRefs (lck , packed .remove (idx ), packed , true );
699704 }
700- } finally {
701- lck .unlock ();
702705 }
703- } finally {
704- inProcessPackedRefsLock .unlock ();
705- }
706- }
707706
708- RefList <LooseRef > curLoose , newLoose ;
709- do {
710- curLoose = looseRefs .get ();
711- int idx = curLoose .find (name );
712- if (idx < 0 )
713- break ;
714- newLoose = curLoose .remove (idx );
715- } while (!looseRefs .compareAndSet (curLoose , newLoose ));
707+ RefList <LooseRef > curLoose , newLoose ;
708+ do {
709+ curLoose = looseRefs .get ();
710+ int idx = curLoose .find (name );
711+ if (idx < 0 ) {
712+ break ;
713+ }
714+ newLoose = curLoose .remove (idx );
715+ } while (!looseRefs .compareAndSet (curLoose , newLoose ));
716716
717- int levels = levelsIn (name ) - 2 ;
718- delete (logFor (name ), levels );
719- if (dst .getStorage ().isLoose ()) {
720- deleteAndUnlock (fileFor (name ), levels , update );
717+ int levels = levelsIn (name ) - 2 ;
718+ delete (logFor (name ), levels );
719+ if (dst .getStorage ().isLoose ()) {
720+ deleteAndUnlock (fileFor (name ), levels , update );
721+ }
722+ } finally {
723+ lck .unlock ();
724+ }
725+ } finally {
726+ inProcessPackedRefsLock .unlock ();
721727 }
722728
723729 modCnt .incrementAndGet ();
0 commit comments