Browse Source

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>
next
Thomas Wolf 5 years ago
parent
commit
36e16435be
  1. 112
      org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java

112
org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java

@ -536,63 +536,67 @@ public class IndexDiff {
if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) { if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) {
IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode; IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode;
SubmoduleWalk smw = SubmoduleWalk.forIndex(repository); try (SubmoduleWalk smw = new SubmoduleWalk(repository)) {
while (smw.next()) { smw.setTree(new DirCacheIterator(dirCache));
try { while (smw.next()) {
if (localIgnoreSubmoduleMode == null) try {
localIgnoreSubmoduleMode = smw.getModulesIgnore(); if (localIgnoreSubmoduleMode == null)
if (IgnoreSubmoduleMode.ALL localIgnoreSubmoduleMode = smw.getModulesIgnore();
.equals(localIgnoreSubmoduleMode)) if (IgnoreSubmoduleMode.ALL
continue; .equals(localIgnoreSubmoduleMode))
} catch (ConfigInvalidException e) { continue;
throw new IOException(MessageFormat.format( } catch (ConfigInvalidException e) {
JGitText.get().invalidIgnoreParamSubmodule, throw new IOException(MessageFormat.format(
smw.getPath()), e); JGitText.get().invalidIgnoreParamSubmodule,
} smw.getPath()), e);
try (Repository subRepo = smw.getRepository()) { }
String subRepoPath = smw.getPath(); try (Repository subRepo = smw.getRepository()) {
if (subRepo != null) { String subRepoPath = smw.getPath();
ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ if (subRepo != null) {
if (subHead != null ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$
&& !subHead.equals(smw.getObjectId())) { if (subHead != null
modified.add(subRepoPath); && !subHead.equals(smw.getObjectId())) {
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); modified.add(subRepoPath);
recordFileMode(subRepoPath, FileMode.GITLINK); 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)) {
} else if (missingSubmodules.remove(subRepoPath)) { // If the directory is there and empty but the
// If the directory is there and empty but the submodule // submodule repository in .git/modules doesn't
// repository in .git/modules doesn't exist yet it isn't // exist yet it isn't "missing".
// "missing". File gitDir = new File(
File gitDir = new File( new File(repository.getDirectory(),
new File(repository.getDirectory(), Constants.MODULES),
Constants.MODULES), subRepoPath);
subRepoPath); if (!gitDir.isDirectory()) {
if (!gitDir.isDirectory()) { File dir = SubmoduleWalk.getSubmoduleDirectory(
File dir = SubmoduleWalk.getSubmoduleDirectory( repository, subRepoPath);
repository, subRepoPath); if (dir.isDirectory() && !hasFiles(dir)) {
if (dir.isDirectory() && !hasFiles(dir)) { missing.remove(subRepoPath);
missing.remove(subRepoPath); }
} }
} }
} }

Loading…
Cancel
Save