aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2025-06-03 09:51:47 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2025-06-03 09:51:47 +0200
commit886849c68380579e5ea361c600a63389992f7b3c (patch)
treee10517ccb97007e4631640cbb757a8aeece2aa89
parent804b3c23dba535058fd71d3468c5545fb32d8142 (diff)
parent6e0db8377b5fba2988d8ade84011ea07ee06414e (diff)
downloadjgit-886849c68380579e5ea361c600a63389992f7b3c.tar.gz
jgit-886849c68380579e5ea361c600a63389992f7b3c.zip
Merge branch 'stable-7.1' into stable-7.2
* stable-7.1: Use the same ordering/locking in delete() as C git Change-Id: Id52c938b041604162dca9162726bfb594e96f5d1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java58
1 files changed, 32 insertions, 26 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index 05f1ef53a1..319a9ed710 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -701,41 +701,47 @@ public class RefDirectory extends RefDatabase {
}
String name = dst.getName();
- // Write the packed-refs file using an atomic update. We might
- // wind up reading it twice, before and after the lock, to ensure
- // we don't miss an edit made externally.
- PackedRefList packed = getPackedRefs();
- if (packed.contains(name)) {
- inProcessPackedRefsLock.lock();
+ // Get and keep the packed-refs lock while updating packed-refs and
+ // removing any loose ref
+ inProcessPackedRefsLock.lock();
+ try {
+ LockFile lck = lockPackedRefsOrThrow();
try {
- LockFile lck = lockPackedRefsOrThrow();
- try {
+ // Write the packed-refs file using an atomic update. We might
+ // wind up reading it twice, before and after checking if the
+ // ref to delete is included or not, to ensure
+ // we don't rely on a PackedRefList that is a result of in-memory
+ // or NFS caching.
+ PackedRefList packed = getPackedRefs();
+ if (packed.contains(name)) {
+ // Force update our packed-refs snapshot before writing
packed = refreshPackedRefs();
int idx = packed.find(name);
if (0 <= idx) {
commitPackedRefs(lck, packed.remove(idx), packed, true);
}
- } finally {
- lck.unlock();
}
- } finally {
- inProcessPackedRefsLock.unlock();
- }
- }
- RefList<LooseRef> curLoose, newLoose;
- do {
- curLoose = looseRefs.get();
- int idx = curLoose.find(name);
- if (idx < 0)
- break;
- newLoose = curLoose.remove(idx);
- } while (!looseRefs.compareAndSet(curLoose, newLoose));
+ RefList<LooseRef> curLoose, newLoose;
+ do {
+ curLoose = looseRefs.get();
+ int idx = curLoose.find(name);
+ if (idx < 0) {
+ break;
+ }
+ newLoose = curLoose.remove(idx);
+ } while (!looseRefs.compareAndSet(curLoose, newLoose));
- int levels = levelsIn(name) - 2;
- delete(logFor(name), levels);
- if (dst.getStorage().isLoose()) {
- deleteAndUnlock(fileFor(name), levels, update);
+ int levels = levelsIn(name) - 2;
+ delete(logFor(name), levels);
+ if (dst.getStorage().isLoose()) {
+ deleteAndUnlock(fileFor(name), levels, update);
+ }
+ } finally {
+ lck.unlock();
+ }
+ } finally {
+ inProcessPackedRefsLock.unlock();
}
modCnt.incrementAndGet();