Bug: 394544 Change-Id: I73faa55d860db64efc3412fee27386df47552a75 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Chris Aniszczyk <zx@twitter.com>tags/v2.2.0.201212191850-r
@@ -0,0 +1,90 @@ | |||
/* | |||
* Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.api; | |||
import static org.junit.Assert.assertTrue; | |||
import java.util.Date; | |||
import java.util.Properties; | |||
import org.eclipse.jgit.lib.RepositoryTestCase; | |||
import org.eclipse.jgit.util.GitDateParser; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
public class GarbageCollectCommandTest extends RepositoryTestCase { | |||
private Git git; | |||
@Override | |||
@Before | |||
public void setUp() throws Exception { | |||
super.setUp(); | |||
git = new Git(db); | |||
String path = "a.txt"; | |||
writeTrashFile(path, "content"); | |||
git.add().addFilepattern(path).call(); | |||
git.commit().setMessage("commit").call(); | |||
} | |||
@Test | |||
public void testGConeCommit() throws Exception { | |||
Date expire = GitDateParser.parse("now", null); | |||
Properties res = git.gc().setExpire(expire).call(); | |||
assertTrue(res.size() == 7); | |||
} | |||
@Test | |||
public void testGCmoreCommits() throws Exception { | |||
writeTrashFile("a.txt", "a couple of words for gc to pack"); | |||
writeTrashFile("b.txt", "a couple of words for gc to pack 2"); | |||
writeTrashFile("c.txt", "a couple of words for gc to pack 3"); | |||
git.commit().setAll(true).setMessage("commit2").call(); | |||
writeTrashFile("a.txt", "a couple of words for gc to pack more"); | |||
writeTrashFile("b.txt", "a couple of words for gc to pack more 2"); | |||
writeTrashFile("c.txt", "a couple of words for gc to pack more 3"); | |||
git.commit().setAll(true).setMessage("commit3").call(); | |||
Properties res = git.gc().setExpire(GitDateParser.parse("now", null)) | |||
.call(); | |||
assertTrue(res.size() == 7); | |||
} | |||
} |
@@ -209,6 +209,7 @@ flagIsDisposed={0} is disposed. | |||
flagNotFromThis={0} not from this. | |||
flagsAlreadyCreated={0} flags already created. | |||
funnyRefname=funny refname | |||
gcFailed=Garbage collection failed. | |||
gitmodulesNotFound=.gitmodules not found in tree. | |||
headRequiredToStash=HEAD required to stash local changes | |||
hoursAgo={0} hours ago | |||
@@ -507,6 +508,7 @@ unrecognizedRef=Unrecognized ref: {0} | |||
unsupportedCommand0=unsupported command 0 | |||
unsupportedEncryptionAlgorithm=Unsupported encryption algorithm: {0} | |||
unsupportedEncryptionVersion=Unsupported encryption version: {0} | |||
unsupportedGC Unsupported garbage collector for repository type: {0} | |||
unsupportedOperationNotAddAtEnd=Not add-at-end: {0} | |||
unsupportedPackIndexVersion=Unsupported pack index version {0} | |||
unsupportedPackVersion=Unsupported pack version {0}. |
@@ -0,0 +1,144 @@ | |||
/* | |||
* Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.api; | |||
import java.io.IOException; | |||
import java.text.MessageFormat; | |||
import java.text.ParseException; | |||
import java.util.Date; | |||
import java.util.Properties; | |||
import org.eclipse.jgit.api.errors.GitAPIException; | |||
import org.eclipse.jgit.api.errors.JGitInternalException; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.storage.file.FileRepository; | |||
import org.eclipse.jgit.storage.file.GC; | |||
import org.eclipse.jgit.storage.file.GC.RepoStatistics; | |||
import org.eclipse.jgit.util.GitDateParser; | |||
/** | |||
* A class used to execute a {@code gc} command. It has setters for all | |||
* supported options and arguments of this command and a {@link #call()} method | |||
* to finally execute the command. Each instance of this class should only be | |||
* used for one invocation of the command (means: one call to {@link #call()}) | |||
* | |||
* @since 2.2 | |||
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-gc.html" | |||
* >Git documentation about gc</a> | |||
*/ | |||
public class GarbageCollectCommand extends GitCommand<Properties> { | |||
private ProgressMonitor monitor; | |||
private Date expire; | |||
/** | |||
* @param repo | |||
*/ | |||
protected GarbageCollectCommand(Repository repo) { | |||
super(repo); | |||
if (!(repo instanceof FileRepository)) | |||
throw new UnsupportedOperationException(MessageFormat.format( | |||
JGitText.get().unsupportedGC, repo.getClass().toString())); | |||
} | |||
/** | |||
* @param monitor | |||
* a progress monitor | |||
* @return this instance | |||
*/ | |||
public GarbageCollectCommand setProgressMonitor(ProgressMonitor monitor) { | |||
this.monitor = monitor; | |||
return this; | |||
} | |||
/** | |||
* During gc() or prune() each unreferenced, loose object which has been | |||
* created or modified after <code>expire</code> will not be pruned. Only | |||
* older objects may be pruned. If set to null then every object is a | |||
* candidate for pruning. Use {@link GitDateParser} to parse time formats | |||
* used by git gc. | |||
* | |||
* @param expire | |||
* minimal age of objects to be pruned. | |||
* @return this instance | |||
*/ | |||
public GarbageCollectCommand setExpire(Date expire) { | |||
this.expire = expire; | |||
return this; | |||
} | |||
@Override | |||
public Properties call() throws GitAPIException { | |||
checkCallable(); | |||
GC gc = new GC((FileRepository) repo); | |||
gc.setProgressMonitor(monitor); | |||
if (this.expire != null) | |||
gc.setExpire(expire); | |||
try { | |||
gc.gc(); | |||
return toProperties(gc.getStatistics()); | |||
} catch (IOException e) { | |||
throw new JGitInternalException(JGitText.get().gcFailed, e); | |||
} catch (ParseException e) { | |||
throw new JGitInternalException(JGitText.get().gcFailed, e); | |||
} | |||
} | |||
@SuppressWarnings("boxing") | |||
private static Properties toProperties(RepoStatistics stats) { | |||
Properties p = new Properties(); | |||
p.put("numberOfLooseObjects", stats.numberOfLooseObjects); //$NON-NLS-1$ | |||
p.put("numberOfLooseRefs", stats.numberOfLooseRefs); //$NON-NLS-1$ | |||
p.put("numberOfPackedObjects", stats.numberOfPackedObjects); //$NON-NLS-1$ | |||
p.put("numberOfPackedRefs", stats.numberOfPackedRefs); //$NON-NLS-1$ | |||
p.put("numberOfPackFiles", stats.numberOfPackFiles); //$NON-NLS-1$ | |||
p.put("sizeOfLooseObjects", stats.sizeOfLooseObjects); //$NON-NLS-1$ | |||
p.put("sizeOfPackedObjects", stats.sizeOfPackedObjects); //$NON-NLS-1$ | |||
return p; | |||
} | |||
} |
@@ -617,6 +617,21 @@ public class Git { | |||
return new ApplyCommand(repo); | |||
} | |||
/** | |||
* Returns a command object to execute a {@code gc} command | |||
* | |||
* @see <a | |||
* href="http://www.kernel.org/pub/software/scm/git/docs/git-gc.html" | |||
* >Git documentation about gc</a> | |||
* | |||
* @return a {@link GarbageCollectCommand} used to collect all optional | |||
* parameters and to finally execute the {@code gc} command | |||
* @since 2.2 | |||
*/ | |||
public GarbageCollectCommand gc() { | |||
return new GarbageCollectCommand(repo); | |||
} | |||
/** | |||
* @return the git repository this class is interacting with | |||
*/ |
@@ -270,6 +270,7 @@ public class JGitText extends TranslationBundle { | |||
/***/ public String flagNotFromThis; | |||
/***/ public String flagsAlreadyCreated; | |||
/***/ public String funnyRefname; | |||
/***/ public String gcFailed; | |||
/***/ public String gitmodulesNotFound; | |||
/***/ public String headRequiredToStash; | |||
/***/ public String hoursAgo; | |||
@@ -568,6 +569,7 @@ public class JGitText extends TranslationBundle { | |||
/***/ public String unsupportedCommand0; | |||
/***/ public String unsupportedEncryptionAlgorithm; | |||
/***/ public String unsupportedEncryptionVersion; | |||
/***/ public String unsupportedGC; | |||
/***/ public String unsupportedOperationNotAddAtEnd; | |||
/***/ public String unsupportedPackIndexVersion; | |||
/***/ public String unsupportedPackVersion; |