diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHookChangesetCollector.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHookChangesetCollector.java index b3b1f97467..58b7ea0d75 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHookChangesetCollector.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHookChangesetCollector.java @@ -189,6 +189,7 @@ public class GitHookChangesetCollector finally { IOUtil.close(converter); + GitUtil.release(walk); } return changesets; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 847178d85a..6dd4996b47 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -48,9 +48,9 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.treewalk.TreeWalk; @@ -85,6 +85,15 @@ public final class GitUtil /** Field description */ public static final String REF_MASTER = "master"; + /** Field description */ + private static final String DIRECTORY_DOTGIT = ".git"; + + /** Field description */ + private static final String DIRECTORY_OBJETCS = "objects"; + + /** Field description */ + private static final String DIRECTORY_REFS = "refs"; + /** Field description */ private static final String PREFIX_HEADS = "refs/heads/"; @@ -222,8 +231,23 @@ public final class GitUtil public static org.eclipse.jgit.lib.Repository open(File directory) throws IOException { - return RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, - FS.DETECTED), true); + FS fs = FS.DETECTED; + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + + builder.setFS(fs); + + if (isGitDirectory(fs, directory)) + { + + // bare repository + builder.setGitDir(directory).setBare(); + } + else + { + builder.setWorkTree(directory); + } + + return builder.build(); } /** @@ -599,10 +623,12 @@ public final class GitUtil String localBranch) { String branch = localBranch; - if ( localBranch.startsWith(REF_HEAD_PREFIX) ) + + if (localBranch.startsWith(REF_HEAD_PREFIX)) { branch = localBranch.substring(REF_HEAD_PREFIX.length()); } + return String.format(REMOTE_REF, repository.getId(), branch); } @@ -626,6 +652,37 @@ public final class GitUtil return name; } + /** + * Method description + * + * + * @param dir + * + * @return + */ + public static boolean isGitDirectory(File dir) + { + return isGitDirectory(FS.DETECTED, dir); + } + + /** + * Method description + * + * + * @param fs + * @param dir + * + * @return + */ + public static boolean isGitDirectory(FS fs, File dir) + { + //J- + return fs.resolve(dir, DIRECTORY_OBJETCS).exists() + && fs.resolve(dir, DIRECTORY_REFS).exists() + &&!fs.resolve(dir, DIRECTORY_DOTGIT).exists(); + //J+ + } + //~--- methods -------------------------------------------------------------- /** diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index d107d00ec3..d47dea9440 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -114,6 +114,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand Changeset changeset = null; Repository gr = null; GitChangesetConverter converter = null; + RevWalk revWalk = null; try { @@ -121,7 +122,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand if (!gr.getAllRefs().isEmpty()) { - RevWalk revWalk = new RevWalk(gr); + revWalk = new RevWalk(gr); ObjectId id = GitUtil.getRevisionId(gr, revision); RevCommit commit = revWalk.parseCommit(id); @@ -143,6 +144,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand finally { IOUtil.close(converter); + GitUtil.release(revWalk); GitUtil.close(gr); } @@ -171,6 +173,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand ChangesetPagingResult changesets = null; GitChangesetConverter converter = null; + RevWalk revWalk = null; try { @@ -207,7 +210,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand endId = gr.resolve(request.getEndChangeset()); } - RevWalk revWalk = new RevWalk(gr); + revWalk = new RevWalk(gr); converter = new GitChangesetConverter(gr, revWalk); @@ -278,6 +281,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand finally { IOUtil.close(converter); + GitUtil.release(revWalk); } return changesets; diff --git a/support/scm-support-youdebug/GitFileLeak.ydb b/support/scm-support-youdebug/GitFileLeak.ydb new file mode 100644 index 0000000000..d81395f453 --- /dev/null +++ b/support/scm-support-youdebug/GitFileLeak.ydb @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + +vm.breakpoint("org.eclipse.jgit.lib.Repository", 133){ + println "open repository " + gitDir; +} + +vm.breakpoint("org.eclipse.jgit.lib.Repository", 808){ + println " open repository, counter: " + useCnt.get(); +} + +vm.breakpoint("org.eclipse.jgit.lib.Repository", 812){ + println " close repository, counter: " + useCnt.get(); +} + +vm.breakpoint("org.eclipse.jgit.lib.Repository", 813){ + println "close repository"; +} + +vm.breakpoint("org.eclipse.jgit.revwalk.RevWalk", 215){ + println " open revwalk"; +} + +vm.breakpoint("org.eclipse.jgit.revwalk.RevWalk", 239){ + println " release revwalk"; +}