From 67b98d5d40d3d531c2383bbc13d7d93abc7d1b8e Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Mon, 18 Mar 2013 13:20:11 +0100 Subject: Make GC more robust against corrupt reflogs With JGit it is possible to write reflog entries where new objectid and old objectid is null. Such reflogs cause FileRepository GC to crash because it doesn't expect the new objectid to be null. One case where this happened is in Gerrit's allProjects repo. In the same way as we expect the old objectid to be potentially null we should also ignore null values in the new objectid column. Change-Id: Icf666c7ef803179b84306ca8deb602369b8df16e --- .../eclipse/jgit/internal/storage/file/GCTest.java | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'org.eclipse.jgit.test') diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTest.java index 8f26f7058d..bc60f64886 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTest.java @@ -49,8 +49,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.File; -import java.util.Collection; import java.io.IOException; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Iterator; @@ -62,6 +62,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.jgit.api.Git; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.internal.storage.file.GC; @@ -76,9 +77,9 @@ import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository.BranchBuilder; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.junit.TestRepository.CommitBuilder; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.EmptyProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref.Storage; @@ -436,6 +437,20 @@ public class GCTest extends LocalDiskRepositoryTestCase { assertEquals(1, stats.numberOfPackFiles); } + @Test + public void testPackRepoWithCorruptReflog() throws Exception { + // create a reflog entry "0000... 0000... foobar" by doing an initial + // refupdate for HEAD which points to a non-existing ref. The + // All-Projects repo of gerrit instances had such entries + RefUpdate ru = repo.updateRef(Constants.HEAD); + ru.link("refs/to/garbage"); + tr.branch("refs/heads/master").commit().add("A", "A").add("B", "B") + .create(); + // make sure HEAD exists + Git.wrap(repo).checkout().setName("refs/heads/master").call(); + gc.gc(); + } + @Test public void testKeepFiles() throws Exception { BranchBuilder bb = tr.branch("refs/heads/master"); @@ -477,9 +492,10 @@ public class GCTest extends LocalDiskRepositoryTestCase { assertEquals(4, ind2.getObjectCount()); for (MutableEntry e: ind1) if (ind2.hasObject(e.toObjectId())) - assertFalse( - "the following object is in both packfiles: " - + e.toObjectId(), ind2.hasObject(e.toObjectId())); + assertFalse( + "the following object is in both packfiles: " + + e.toObjectId(), + ind2.hasObject(e.toObjectId())); } @Test -- cgit v1.2.3