SVNURL url1 = SVNURL.parseURIEncoded(((CopyPair) copyPairs.get(0)).mySource);
SVNURL url2 = SVNURL.parseURIEncoded(((CopyPair) copyPairs.get(0)).myDst);
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNSUPPORTED_FEATURE, "Source and dest appear not to be in the same repository (src: ''{0}''; dst: ''{1}'')", new Object[] {url1, url2});
SVNErrorManager.error(err, SVNLogType.WC);
}
SVNRepository nonTopRepos = null;
for (int i = 0; i < copyPairs.size(); i++) {
CopyPair pair = (CopyPair) copyPairs.get(i);
CopyPathInfo info = (CopyPathInfo) pathInfos.get(i);
if (nonTopRepos == null) {
nonTopRepos = createRepository(SVNURL.parseURIEncoded(pair.mySource), null, null, true);
}
if (pair.mySource.equals(pair.myDst)) {
info.isResurrection = true;
}
}
/*
* Get list of parents that have to be created. start with first 'dst' parent.
* This is a list of urls.
*/
String rootURL = nonTopRepos.getRepositoryRoot(true).toString();
List newDirs = new ArrayList();
SVNURL oldLocation = null;
if (makeParents) {
CopyPair pair = (CopyPair) copyPairs.get(0);
if (!pair.myDst.equals(rootURL)) {
oldLocation = nonTopRepos.getLocation();
nonTopRepos.setLocation(SVNURL.parseURIEncoded(pair.myDst).removePathTail(), false);
SVNNodeKind kind = nonTopRepos.checkPath("", -1);
while (kind == SVNNodeKind.NONE) {
newDirs.add(nonTopRepos.getLocation().toString());
nonTopRepos.setLocation(nonTopRepos.getLocation().removePathTail(), false);
kind = nonTopRepos.checkPath("", -1);
}
}
} else if (Boolean.getBoolean("svnkit.compatibleHash")) {
// XXX: hack for tests to generate error message tests will like.
// do not check paths above repository root.
CopyPair pair = (CopyPair) copyPairs.get(0);
if (!pair.myDst.equals(rootURL)) {
oldLocation = nonTopRepos.getLocation();
nonTopRepos.setLocation(SVNURL.parseURIEncoded(pair.myDst).removePathTail(), false);
SVNNodeKind kind = nonTopRepos.checkPath("", -1);
if (kind == SVNNodeKind.NONE) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_NOT_FOUND, "''{0}'' path not found", nonTopRepos.getLocation());
SVNErrorManager.error(err, SVNLogType.WC);
}
}
}
if (oldLocation != null) {
nonTopRepos.setLocation(oldLocation, false);
}
/*
* Check if source is dst child (while dst is not root).
*/
for (int i = 0; i < copyPairs.size(); i++) {
CopyPair pair = (CopyPair) copyPairs.get(i);
CopyPathInfo info = (CopyPathInfo) pathInfos.get(i);
if (!pair.myDst.equals(rootURL) && SVNPathUtil.getPathAsChild(pair.myDst, pair.mySource) != null) {
info.isResurrection = true;
}
}
long latestRevision = nonTopRepos.getLatestRevision();
for (int i = 0; i < copyPairs.size(); i++) {
CopyPair pair = (CopyPair) copyPairs.get(i);
CopyPathInfo info = (CopyPathInfo) pathInfos.get(i);
pair.mySourceRevisionNumber = getRevisionNumber(pair.mySourceRevision, nonTopRepos, null);
info.mySourceRevisionNumber = pair.mySourceRevisionNumber;
SVNRepositoryLocation[] locations = getLocations(SVNURL.parseURIEncoded(pair.mySource), null, null /*optimize topRepos*/, pair.mySourcePegRevision, pair.mySourceRevision, SVNRevision.UNDEFINED);
pair.mySource = locations[0].getURL().toString();
// tests:
// src is equal to dst
if (isMove && pair.mySource.equals(pair.myDst)) {
//if ("".equals(srcRelative) && isMove) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNSUPPORTED_FEATURE, "Cannot move URL ''{0}'' into itself", SVNURL.parseURIEncoded(pair.mySource));
SVNErrorManager.error(err, SVNLogType.WC);
}
// src doesn't exist at source revision.
nonTopRepos.setLocation(SVNURL.parseURIEncoded(pair.mySource), false);
info.mySourceKind = nonTopRepos.checkPath("", pair.mySourceRevisionNumber);
if (info.mySourceKind == SVNNodeKind.NONE) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_NOT_FOUND,
"Path ''{0}'' does not exist in revision {1}", new Object[] {SVNURL.parseURIEncoded(pair.mySource), new Long(pair.mySourceRevisionNumber)});
SVNErrorManager.error(err, SVNLogType.WC);
}
// dst already exists at HEAD.
nonTopRepos.setLocation(SVNURL.parseURIEncoded(pair.myDst), false);
SVNNodeKind dstKind = nonTopRepos.checkPath("", latestRevision);
if (dstKind != SVNNodeKind.NONE) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_ALREADY_EXISTS,
"Path ''{0}'' already exists", pair.myDst);
SVNErrorManager.error(err, SVNLogType.WC);
}
info.mySource = pair.mySource;
info.myDstPath = pair.myDst;
}
List paths = new ArrayList(copyPairs.size() * 2);
List commitItems = new ArrayList(copyPairs.size() * 2);
if (makeParents) {
for (Iterator newDirsIter = newDirs.iterator(); newDirsIter.hasNext();) {
String itemURL = (String) newDirsIter.next();
SVNCommitItem item = new SVNCommitItem(null,
SVNURL.parseURIEncoded(itemURL), null, SVNNodeKind.NONE, null, null, true, false, false, false, false, false);
commitItems.add(item);
}
}
for (Iterator infos = pathInfos.iterator(); infos.hasNext();) {
CopyPathInfo info = (CopyPathInfo) infos.next();
SVNURL itemURL = SVNURL.parseURIEncoded(info.myDstPath);
SVNCommitItem item = new SVNCommitItem(null, itemURL, null, SVNNodeKind.NONE, null, null, true, false, false, false, false, false);
commitItems.add(item);
pathsMap.put(info.myDstPath, info);
if (isMove && !info.isResurrection) {
itemURL = SVNURL.parseURIEncoded(info.mySource);
item = new SVNCommitItem(null, itemURL, null, SVNNodeKind.NONE, null, null, false, true, false, false, false, false);
commitItems.add(item);
pathsMap.put(info.mySource, info);
}
}
if (makeParents) {
for (Iterator newDirsIter = newDirs.iterator(); newDirsIter.hasNext();) {
String dirPath = (String) newDirsIter.next();
CopyPathInfo info = new CopyPathInfo();
info.myDstPath = dirPath;
info.isDirAdded = true;
paths.add(info.myDstPath);
pathsMap.put(dirPath, info);
}
}
for (Iterator infos = pathInfos.iterator(); infos.hasNext();) {
CopyPathInfo info = (CopyPathInfo) infos.next();
nonTopRepos.setLocation(SVNURL.parseURIEncoded(info.mySource), false);
Map mergeInfo = calculateTargetMergeInfo(null, null, SVNURL.parseURIEncoded(info.mySource),
info.mySourceRevisionNumber, nonTopRepos, false);
if (mergeInfo != null) {
info.myMergeInfoProp = SVNMergeInfoUtil.formatMergeInfoToString(mergeInfo, null);
}
paths.add(info.myDstPath);
if (isMove && !info.isResurrection) {
// this is too.
paths.add(info.mySource);
}
}
SVNCommitItem[] commitables = (SVNCommitItem[]) commitItems.toArray(new SVNCommitItem[commitItems.size()]);
message = commitHandler.getCommitMessage(message, commitables);
if (message == null) {
return SVNCommitInfo.NULL;
}
message = SVNCommitUtil.validateCommitMessage(message);
revprops = commitHandler.getRevisionProperties(message, commitables, revprops == null ? new SVNProperties() : revprops);
if (revprops == null) {
return SVNCommitInfo.NULL;
}
SVNPropertiesManager.validateRevisionProperties(revprops);
SVNURL topURL = SVNURL.parseURIEncoded((String) paths.get(0));
for(int i = 1; i < paths.size(); i++) {
String url = (String) paths.get(i);
topURL = SVNURLUtil.getCommonURLAncestor(topURL, SVNURL.parseURIEncoded(url));
}
if (paths.contains(topURL.toString())) {
topURL = topURL.removePathTail();
}
for(int i = 0; i < paths.size(); i++) {
String url = (String) paths.get(i);
SVNURL svnURL = SVNURL.parseURIEncoded(url);
url = SVNPathUtil.getPathAsChild(topURL.getPath(), svnURL.getPath());
paths.set(i, url);
CopyPathInfo info = (CopyPathInfo) pathsMap.remove(svnURL.toString());
if (info != null) {
if (info.mySource != null) {
info.mySourcePath = getPathRelativeToRoot(null, SVNURL.parseURIEncoded(info.mySource), SVNURL.parseURIEncoded(rootURL), null, null);
info.mySourceRelativePath = getPathRelativeToSession(SVNURL.parseURIEncoded(info.mySource), topURL, null);
}
pathsMap.put(url, info);
}
}
nonTopRepos.setLocation(topURL, false);
ISVNEditor commitEditor = nonTopRepos.getCommitEditor(message, null, true, revprops, null);
ISVNCommitPathHandler committer = new CopyCommitPathHandler(pathsMap, isMove);
SVNCommitInfo result = null;
try {
SVNCommitUtil.driveCommitEditor(committer, paths, commitEditor, latestRevision);