in org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java [533:699]
private void buildMaps(Repository repository, RevCommit baseCommit,
RevCommit compareCommit, IProgressMonitor monitor)
throws InterruptedException, IOException {
monitor.beginTask(UIText.CompareTreeView_AnalyzingRepositoryTaskText,
IProgressMonitor.UNKNOWN);
long previousTimeMilliseconds = System.currentTimeMillis();
boolean useIndex = compareVersion.equals(INDEX_VERSION);
fileNodes.clear();
containerNodes.clear();
boolean checkIgnored = false;
try (TreeWalk tw = new TreeWalk(repository)) {
int baseTreeIndex;
if (baseCommit == null) {
checkIgnored = true;
baseTreeIndex = tw.addTree(new FileTreeIterator(repository));
} else
baseTreeIndex = tw.addTree(new CanonicalTreeParser(null,
repository.newObjectReader(), baseCommit.getTree()));
int compareTreeIndex;
if (!useIndex)
compareTreeIndex = tw.addTree(new CanonicalTreeParser(null,
repository.newObjectReader(), compareCommit.getTree()));
else
compareTreeIndex = tw.addTree(new DirCacheIterator(repository
.readDirCache()));
if (input instanceof IResource[]) {
IResource[] resources = (IResource[]) input;
TreeFilter pathFilter = filterPaths(Arrays.stream(resources)
.map(r -> repositoryMapping.getRepoRelativePath(r))
.filter(p -> p != null && !p.isEmpty())
.collect(Collectors.toList()));
if (checkIgnored) {
if (pathFilter != null) {
tw.setFilter(AndTreeFilter.create(pathFilter,
new NotIgnoredFilter(baseTreeIndex)));
} else {
tw.setFilter(new NotIgnoredFilter(baseTreeIndex));
}
} else if (pathFilter != null) {
tw.setFilter(pathFilter);
}
}
tw.setRecursive(true);
while (tw.next()) {
if (monitor.isCanceled())
throw new InterruptedException();
AbstractTreeIterator compareVersionIterator = tw.getTree(
compareTreeIndex, AbstractTreeIterator.class);
AbstractTreeIterator baseVersionIterator = tw.getTree(
baseTreeIndex, AbstractTreeIterator.class);
IFileRevision left = null;
IFileRevision right = null;
String repoRelativePath = baseVersionIterator != null
? baseVersionIterator.getEntryPathString()
: compareVersionIterator.getEntryPathString();
IPath currentPath = new Path(repoRelativePath);
// Updating the progress bar is slow, so just sample it. To
// make sure slow compares are reflected in the progress
// monitor also update before comparing large files.
long currentTimeMilliseconds = System.currentTimeMillis();
long size1 = -1;
long size2 = -1;
if (compareVersionIterator != null
&& baseVersionIterator != null) {
size1 = getEntrySize(tw, compareVersionIterator);
size2 = getEntrySize(tw, baseVersionIterator);
}
final long REPORTSIZE = 100000;
if (size1 > REPORTSIZE
|| size2 > REPORTSIZE
|| currentTimeMilliseconds - previousTimeMilliseconds > 500) {
monitor.setTaskName(currentPath.toString());
previousTimeMilliseconds = currentTimeMilliseconds;
}
Type type = null;
if (compareVersionIterator != null
&& baseVersionIterator != null) {
boolean equalContent = compareVersionIterator
.getEntryObjectId().equals(
baseVersionIterator.getEntryObjectId());
type = equalContent ? Type.FILE_BOTH_SIDES_SAME
: Type.FILE_BOTH_SIDES_DIFFER;
} else if (compareVersionIterator != null
&& baseVersionIterator == null) {
type = Type.FILE_DELETED;
} else if (compareVersionIterator == null
&& baseVersionIterator != null) {
type = Type.FILE_ADDED;
}
IFile file = null;
if (type != Type.FILE_BOTH_SIDES_SAME) {
file = ResourceUtil.getFileForLocation(repository,
repoRelativePath, false);
}
CheckoutMetadata metadata = null;
if (baseVersionIterator != null) {
if (baseCommit == null) {
if (file != null)
left = new WorkspaceFileRevision(getRepository(),
repoRelativePath, file);
else {
left = new WorkingTreeFileRevision(getRepository(),
repoRelativePath);
}
} else {
metadata = new CheckoutMetadata(
tw.getEolStreamType(
TreeWalk.OperationType.CHECKOUT_OP),
tw.getFilterCommand(
Constants.ATTR_FILTER_TYPE_SMUDGE));
left = GitFileRevision.inCommit(repository, baseCommit,
repoRelativePath, tw.getObjectId(baseTreeIndex),
metadata);
}
}
if (compareVersionIterator != null) {
if (!useIndex) {
if (metadata == null) {
metadata = new CheckoutMetadata(
tw.getEolStreamType(
TreeWalk.OperationType.CHECKOUT_OP),
tw.getFilterCommand(
Constants.ATTR_FILTER_TYPE_SMUDGE));
}
right = GitFileRevision.inCommit(repository,
compareCommit, repoRelativePath,
tw.getObjectId(compareTreeIndex), metadata);
} else {
right = GitFileRevision.inIndex(repository,
repoRelativePath);
}
}
IPath containerPath = currentPath.removeLastSegments(1);
ContainerNode containerNode = getOrCreateContainerNode(
containerPath, type);
FileNode fileNode = new FileNode(currentPath, file, type, left,
right);
containerNode.addChild(fileNode);
fileNodes.put(currentPath, fileNode);
// If a file is not "equal content", the container nodes up to
// the root must be shown in any case, so propagate the
// change of the "only equal content" flag.
if (type != Type.FILE_BOTH_SIDES_SAME) {
IPath path = currentPath;
while (path.segmentCount() > 0) {
path = path.removeLastSegments(1);
ContainerNode node = containerNodes.get(path);
node.setOnlyEqualContent(false);
}
}
}
} finally {
monitor.done();
}
}