From 7dce16018e05c0a094b3eb20009e0438764f046e Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Tue, 19 Nov 2013 12:44:19 +0100 Subject: [PATCH] Add close() method to API The API in org.eclipse.jgit.api does allow to open repositories but it did not allow to close them. This commit fixes this and allows API users to close a repository without having to use lower-level classes. Bug: 420502 Change-Id: I866225cc8534ae5916113fa24eb1c7513fd4472e Signed-off-by: Christian Halstrick Signed-off-by: Matthias Sohn --- .../eclipse/jgit/api/GitConstructionTest.java | 28 +++++++++++++++++++ .../src/org/eclipse/jgit/api/Git.java | 20 +++++++++++++ 2 files changed, 48 insertions(+) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java index 8d7758cb7..64bb8bfa4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java @@ -45,6 +45,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.File; import java.io.IOException; import org.eclipse.jgit.api.ListBranchCommand.ListMode; @@ -53,6 +54,7 @@ import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.util.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -123,4 +125,30 @@ public void testOpen() throws IOException, JGitInternalException, // should not get here } } + + @Test + /** + * Tests that a repository with packfiles can be deleted after calling + * Git.close(). On Windows the first try to delete the worktree will fail + * (because file handles on packfiles are still open) but the second + * attempt after a close will succeed. + * + * @throws IOException + * @throws JGitInternalException + * @throws GitAPIException + */ + public void testClose() throws IOException, JGitInternalException, + GitAPIException { + File workTree = db.getWorkTree(); + Git git = Git.wrap(db); + git.gc().setExpire(null).call(); + git.checkout().setName(git.getRepository().resolve("HEAD^").getName()) + .call(); + try { + FileUtils.delete(workTree, FileUtils.RECURSIVE); + } catch (IOException e) { + git.close(); + FileUtils.delete(workTree, FileUtils.RECURSIVE); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java index 08ab88005..983b6b552 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java @@ -124,6 +124,26 @@ public static Git wrap(Repository repo) { return new Git(repo); } + /** + * Frees resources held by the underlying {@link Repository} instance. It is + * recommended to call this method as soon as you don't need a reference to + * this {@link Git} instance and the underlying {@link Repository} instance + * anymore. This method closes the underlying object and ref databases. This + * will free memory and file handles. E.g. on Windows the repository will + * keep file handles on pack files unless you call this method. Such open + * file handles may for example prevent that the repository folder in the + * filesystem can be deleted. + *

+ * After calling close() you should not use this {@link Git} instance and + * the underlying {@link Repository} instance anymore. + * + * @since 3.2 + */ + public void close() { + if (repo != null) + repo.close(); + } + /** * Returns a command object to execute a {@code clone} command *