myChildrenWithMergeInfo = new LinkedList();
if (!(myAreSourcesAncestral && myIsSameRepository)) {
if (myAreSourcesAncestral) {
MergePath item = new MergePath(targetWCPath);
SVNMergeRange itemRange = new SVNMergeRange(revision1, revision2, true);
item.myRemainingRanges = new SVNMergeRangeList(itemRange);
myChildrenWithMergeInfo.add(item);
}
driveMergeReportEditor(targetWCPath, url1, revision1, url2, revision2, null, isRollBack,
depth, adminArea, mergeCallback, null);
return;
}
SVNRepository repository = isRollBack ? myRepository1 : myRepository2;
SVNURL sourceRootURL = repository.getRepositoryRoot(true);
String mergeInfoPath = getPathRelativeToRoot(null, primaryURL, sourceRootURL, null, null);
myChildrenWithMergeInfo = getMergeInfoPaths(myChildrenWithMergeInfo, mergeInfoPath, parentEntry,
sourceRootURL, revision1, revision2, repository, depth);
MergePath targetMergePath = (MergePath) myChildrenWithMergeInfo.get(0);
myIsTargetMissingChild = targetMergePath.myHasMissingChildren;
boolean inheritable = !myIsTargetMissingChild && (depth == SVNDepth.INFINITY || depth == SVNDepth.IMMEDIATES);
populateRemainingRanges(myChildrenWithMergeInfo, sourceRootURL, url1, revision1, url2, revision2,
inheritable, honorMergeInfo, repository);
SVNMergeRange range = new SVNMergeRange(revision1, revision2, inheritable);
SVNRemoteDiffEditor editor = null;
SVNErrorMessage err = null;
if (honorMergeInfo && !myIsRecordOnly) {
long startRev = getMostInclusiveStartRevision(myChildrenWithMergeInfo, isRollBack);
if (SVNRevision.isValidRevisionNumber(startRev)) {
range.setStartRevision(startRev);
long endRev = getYoungestEndRevision(myChildrenWithMergeInfo, isRollBack);
while (SVNRevision.isValidRevisionNumber(endRev)) {
SVNURL realURL1 = url1;
SVNURL realURL2 = url2;
SVNURL oldURL1 = null;
SVNURL oldURL2 = null;
long nextEndRev = SVNRepository.INVALID_REVISION;
sliceRemainingRanges(myChildrenWithMergeInfo, isRollBack, endRev);
myCurrentAncestorIndex = -1;
if (!sameURLs) {
if (isRollBack && endRev != revision2) {
realURL2 = url1;
oldURL2 = ensureSessionURL(myRepository2, realURL2);
}
if (!isRollBack && startRev != revision1) {
realURL1 = url2;
oldURL1 = ensureSessionURL(myRepository1, realURL1);
}
}
try {
editor = driveMergeReportEditor(myTarget, realURL1, startRev, realURL2, endRev,
myChildrenWithMergeInfo, isRollBack, depth, adminArea, mergeCallback, editor);
} finally {
if (oldURL1 != null) {
myRepository1.setLocation(oldURL1, false);
}
if (oldURL2 != null) {
myRepository2.setLocation(oldURL2, false);
}
}
removeFirstRangeFromRemainingRanges(endRev, myChildrenWithMergeInfo);
nextEndRev = getYoungestEndRevision(myChildrenWithMergeInfo, isRollBack);
if (SVNRevision.isValidRevisionNumber(nextEndRev) && myConflictedPaths != null &&
!myConflictedPaths.isEmpty()) {
SVNMergeRange conflictedRange = new SVNMergeRange(startRev, endRev, false);
err = makeMergeConflictError(myTarget, conflictedRange);
range.setEndRevision(endRev);
break;
}
startRev = endRev;
endRev = nextEndRev;
}
}
} else {
if (!myIsRecordOnly) {
myCurrentAncestorIndex = -1;
editor = driveMergeReportEditor(myTarget, url1, revision1, url2, revision2, null, isRollBack,
depth, adminArea, mergeCallback, editor);
}
}
if (recordMergeInfo) {
MergePath mergeTarget = (MergePath) myChildrenWithMergeInfo.get(0);
removeAbsentChildren(myTarget, myChildrenWithMergeInfo);
SVNMergeRangeList filteredRangeList = filterNaturalHistoryFromMergeInfo(mergeInfoPath,
mergeTarget.myImplicitMergeInfo, range);
if (!filteredRangeList.isEmpty()) {
Map merges = determinePerformedMerges(myTarget, filteredRangeList, depth);
recordMergeInfoOnMergedChildren(depth);
updateWCMergeInfo(myTarget, mergeInfoPath, parentEntry, merges, isRollBack);
}
for (int i = 0; i < myChildrenWithMergeInfo.size(); i++) {
MergePath child = (MergePath) myChildrenWithMergeInfo.get(i);
if (child == null || child.myIsAbsent) {
continue;
}
String childReposPath = null;
if (child.myPath.equals(myTarget)) {
childReposPath = "";
} else {
childReposPath = SVNPathUtil.getRelativePath(myTarget.getAbsolutePath(),
child.myPath.getAbsolutePath());
}
SVNEntry childEntry = myWCAccess.getVersionedEntry(child.myPath, false);
String childMergeSourcePath = SVNPathUtil.getAbsolutePath(SVNPathUtil.append(mergeInfoPath,
childReposPath));
Map childMerges = new TreeMap();
SVNMergeRangeList childMergeRangeList = filterNaturalHistoryFromMergeInfo(childMergeSourcePath,
child.myImplicitMergeInfo, range);
if (childMergeRangeList.isEmpty()) {
continue;
}
SVNMergeRange[] childMergeRanges = childMergeRangeList.getRanges();
for (int j = 0; j < childMergeRangeList.getSize(); j++) {
SVNMergeRange rng = childMergeRanges[j];
if (childEntry.isFile()) {
rng.setInheritable(true);
} else {
rng.setInheritable(!child.myHasMissingChildren && (depth == SVNDepth.INFINITY ||
depth == SVNDepth.IMMEDIATES));
}
}
childMerges.put(child.myPath, childMergeRangeList);
if (child.myIsIndirectMergeInfo) {
SVNPropertiesManager.recordWCMergeInfo(child.myPath, child.myPreMergeMergeInfo,
myWCAccess);
}
updateWCMergeInfo(child.myPath, childMergeSourcePath, childEntry, childMerges, isRollBack);
markMergeInfoAsInheritableForARange(child.myPath, childMergeSourcePath,
child.myPreMergeMergeInfo, range, myChildrenWithMergeInfo, true, i);
if (i > 0) {
boolean isInSwitchedSubTree = false;
if (child.myIsSwitched) {
isInSwitchedSubTree = true;
} else if (i > 1) {
for (int j = i - 1; j > 0; j--) {
MergePath parent = (MergePath) myChildrenWithMergeInfo.get(j);
if (parent != null && parent.myIsSwitched &&
SVNPathUtil.isAncestor(parent.myPath.getAbsolutePath().replace(File.separatorChar, '/'),
child.myPath.getAbsolutePath().replace(File.separatorChar, '/'))) {
isInSwitchedSubTree = true;
break;
}
}
}
elideMergeInfo(myWCAccess, child.myPath, childEntry, isInSwitchedSubTree ? null : myTarget);
}
}
}
if (myAddedPaths != null) {
for (Iterator addedPathsIter = myAddedPaths.iterator(); addedPathsIter.hasNext();) {
File addedPath = (File) addedPathsIter.next();
SVNPropertyValue addedPathParentPropValue = SVNPropertiesManager.getProperty(myWCAccess,
addedPath.getParentFile(), SVNProperty.MERGE_INFO);
String addedPathParentPropValueStr = addedPathParentPropValue != null ?
addedPathParentPropValue.getString() : null;
if (addedPathParentPropValueStr != null &&
addedPathParentPropValueStr.indexOf(SVNMergeRangeList.MERGE_INFO_NONINHERITABLE_STRING) != -1) {
String addedPathStr = addedPath.getAbsolutePath().replace(File.separatorChar, '/');
String targetMergePathStr = targetMergePath.myPath.getAbsolutePath().replace(File.separatorChar, '/');
String commonAncestorPath = SVNPathUtil.getCommonPathAncestor(addedPathStr,
targetMergePathStr);
String relativeAddedPath = SVNPathUtil.getRelativePath(commonAncestorPath, addedPathStr);
SVNEntry entry = myWCAccess.getVersionedEntry(addedPath, false);
Map mergeMergeInfo = new TreeMap();
SVNMergeRange rng = range.dup();
if (entry.isFile()) {
rng.setInheritable(true);
} else {
rng.setInheritable(!(depth == SVNDepth.INFINITY || depth == SVNDepth.IMMEDIATES));
}
SVNMergeRangeList rangeList = new SVNMergeRangeList(rng);
mergeMergeInfo.put(SVNPathUtil.getAbsolutePath(SVNPathUtil.append(mergeInfoPath,
relativeAddedPath)), rangeList);
boolean[] inherited = { false };