Merge "PackedBatchRefUpdate: hold inProcessPackedRefsLock across pack step"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
index 4dc40df..79f2013 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
@@ -1533,6 +1533,25 @@ public void testCommonRefPrefix() {
StringUtils.commonPrefix("refs/heads/", "refs/heads/main"));
}
+ @Test
+ public void testPackDoesNotUnlockHeldLocks() throws IOException {
+ String ref = "refs/heads/master";
+ writeLooseRef(ref, A);
+
+ File refFile = refdir.fileFor(ref);
+ LockFile held = new LockFile(refFile);
+ assertTrue("must acquire lock", held.lock());
+ try {
+ refdir.pack(Map.of(ref, held));
+ assertFalse("loose ref must be deleted after packing",
+ refFile.exists());
+ assertTrue("held lock must still be locked after pack()",
+ held.isLocked());
+ } finally {
+ held.unlock();
+ }
+ }
+
void writePackedRef(String name, AnyObjectId id) throws IOException {
writePackedRefs(id.name() + " " + name + "\n");
}
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 a9211fe..d5ac5aa 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
@@ -876,8 +876,13 @@ private void pack(Collection<String> refs,
}
newLoose = curLoose.remove(idx);
} while (!looseRefs.compareAndSet(curLoose, newLoose));
- int levels = levelsIn(refName) - 2;
- deleteAndUnlock(refFile, levels, rLck);
+ if (shouldUnlock) {
+ int levels = levelsIn(refName) - 2;
+ deleteAndUnlock(refFile, levels, rLck);
+ shouldUnlock = false;
+ } else {
+ delete(refFile);
+ }
LOG.debug(JGitText.get().deleteLooseRef, refFile, clr_oid);
}
} finally {