* master: Add config parameter gc.prunePackExpire for packfile expiration In TestRepository, use a consistent clock Change-Id: I7ac568e650fbd191e48a8f1a4068af72deb242e8 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v4.3.0.201604071810-r
@@ -112,23 +112,18 @@ import org.eclipse.jgit.util.io.SafeBufferedOutputStream; | |||
* type of Repository the test data is stored on. | |||
*/ | |||
public class TestRepository<R extends Repository> { | |||
private static final PersonIdent defaultAuthor; | |||
private static final PersonIdent defaultCommitter; | |||
public static final String AUTHOR = "J. Author"; | |||
static { | |||
final MockSystemReader m = new MockSystemReader(); | |||
final long now = m.getCurrentTime(); | |||
final int tz = m.getTimezone(now); | |||
public static final String AUTHOR_EMAIL = "jauthor@example.com"; | |||
final String an = "J. Author"; | |||
final String ae = "jauthor@example.com"; | |||
defaultAuthor = new PersonIdent(an, ae, now, tz); | |||
public static final String COMMITTER = "J. Committer"; | |||
final String cn = "J. Committer"; | |||
final String ce = "jcommitter@example.com"; | |||
defaultCommitter = new PersonIdent(cn, ce, now, tz); | |||
} | |||
public static final String COMMITTER_EMAIL = "jcommitter@example.com"; | |||
private final PersonIdent defaultAuthor; | |||
private final PersonIdent defaultCommitter; | |||
private final R db; | |||
@@ -184,6 +179,10 @@ public class TestRepository<R extends Repository> { | |||
this.pool = rw; | |||
this.inserter = db.newObjectInserter(); | |||
this.mockSystemReader = reader; | |||
long now = mockSystemReader.getCurrentTime(); | |||
int tz = mockSystemReader.getTimezone(now); | |||
defaultAuthor = new PersonIdent(AUTHOR, AUTHOR_EMAIL, now, tz); | |||
defaultCommitter = new PersonIdent(COMMITTER, COMMITTER_EMAIL, now, tz); | |||
} | |||
/** @return the repository this helper class operates against. */ |
@@ -213,9 +213,20 @@ public class GcBasicPackingTest extends GcTestCase { | |||
assertEquals(9, stats.numberOfPackedObjects); | |||
assertEquals(2, stats.numberOfPackFiles); | |||
// repack again but now without a grace period for loose objects. Since | |||
// we don't have loose objects anymore this shouldn't change anything | |||
gc.setExpireAgeMillis(0); | |||
gc.gc(); | |||
stats = gc.getStatistics(); | |||
assertEquals(0, stats.numberOfLooseObjects); | |||
// if objects exist in multiple packFiles then they are counted multiple | |||
// times | |||
assertEquals(9, stats.numberOfPackedObjects); | |||
assertEquals(2, stats.numberOfPackFiles); | |||
// repack again but now without a grace period for packfiles. We should | |||
// end up with one packfile | |||
gc.setExpireAgeMillis(0); | |||
gc.setPackExpireAgeMillis(0); | |||
gc.gc(); | |||
stats = gc.getStatistics(); | |||
assertEquals(0, stats.numberOfLooseObjects); |
@@ -95,7 +95,8 @@ public class GcCommitSelectionTest extends GcTestCase { | |||
} | |||
currentCommits = nextCommitCount; | |||
gc.setExpireAgeMillis(0); // immediately delete old packs | |||
gc.setPackExpireAgeMillis(0); // immediately delete old packs | |||
gc.setExpireAgeMillis(0); | |||
gc.gc(); | |||
assertEquals(currentCommits * 3, // commit/tree/object | |||
gc.getStatistics().numberOfPackedObjects); | |||
@@ -158,7 +159,8 @@ public class GcCommitSelectionTest extends GcTestCase { | |||
} | |||
currentCommits = nextCommitCount; | |||
gc.setExpireAgeMillis(0); // immediately delete old packs | |||
gc.setPackExpireAgeMillis(0); // immediately delete old packs | |||
gc.setExpireAgeMillis(0); | |||
gc.gc(); | |||
assertEquals(currentCommits + " commits: ", expectedBitmapCount, | |||
gc.getStatistics().numberOfBitmaps); | |||
@@ -198,7 +200,8 @@ public class GcCommitSelectionTest extends GcTestCase { | |||
final int commitsForShallowBranches = 100; | |||
// Excessive branch history pruning, one old branch. | |||
gc.setExpireAgeMillis(0); // immediately delete old packs | |||
gc.setPackExpireAgeMillis(0); // immediately delete old packs | |||
gc.setExpireAgeMillis(0); | |||
gc.gc(); | |||
assertEquals( | |||
commitsForSparseBranch + commitsForFullBranch |
@@ -111,6 +111,8 @@ import org.eclipse.jgit.util.SystemReader; | |||
public class GC { | |||
private static final String PRUNE_EXPIRE_DEFAULT = "2.weeks.ago"; //$NON-NLS-1$ | |||
private static final String PRUNE_PACK_EXPIRE_DEFAULT = "1.hour.ago"; //$NON-NLS-1$ | |||
private final FileRepository repo; | |||
private ProgressMonitor pm; | |||
@@ -119,6 +121,10 @@ public class GC { | |||
private Date expire; | |||
private long packExpireAgeMillis = -1; | |||
private Date packExpire; | |||
private PackConfig pconfig = null; | |||
/** | |||
@@ -186,7 +192,7 @@ public class GC { | |||
*/ | |||
private void deleteOldPacks(Collection<PackFile> oldPacks, | |||
Collection<PackFile> newPacks) throws ParseException { | |||
long expireDate = getExpireDate(); | |||
long packExpireDate = getPackExpireDate(); | |||
oldPackLoop: for (PackFile oldPack : oldPacks) { | |||
String oldName = oldPack.getPackName(); | |||
// check whether an old pack file is also among the list of new | |||
@@ -196,7 +202,7 @@ public class GC { | |||
continue oldPackLoop; | |||
if (!oldPack.shouldBeKept() | |||
&& oldPack.getPackFile().lastModified() < expireDate) { | |||
&& oldPack.getPackFile().lastModified() < packExpireDate) { | |||
oldPack.close(); | |||
prunePack(oldName); | |||
} | |||
@@ -449,6 +455,26 @@ public class GC { | |||
return expireDate; | |||
} | |||
private long getPackExpireDate() throws ParseException { | |||
long packExpireDate = Long.MAX_VALUE; | |||
if (packExpire == null && packExpireAgeMillis == -1) { | |||
String prunePackExpireStr = repo.getConfig().getString( | |||
ConfigConstants.CONFIG_GC_SECTION, null, | |||
ConfigConstants.CONFIG_KEY_PRUNEPACKEXPIRE); | |||
if (prunePackExpireStr == null) | |||
prunePackExpireStr = PRUNE_PACK_EXPIRE_DEFAULT; | |||
packExpire = GitDateParser.parse(prunePackExpireStr, null, | |||
SystemReader.getInstance().getLocale()); | |||
packExpireAgeMillis = -1; | |||
} | |||
if (packExpire != null) | |||
packExpireDate = packExpire.getTime(); | |||
if (packExpireAgeMillis != -1) | |||
packExpireDate = System.currentTimeMillis() - packExpireAgeMillis; | |||
return packExpireDate; | |||
} | |||
/** | |||
* Remove all entries from a map which key is the id of an object referenced | |||
* by the given ObjectWalk | |||
@@ -982,6 +1008,20 @@ public class GC { | |||
expire = null; | |||
} | |||
/** | |||
* During gc() or prune() packfiles which are created or modified in the | |||
* last <code>packExpireAgeMillis</code> milliseconds will not be deleted. | |||
* Only older packfiles may be deleted. If set to 0 then every packfile is a | |||
* candidate for deletion. | |||
* | |||
* @param packExpireAgeMillis | |||
* minimal age of packfiles to be deleted in milliseconds. | |||
*/ | |||
public void setPackExpireAgeMillis(long packExpireAgeMillis) { | |||
this.packExpireAgeMillis = packExpireAgeMillis; | |||
expire = null; | |||
} | |||
/** | |||
* Set the PackConfig used when (re-)writing packfiles. This allows to | |||
* influence how packs are written and to implement something similar to | |||
@@ -1011,4 +1051,18 @@ public class GC { | |||
this.expire = expire; | |||
expireAgeMillis = -1; | |||
} | |||
/** | |||
* During gc() or prune() packfiles which are created or modified after or | |||
* at <code>packExpire</code> will not be deleted. Only older packfiles may | |||
* be deleted. If set to null then every packfile is a candidate for | |||
* deletion. | |||
* | |||
* @param packExpire | |||
* instant in time which defines packfile expiration | |||
*/ | |||
public void setPackExpire(Date packExpire) { | |||
this.packExpire = packExpire; | |||
packExpireAgeMillis = -1; | |||
} | |||
} |
@@ -247,6 +247,12 @@ public class ConfigConstants { | |||
/** The "pruneexpire" key */ | |||
public static final String CONFIG_KEY_PRUNEEXPIRE = "pruneexpire"; | |||
/** | |||
* The "prunepackexpire" key | |||
* @since 4.3 | |||
*/ | |||
public static final String CONFIG_KEY_PRUNEPACKEXPIRE = "prunepackexpire"; | |||
/** | |||
* The "aggressiveDepth" key | |||
* @since 3.6 |