diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2019-10-14 21:06:18 +0200 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2019-10-15 08:54:20 +0200 |
commit | 36e16435bed5ba457f6d709643acc93505e99d2c (patch) | |
tree | 9003f4d44cd7ae2252909bf08df0585706776b6f | |
parent | d1d8bc30c213e6c416534a02921edada9d50cb25 (diff) | |
download | jgit-36e16435bed5ba457f6d709643acc93505e99d2c.tar.gz jgit-36e16435bed5ba457f6d709643acc93505e99d2c.zip |
IndexDiff: close SubmoduleWalk and use already loaded DirCache
If the SubModuleWalk isn't closed its TreeWalk's ObjectReader won't
be closed. Re-loading the DirCache during an IndexDiff is not only
inefficient but could also give strange results if an external
process had modified the index in the meantime: file diffs would
be based on a "before" state, but submodule diffs on an "after"
state.
Change-Id: Iab948c08ac342138b37263c9028d80b84101f6d6
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java index ce1eb597fc..88d0859842 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -536,63 +536,67 @@ public class IndexDiff { if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) { IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode; - SubmoduleWalk smw = SubmoduleWalk.forIndex(repository); - while (smw.next()) { - try { - if (localIgnoreSubmoduleMode == null) - localIgnoreSubmoduleMode = smw.getModulesIgnore(); - if (IgnoreSubmoduleMode.ALL - .equals(localIgnoreSubmoduleMode)) - continue; - } catch (ConfigInvalidException e) { - throw new IOException(MessageFormat.format( - JGitText.get().invalidIgnoreParamSubmodule, - smw.getPath()), e); - } - try (Repository subRepo = smw.getRepository()) { - String subRepoPath = smw.getPath(); - if (subRepo != null) { - ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ - if (subHead != null - && !subHead.equals(smw.getObjectId())) { - modified.add(subRepoPath); - recordFileMode(subRepoPath, FileMode.GITLINK); - } else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) { - IndexDiff smid = submoduleIndexDiffs.get(smw - .getPath()); - if (smid == null) { - smid = new IndexDiff(subRepo, - smw.getObjectId(), - wTreeIt.getWorkingTreeIterator(subRepo)); - submoduleIndexDiffs.put(subRepoPath, smid); - } - if (smid.diff()) { - if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED - && smid.getAdded().isEmpty() - && smid.getChanged().isEmpty() - && smid.getConflicting().isEmpty() - && smid.getMissing().isEmpty() - && smid.getModified().isEmpty() - && smid.getRemoved().isEmpty()) { - continue; - } + try (SubmoduleWalk smw = new SubmoduleWalk(repository)) { + smw.setTree(new DirCacheIterator(dirCache)); + while (smw.next()) { + try { + if (localIgnoreSubmoduleMode == null) + localIgnoreSubmoduleMode = smw.getModulesIgnore(); + if (IgnoreSubmoduleMode.ALL + .equals(localIgnoreSubmoduleMode)) + continue; + } catch (ConfigInvalidException e) { + throw new IOException(MessageFormat.format( + JGitText.get().invalidIgnoreParamSubmodule, + smw.getPath()), e); + } + try (Repository subRepo = smw.getRepository()) { + String subRepoPath = smw.getPath(); + if (subRepo != null) { + ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ + if (subHead != null + && !subHead.equals(smw.getObjectId())) { modified.add(subRepoPath); recordFileMode(subRepoPath, FileMode.GITLINK); + } else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) { + IndexDiff smid = submoduleIndexDiffs + .get(smw.getPath()); + if (smid == null) { + smid = new IndexDiff(subRepo, + smw.getObjectId(), + wTreeIt.getWorkingTreeIterator( + subRepo)); + submoduleIndexDiffs.put(subRepoPath, smid); + } + if (smid.diff()) { + if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED + && smid.getAdded().isEmpty() + && smid.getChanged().isEmpty() + && smid.getConflicting().isEmpty() + && smid.getMissing().isEmpty() + && smid.getModified().isEmpty() + && smid.getRemoved().isEmpty()) { + continue; + } + modified.add(subRepoPath); + recordFileMode(subRepoPath, + FileMode.GITLINK); + } } - } - } else if (missingSubmodules.remove(subRepoPath)) { - // If the directory is there and empty but the submodule - // repository in .git/modules doesn't exist yet it isn't - // "missing". - File gitDir = new File( - new File(repository.getDirectory(), - Constants.MODULES), - subRepoPath); - if (!gitDir.isDirectory()) { - File dir = SubmoduleWalk.getSubmoduleDirectory( - repository, subRepoPath); - if (dir.isDirectory() && !hasFiles(dir)) { - missing.remove(subRepoPath); + } else if (missingSubmodules.remove(subRepoPath)) { + // If the directory is there and empty but the + // submodule repository in .git/modules doesn't + // exist yet it isn't "missing". + File gitDir = new File( + new File(repository.getDirectory(), + Constants.MODULES), + subRepoPath); + if (!gitDir.isDirectory()) { + File dir = SubmoduleWalk.getSubmoduleDirectory( + repository, subRepoPath); + if (dir.isDirectory() && !hasFiles(dir)) { + missing.remove(subRepoPath); + } } } } |