private List getMergeInfoPaths(final List children, final String mergeSrcPath,
SVNEntry entry, final SVNURL sourceRootURL, final long revision1,
final long revision2, final SVNRepository repository, final SVNDepth depth) throws SVNException {
final List childrenWithMergeInfo = children == null ? new LinkedList() : children;
ISVNEntryHandler handler = new ISVNEntryHandler() {
public void handleEntry(File path, SVNEntry entry) throws SVNException {
File target = myTarget;
SVNAdminArea adminArea = entry.getAdminArea();
if (entry.isDirectory() && !adminArea.getThisDirName().equals(entry.getName()) &&
!entry.isAbsent()) {
return;
}
if (entry.isDeleted()) {
return;
}
boolean isSwitched = false;
boolean hasMergeInfoFromMergeSrc = false;
boolean pathIsMergeTarget = target.equals(path);
String mergeInfoProp = null;
if (!entry.isAbsent() && !entry.isScheduledForDeletion()) {
SVNVersionedProperties props = adminArea.getProperties(entry.getName());
mergeInfoProp = props.getStringPropertyValue(SVNProperty.MERGE_INFO);
if (mergeInfoProp != null && !pathIsMergeTarget) {
String relToTargetPath = SVNPathUtil.getRelativePath(target.getAbsolutePath(),
path.getAbsolutePath());
String mergeSrcChildPath = SVNPathUtil.getAbsolutePath(SVNPathUtil.append(mergeSrcPath,
relToTargetPath));
Map mergeInfo = SVNMergeInfoUtil.parseMergeInfo(new StringBuffer(mergeInfoProp),
null);
if (mergeInfoProp == null || mergeInfoProp.length() == 0 || mergeInfo.containsKey(mergeSrcChildPath)) {
hasMergeInfoFromMergeSrc = true;
} else {
SVNURL mergeInfoURL = sourceRootURL.appendPath(mergeSrcChildPath, false);
SVNRevision pegRevision = SVNRevision.create(revision1 < revision2 ?
revision2 : revision1);
SVNErrorCode code = null;
SVNURL originalURL = null;
try {
originalURL = ensureSessionURL(repository, mergeInfoURL);
getLocations(mergeInfoURL, null, repository, pegRevision,
SVNRevision.create(revision1), SVNRevision.create(revision2));
hasMergeInfoFromMergeSrc = true;
} catch (SVNException svne) {
code = svne.getErrorMessage().getErrorCode();
if (code != SVNErrorCode.FS_NOT_FOUND &&
code != SVNErrorCode.RA_DAV_PATH_NOT_FOUND &&
code != SVNErrorCode.CLIENT_UNRELATED_RESOURCES) {
throw svne;
}
} finally {
if (originalURL != null) {
repository.setLocation(originalURL, false);
}
}
}
}
isSwitched = SVNWCManager.isEntrySwitched(path, entry);
}
File parent = path.getParentFile();
if (pathIsMergeTarget || hasMergeInfoFromMergeSrc ||
entry.isScheduledForDeletion() ||
isSwitched ||
entry.getDepth() == SVNDepth.EMPTY ||
entry.getDepth() == SVNDepth.FILES ||
entry.isAbsent() ||
(depth == SVNDepth.IMMEDIATES && entry.isDirectory() &&
parent != null && !parent.equals(path) && parent.equals(target))) {
boolean hasMissingChild = entry.getDepth() == SVNDepth.EMPTY || entry.getDepth() == SVNDepth.FILES ||
(depth == SVNDepth.IMMEDIATES && entry.isDirectory() && parent != null && parent.equals(target));
boolean hasNonInheritable = false;
if (mergeInfoProp != null && mergeInfoProp.indexOf(SVNMergeRangeList.MERGE_INFO_NONINHERITABLE_STRING) != -1) {
hasNonInheritable = true;
}
if (!hasNonInheritable && (entry.getDepth() == SVNDepth.EMPTY ||
entry.getDepth() == SVNDepth.FILES)) {
hasNonInheritable = true;
}
MergePath child = new MergePath();
child.myPath = path;
child.myHasMissingChildren = hasMissingChild;
child.myIsSwitched = isSwitched;
child.myIsAbsent = entry.isAbsent();
child.myIsScheduledForDeletion = entry.isScheduledForDeletion();
child.myHasNonInheritableMergeInfo = hasNonInheritable;
childrenWithMergeInfo.add(child);
}
}
public void handleError(File path, SVNErrorMessage error) throws SVNException {
while (error.hasChildErrorMessage()) {
error = error.getChildErrorMessage();
}
if (error.getErrorCode() == SVNErrorCode.WC_PATH_NOT_FOUND ||
error.getErrorCode() == SVNErrorCode.WC_NOT_LOCKED) {
return;
}
SVNErrorManager.error(error, SVNLogType.DEFAULT);
}
};
if (entry.isFile()) {
handler.handleEntry(myTarget, entry);
} else {
myWCAccess.walkEntries(myTarget, handler, true, depth);
}
Collections.sort(childrenWithMergeInfo);