Merge branch 'stable-5.6' * stable-5.6: reftable: don't check deadline on the first try reftable: clarify comment reftable: clear cache on full compaction reftable: remove outdated comment reftable: clarify that LogCursor may return a null ReflogEntry Change-Id: I9458a746311984fa687b3da964805e2568ed37f3
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java index 9da3507..b13cdb9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
@@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; @@ -510,6 +511,43 @@ public void testRenameAtomic() throws IOException { } @Test + public void compactFully() throws Exception { + FileReftableDatabase refDb = (FileReftableDatabase) db.getRefDatabase(); + PersonIdent person = new PersonIdent("jane", "jane@invalid"); + + ObjectId aId = db.exactRef("refs/heads/a").getObjectId(); + ObjectId bId = db.exactRef("refs/heads/b").getObjectId(); + + SecureRandom random = new SecureRandom(); + List<String> strs = new ArrayList<>(); + for (int i = 0; i < 1024; i++) { + strs.add(String.format("%02x", + Integer.valueOf(random.nextInt(256)))); + } + + String randomStr = String.join("", strs); + String refName = "branch"; + for (long i = 0; i < 2; i++) { + RefUpdate ru = refDb.newUpdate(refName, false); + ru.setNewObjectId(i % 2 == 0 ? aId : bId); + ru.setForceUpdate(true); + // Only write a large string in the first table, so it becomes much larger + // than the second, and the result is not autocompacted. + ru.setRefLogMessage(i == 0 ? randomStr : "short", false); + ru.setRefLogIdent(person); + + RefUpdate.Result res = ru.update(); + assertTrue(res == Result.NEW || res == FORCED); + } + + assertEquals(refDb.exactRef(refName).getObjectId(), bId); + assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment())); + refDb.compactFully(); + assertEquals(refDb.exactRef(refName).getObjectId(), bId); + assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment())); + } + + @Test public void reftableRefsStorageClass() throws IOException { Ref b = db.exactRef("refs/heads/b"); assertEquals(Ref.Storage.PACKED, b.getStorage());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java index dc9c28c..aea14de 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
@@ -106,6 +106,7 @@ public void compactFully() throws IOException { reftableDatabase.getLock().lock(); try { reftableStack.compactFully(); + reftableDatabase.clearCache(); } finally { reftableDatabase.getLock().unlock(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java index 5b540bd..4cb0bd3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
@@ -237,8 +237,13 @@ void reload() throws IOException { long max = 1000; long delay = 0; boolean success = false; - while (System.currentTimeMillis() < deadline) { + + // Don't check deadline for the first 3 retries, so we can step with a + // debugger without worrying about deadlines. + int tries = 0; + while (tries < 3 || System.currentTimeMillis() < deadline) { List<String> names = readTableNames(); + tries++; try { reloadOnce(names); success = true; @@ -260,9 +265,6 @@ void reload() throws IOException { } if (!success) { - // TODO: should reexamine the 'refs' file to see if it was the same - // if it didn't change, then we must have corruption. If it did, - // retry. throw new LockFailedException(stackPath); } @@ -374,7 +376,7 @@ private String filename(long low, long high) { * * @param w * writer to write data to a reftable under construction - * @return true if the transaction. + * @return true if the transaction was successful. * @throws IOException * on I/O problems */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java index 9d410ae..f78975a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
@@ -12,6 +12,7 @@ import java.io.IOException; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lib.ReflogEntry; /** @@ -45,8 +46,9 @@ public abstract class LogCursor implements AutoCloseable { /** * Get current log entry. * - * @return current log entry. + * @return current log entry. Maybe null if we are producing deletions. */ + @Nullable public abstract ReflogEntry getReflogEntry(); /** {@inheritDoc} */