From 8da939221c2e244fe0ba979fa8419a90bf618315 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Mon, 11 Nov 2013 10:57:46 +0100 Subject: Don't delete .idx file if .pack file can't be deleted If during an garbage collection old packfiles are deleted it could happen that on certain platforms the index file can be deleted but the packfile can't be deleted (because someone locked the file). This led to repositories with packfiles without corresponding index files. Those zombie-packfiles potentially consume a lot of space on disk and it is never tried to delete them again. Try to avoid this situation by deleting packfiles first and don't try to delete the other files if we can't delete the packfile. This gives us the chance to delete the packfile during next GC. This commit only improves the situation - there is still the chance for orphan files during packfile deletion. We don't have an atomic delete of multiple files . Change-Id: I0a19ae630186f07d0cc7fe9df246fa1cedeca8f6 --- .../eclipse/jgit/internal/storage/file/GCTest.java | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) (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 9d2a03b097..35455f48a9 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,6 +49,7 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; import java.util.Collections; @@ -66,6 +67,7 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.GC.RepoStatistics; import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry; +import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; @@ -620,6 +622,40 @@ public class GCTest extends LocalDiskRepositoryTestCase { assertEquals(2, stats.numberOfPackFiles); } + @Test + public void testPruneOldPacksWithOpenHandleOnPack() throws Exception { + gc.setExpireAgeMillis(0); + + BranchBuilder bb = tr.branch("refs/heads/master"); + bb.commit().add("A", "A").add("B", "B").create(); + fsTick(); + gc.gc(); + + Collection packs = repo.getObjectDatabase().getPacks(); + assertEquals(1, packs.size()); + PackFile pack = packs.iterator().next(); + File packFile = pack.getPackFile(); + File indexFile = new File(packFile.getParentFile(), "pack-" + + pack.getPackName() + + "." + + PackExt.INDEX.getExtension()); + FileInputStream fis = new FileInputStream(packFile); + try { + bb.commit().add("A", "A2").add("B", "B2").create(); + fsTick(); + gc.gc(); + if (packFile.exists()) { + assertTrue( + "The pack was present but the index file was missing.", + indexFile.exists()); + } + + } finally { + fis.close(); + } + + } + @Test public void testPackCommitsAndLooseOneWithPruneNowNoReflog() throws Exception { -- cgit v1.2.3