If set, "singlePack" will create a single GC pack file for all objects reachable from refs/*. If not set, the GC pack will contain object reachable from refs/heads/* and refs/tags/*, and the GC_REST pack will contain all other reachable objects. Change-Id: I56bcb6a9da2c10a0909c2f940c025db6f3acebcb Signed-off-by: Terry Parker <tparker@google.com>tags/v4.9.0.201710071750-r
@@ -31,6 +31,7 @@ import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
/** Tests for pack creation and garbage expiration. */ | |||
public class DfsGarbageCollectorTest { | |||
private TestRepository<InMemoryRepository> git; | |||
private InMemoryRepository repo; | |||
@@ -632,6 +633,26 @@ public class DfsGarbageCollectorTest { | |||
} | |||
} | |||
@Test | |||
public void testSinglePackForAllRefs() throws Exception { | |||
RevCommit commit0 = commit().message("0").create(); | |||
git.update("head", commit0); | |||
RevCommit commit1 = commit().message("1").parent(commit0).create(); | |||
git.update("refs/notes/note1", commit1); | |||
DfsGarbageCollector gc = new DfsGarbageCollector(repo); | |||
gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); | |||
gc.getPackConfig().setSinglePack(true); | |||
run(gc); | |||
assertEquals(1, odb.getPacks().length); | |||
gc = new DfsGarbageCollector(repo); | |||
gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); | |||
gc.getPackConfig().setSinglePack(false); | |||
run(gc); | |||
assertEquals(2, odb.getPacks().length); | |||
} | |||
private TestRepository<InMemoryRepository>.CommitBuilder commit() { | |||
return git.commit(); | |||
} |
@@ -274,6 +274,12 @@ public class DfsGarbageCollector { | |||
// Hoist all branch tips and tags earlier in the pack file | |||
tagTargets.addAll(allHeadsAndTags); | |||
// Combine the GC_REST objects into the GC pack if requested | |||
if (packConfig.getSinglePack()) { | |||
allHeadsAndTags.addAll(nonHeads); | |||
nonHeads.clear(); | |||
} | |||
boolean rollback = true; | |||
try { | |||
packHeads(pm); |
@@ -865,6 +865,12 @@ public class GC { | |||
tagTargets.addAll(allHeadsAndTags); | |||
nonHeads.addAll(indexObjects); | |||
// Combine the GC_REST objects into the GC pack if requested | |||
if (pconfig != null && pconfig.getSinglePack()) { | |||
allHeadsAndTags.addAll(nonHeads); | |||
nonHeads.clear(); | |||
} | |||
List<PackFile> ret = new ArrayList<>(2); | |||
PackFile heads = null; | |||
if (!allHeadsAndTags.isEmpty()) { |
@@ -260,6 +260,8 @@ public class PackConfig { | |||
private boolean cutDeltaChains; | |||
private boolean singlePack; | |||
/** Create a default configuration. */ | |||
public PackConfig() { | |||
// Fields are initialized to defaults. | |||
@@ -320,6 +322,7 @@ public class PackConfig { | |||
this.bitmapExcessiveBranchCount = cfg.bitmapExcessiveBranchCount; | |||
this.bitmapInactiveBranchAgeInDays = cfg.bitmapInactiveBranchAgeInDays; | |||
this.cutDeltaChains = cfg.cutDeltaChains; | |||
this.singlePack = cfg.singlePack; | |||
} | |||
/** | |||
@@ -554,6 +557,30 @@ public class PackConfig { | |||
cutDeltaChains = cut; | |||
} | |||
/** | |||
* @return true if all of refs/* should be packed in a single pack. Default | |||
* is false, packing a separate GC_REST pack for references outside | |||
* of refs/heads/* and refs/tags/*. | |||
* @since 4.9 | |||
*/ | |||
public boolean getSinglePack() { | |||
return singlePack; | |||
} | |||
/** | |||
* If {@code true}, packs a single GC pack for all objects reachable from | |||
* refs/*. Otherwise packs the GC pack with objects reachable from | |||
* refs/heads/* and refs/tags/*, and a GC_REST pack with the remaining | |||
* reachable objects. Disabled by default, packing GC and GC_REST. | |||
* | |||
* @param single | |||
* true to pack a single GC pack rather than GC and GC_REST packs | |||
* @since 4.9 | |||
*/ | |||
public void setSinglePack(boolean single) { | |||
singlePack = single; | |||
} | |||
/** | |||
* Get the number of objects to try when looking for a delta base. | |||
* | |||
@@ -1026,6 +1053,8 @@ public class PackConfig { | |||
rc.getBoolean("pack", "deltacompression", isDeltaCompress())); //$NON-NLS-1$ //$NON-NLS-2$ | |||
setCutDeltaChains( | |||
rc.getBoolean("pack", "cutdeltachains", getCutDeltaChains())); //$NON-NLS-1$ //$NON-NLS-2$ | |||
setSinglePack( | |||
rc.getBoolean("pack", "singlepack", getSinglePack())); //$NON-NLS-1$ //$NON-NLS-2$ | |||
setBuildBitmaps( | |||
rc.getBoolean("pack", "buildbitmaps", isBuildBitmaps())); //$NON-NLS-1$ //$NON-NLS-2$ | |||
setBitmapContiguousCommitCount( | |||
@@ -1073,6 +1102,7 @@ public class PackConfig { | |||
.append(getBitmapExcessiveBranchCount()); | |||
b.append(", bitmapInactiveBranchAge=") //$NON-NLS-1$ | |||
.append(getBitmapInactiveBranchAgeInDays()); | |||
b.append(", singlePack=").append(getSinglePack()); //$NON-NLS-1$ | |||
return b.toString(); | |||
} | |||
} |