Fix open file handle prevent deleting a repository on Windows (#2008)

Fixes the problem of unclosed file handles which occur when a repository or pack file is accessed (e.g. asynchronously in a post receive hook) after the file had already been closed. Such open file handle prevents deleting a repositories on Windows.
This commit is contained in:
Matthias Thieroff
2022-04-21 07:45:44 +02:00
committed by GitHub
parent 81891051a4
commit fae952ff09
3 changed files with 11 additions and 22 deletions

View File

@@ -0,0 +1,2 @@
- type: fixed
description: Open file handle prevent deleting a repository on Windows ([#2008](https://github.com/scm-manager/scm-manager/pull/2008))

View File

@@ -29,7 +29,6 @@ package sonia.scm.repository;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevSort;
@@ -40,7 +39,6 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.util.IOUtil;
import sonia.scm.web.CollectingPackParserListener; import sonia.scm.web.CollectingPackParserListener;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -92,16 +90,12 @@ public class GitHookChangesetCollector
{ {
Map<String, Changeset> changesets = Maps.newLinkedHashMap(); Map<String, Changeset> changesets = Maps.newLinkedHashMap();
org.eclipse.jgit.lib.Repository repository = rpack.getRepository(); try (
org.eclipse.jgit.lib.Repository repository = rpack.getRepository();
RevWalk walk = null; RevWalk walk = rpack.getRevWalk();
GitChangesetConverter converter = converterFactory.create(repository, walk)
GitChangesetConverter converter = null; ) {
repository.incrementOpen();
try
{
walk = rpack.getRevWalk();
converter = converterFactory.create(repository, walk);
for (ReceiveCommand rc : receiveCommands) for (ReceiveCommand rc : receiveCommands)
{ {
@@ -142,18 +136,13 @@ public class GitHookChangesetCollector
{ {
logger.error("could not collect changesets", ex); logger.error("could not collect changesets", ex);
} }
finally
{
IOUtil.close(converter);
GitUtil.release(walk);
}
return Lists.newArrayList(changesets.values()); return Lists.newArrayList(changesets.values());
} }
private void collectChangesets(Map<String, Changeset> changesets, private void collectChangesets(Map<String, Changeset> changesets,
GitChangesetConverter converter, RevWalk walk, ReceiveCommand rc) GitChangesetConverter converter, RevWalk walk, ReceiveCommand rc)
throws IncorrectObjectTypeException, IOException throws IOException
{ {
ObjectId newId = rc.getNewId(); ObjectId newId = rc.getNewId();

View File

@@ -30,16 +30,14 @@ import com.google.common.base.Preconditions;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.util.FS;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.repository.GitConfig; import sonia.scm.repository.GitConfig;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.GitUtil;
import sonia.scm.repository.RepositoryProvider; import sonia.scm.repository.RepositoryProvider;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -103,7 +101,7 @@ public class GitRepositoryResolver implements RepositoryResolver<HttpServletRequ
logger.debug("try to open git repository at {}", gitdir); logger.debug("try to open git repository at {}", gitdir);
return RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED), true); return GitUtil.open(gitdir);
} }
else else
{ {