]> source.dussan.org Git - jgit.git/commitdiff
Add close() method to API 60/18560/4
authorChristian Halstrick <christian.halstrick@sap.com>
Tue, 19 Nov 2013 11:44:19 +0000 (12:44 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Tue, 19 Nov 2013 23:16:39 +0000 (00:16 +0100)
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 <christian.halstrick@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java

index 8d7758cb7a5c34370385734885d04bcc5a060c54..64bb8bfa4d94706f4f5cd831a798b1ff40388c1e 100644 (file)
@@ -45,6 +45,7 @@ package org.eclipse.jgit.api;
 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.api.errors.JGitInternalException;
 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 class GitConstructionTest extends RepositoryTestCase {
                        // 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);
+               }
+       }
 }
index 08ab88005d8cbf74223bbb9ff4e1a9455bc53fac..983b6b552ec69eedbb3fc30475802183a82bbdad 100644 (file)
@@ -124,6 +124,26 @@ public class Git {
                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.
+        * <p>
+        * 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
         *