boolean isDirectory = info.getKind() != NodeKind.FILE;
final long currentRevision = committedRevision.getNumber();
String repoRoot = info.getRepositoryRootURL().toString();
final String relPath = info.getURL().toString().substring(repoRoot.length());
SVNRepository repo = svn.getSvnKitManager().createRepository(repoRoot);
boolean mergeInfoAvailable = repo.hasCapability(SVNCapability.MERGE_INFO);
showProgressInfo(progressIndicator, "Getting latest repository revision");
long latestRevision = repo.getLatestRevision();
ExtendedScanManager esm = new ExtendedScanManager(repo, latestRevision, progressIndicator);
final Deque<Task> pathsToProcess = new LinkedList<Task>();
boolean retryWithoutMergeInfo = false;
pathsToProcess.add(new Task(relPath, currentRevision, true));
while (!pathsToProcess.isEmpty()) {
checkCancelled(progressIndicator);
final Task task = pathsToProcess.remove();
if (revisions.contain(task.relPath, task.revision)) {
continue;
}
if (scanMode != ScanMode.ONLY_IMPACTING_PATHS) {
pathsToProcess.addAll(esm.getPotentialTargets(task.relPath, scanMode == ScanMode.INCLUDE_CURRENT_BRANCHES_AND_TAGS));
checkCancelled(progressIndicator);
}
try {
showProgressInfo(progressIndicator, "Obtaining log info for " + task.relPath);
final List<Revision> revisionChain = new ArrayList<Revision>();
final List<Task> newTasks = new ArrayList<Task>();
// find deleted revision for current scan point to determine limits of log request
long deletedRevision = (task.revision == latestRevision) ? INVALID_REVISION
: repo.getDeletedRevision(task.relPath, task.revision, latestRevision);
if (deletedRevision >= 0) {
checkCancelled(progressIndicator);
SVNProperties p = repo.getRevisionProperties(deletedRevision, null);
revisionChain.add(new Revision(task.relPath, deletedRevision,
p.getStringValue(SVNRevisionProperty.AUTHOR),
SVNDate.parseDateString(p.getStringValue(SVNRevisionProperty.DATE)),
p.getStringValue(SVNRevisionProperty.LOG),
Collections.<Revision>emptyList(), null, SVNLogEntryPath.TYPE_DELETED));
}
// request log for current scan point
MergeInfoProcessor handler = new MergeInfoProcessor(task.relPath, new LogEntryWithMergeInfoHandler() {
@Override
public void handleLogEntry(SVNLogEntry logEntry, @NotNull List<Revision> mergedRevisions)
throws SVNCancelException {
checkCancelled(progressIndicator);
Revision.LinkType linkType = null;
// check copy sources
Revision copyFromRevision = getCopyFromRevision(logEntry, task.relPath);
if (copyFromRevision != null) {
linkType = Revision.LinkType.COPY;
mergedRevisions = Arrays.asList(copyFromRevision);
} else if (!mergedRevisions.isEmpty()) {
linkType = Revision.LinkType.MERGE;
}
long revision = logEntry.getRevision();
char changeType = getChangeType(logEntry, task.relPath);
Revision rgRev = new Revision(task.relPath, revision,
logEntry.getAuthor(), logEntry.getDate(), logEntry.getMessage(),
mergedRevisions, linkType, changeType);
revisionChain.add(rgRev);
if (!mergedRevisions.isEmpty()) {
Revision linkRev = mergedRevisions.get(0);
newTasks.add(new Task(linkRev.getRelPath(), linkRev.getRevisionNumber(), true));
}
if (changeType == SVNLogEntryPath.TYPE_REPLACED) {
newTasks.add(new Task(task.relPath, revision - 1, true));
}
showProgressInfo(progressIndicator, rgRev + " processed");
}
});
repo.log(new String[]{task.relPath}, deletedRevision < 0 ? INVALID_REVISION : (deletedRevision - 1), 0,
true, true, 0, mergeInfoAvailable && !retryWithoutMergeInfo , null, handler);
handler.checkFinalState();
revisions.addRevisionChain(revisionChain);
pathsToProcess.addAll(newTasks);
retryWithoutMergeInfo = false;