From 67a8858b945944cc94baf9a2f6e4516bc283656b Mon Sep 17 00:00:00 2001 From: Tim Hosey Date: Thu, 4 Jan 2018 02:58:05 +0100 Subject: [PATCH] Fix file handle leak in FetchCommand#fetchSubmodules The private fetchSubmodules method in the FetchCommand class creates a Repository instance for each submodule being fetched, but never calls closes on it. This leads to the leaking of file handles. Bug: 526494 Change-Id: I7070388b8b62063d9d5cd31afae3015a8388044f Signed-off-by: Tim Hosey Signed-off-by: Matthias Sohn --- .../org/eclipse/jgit/api/FetchCommand.java | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java index b2c28dab0..5d178bc13 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java @@ -171,38 +171,42 @@ private void fetchSubmodules(FetchResult results) } walk.setTree(revWalk.parseTree(fetchHead)); while (walk.next()) { - Repository submoduleRepo = walk.getRepository(); + try (Repository submoduleRepo = walk.getRepository()) { - // Skip submodules that don't exist locally (have not been - // cloned), are not registered in the .gitmodules file, or - // not registered in the parent repository's config. - if (submoduleRepo == null || walk.getModulesPath() == null - || walk.getConfigUrl() == null) { - continue; - } - - FetchRecurseSubmodulesMode recurseMode = getRecurseMode( - walk.getPath()); - - // When the fetch mode is "yes" we always fetch. When the mode - // is "on demand", we only fetch if the submodule's revision was - // updated to an object that is not currently present in the - // submodule. - if ((recurseMode == FetchRecurseSubmodulesMode.ON_DEMAND - && !submoduleRepo.hasObject(walk.getObjectId())) - || recurseMode == FetchRecurseSubmodulesMode.YES) { - FetchCommand f = new FetchCommand(submoduleRepo) - .setProgressMonitor(monitor).setTagOpt(tagOption) - .setCheckFetchedObjects(checkFetchedObjects) - .setRemoveDeletedRefs(isRemoveDeletedRefs()) - .setThin(thin).setRefSpecs(refSpecs) - .setDryRun(dryRun) - .setRecurseSubmodules(recurseMode); - configure(f); - if (callback != null) { - callback.fetchingSubmodule(walk.getPath()); + // Skip submodules that don't exist locally (have not been + // cloned), are not registered in the .gitmodules file, or + // not registered in the parent repository's config. + if (submoduleRepo == null || walk.getModulesPath() == null + || walk.getConfigUrl() == null) { + continue; + } + + FetchRecurseSubmodulesMode recurseMode = getRecurseMode( + walk.getPath()); + + // When the fetch mode is "yes" we always fetch. When the + // mode + // is "on demand", we only fetch if the submodule's revision + // was + // updated to an object that is not currently present in the + // submodule. + if ((recurseMode == FetchRecurseSubmodulesMode.ON_DEMAND + && !submoduleRepo.hasObject(walk.getObjectId())) + || recurseMode == FetchRecurseSubmodulesMode.YES) { + FetchCommand f = new FetchCommand(submoduleRepo) + .setProgressMonitor(monitor) + .setTagOpt(tagOption) + .setCheckFetchedObjects(checkFetchedObjects) + .setRemoveDeletedRefs(isRemoveDeletedRefs()) + .setThin(thin).setRefSpecs(refSpecs) + .setDryRun(dryRun) + .setRecurseSubmodules(recurseMode); + configure(f); + if (callback != null) { + callback.fetchingSubmodule(walk.getPath()); + } + results.addSubmodule(walk.getPath(), f.call()); } - results.addSubmodule(walk.getPath(), f.call()); } } } catch (IOException e) {