// do we have to add it if it was unversioned?
//myWCClient.doAdd(dst, false, false, false, true, false);
} else {
// wc:wc.
SVNWCAccess wcAccess = createWCAccess();
File srcParent = src.getParentFile();
File dstParent = dst.getParentFile();
SVNAdminArea srcParentArea = null;
SVNAdminArea dstParentArea = null;
try {
if (srcParent.equals(dstParent)) {
wcAccess.closeAdminArea(srcParent);
srcParentArea = dstParentArea = wcAccess.open(srcParent, true, 0);
} else {
srcParentArea = wcAccess.open(srcParent, false, 0);
dstParentArea = wcAccess.open(dstParent, true, 0);
}
SVNEntry srcEntry = srcParentArea.getVersionedEntry(src.getName(), false);
SVNEntry dstEntry = dstParentArea.getEntry(dst.getName(), false);
File srcWCRoot = SVNWCUtil.getWorkingCopyRoot(src, true);
File dstWCRoot = SVNWCUtil.getWorkingCopyRoot(dst, true);
boolean sameWC = srcWCRoot != null && srcWCRoot.equals(dstWCRoot);
if (sameWC && dstEntry != null
&& (dstEntry.isScheduledForDeletion() || dstEntry.getKind() != srcEntry.getKind())) {
wcAccess.close();
if (srcEntry.getKind() == dstEntry.getKind() && srcEntry.getSchedule() == null && srcEntry.isFile()) {
// make normal move to keep history (R+).
SVNCopySource source = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src);
myCopyClient.doCopy(new SVNCopySource[]{source}, dst, true, false, true);
return;
}
// attempt replace.
SVNFileUtil.copy(src, dst, false, false);
try {
myWCClient.doAdd(dst, false, false, false, SVNDepth.INFINITY, false, false);
} catch (SVNException e) {
// will be thrown on obstruction.
}
myWCClient.doDelete(src, true, false);
return;
} else if (!sameWC) {
SVNEntry dstTmpEntry = dstEntry != null ? dstEntry : dstParentArea.getVersionedEntry(dstParentArea.getThisDirName(), false);
if (srcEntry.getRepositoryRoot() != null && dstTmpEntry.getRepositoryRoot() != null &&
srcEntry.getRepositoryRoot().equals(dstTmpEntry.getRepositoryRoot())) {
//this is the case when different WCs occur to be from the same repository,
//use SVNCopyClient to move between them
wcAccess.close();
SVNCopySource source = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src);
myCopyClient.doCopy(new SVNCopySource[] { source }, dst, true, false, true);
return;
}
}
if (dstEntry != null) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_EXISTS, "There is already a versioned item ''{0}''", dst);
SVNErrorManager.error(err, SVNLogType.WC);
}
// 2. do manual copy of the file or directory
SVNFileUtil.copy(src, dst, false, sameWC);
// 3. update dst dir and dst entry in parent.
if (!sameWC) {
// just add dst (at least try to add, files already there).
wcAccess.close();
try {
myWCClient.doAdd(dst, false, false, false, SVNDepth.INFINITY, false, false);
} catch (SVNException e) {
// obstruction
}
} else if (srcEntry.isFile()) {
if (dstEntry == null) {
dstEntry = dstParentArea.addEntry(dst.getName());
}
String srcURL = srcEntry.getURL();
String srcCFURL = srcEntry.getCopyFromURL();
long srcRevision = srcEntry.getRevision();
long srcCFRevision = srcEntry.getCopyFromRevision();
// copy props!
SVNVersionedProperties srcProps = srcParentArea.getProperties(src.getName());
SVNVersionedProperties dstProps = dstParentArea.getProperties(dst.getName());
srcProps.copyTo(dstProps);
File srcBaseFile = srcParentArea.getBaseFile(src.getName(), false);
File dstBaseFile = dstParentArea.getBaseFile(dst.getName(), false);
if (srcBaseFile.isFile()) {
SVNFileUtil.copy(srcBaseFile, dstBaseFile, false, false);
}
if (srcEntry.isScheduledForAddition() && srcEntry.isCopied()) {
dstEntry.scheduleForAddition();
dstEntry.setCopyFromRevision(srcCFRevision);
dstEntry.setCopyFromURL(srcCFURL);
dstEntry.setKind(SVNNodeKind.FILE);
dstEntry.setRevision(srcRevision);
dstEntry.setCopied(true);
} else if (!srcEntry.isCopied()
&& !srcEntry.isScheduledForAddition()) {
dstEntry.setCopied(true);
dstEntry.scheduleForAddition();
dstEntry.setKind(SVNNodeKind.FILE);
dstEntry.setCopyFromRevision(srcRevision);
dstEntry.setCopyFromURL(srcURL);
} else {
dstEntry.scheduleForAddition();
dstEntry.setKind(SVNNodeKind.FILE);
if (!dstEntry.isScheduledForReplacement()) {
dstEntry.setRevision(0);
}
}
SVNLog log = dstParentArea.getLog();
dstParentArea.saveEntries(false);
dstParentArea.saveVersionedProperties(log, true);
log.save();
dstParentArea.runLogs();
} else if (srcEntry.isDirectory()) {
SVNAdminArea srcArea = wcAccess.open(src, false, 0);
srcEntry = srcArea.getEntry(srcArea.getThisDirName(), false);
if (dstEntry == null) {
dstEntry = dstParentArea.addEntry(dst.getName());
}
SVNAdminArea dstArea = wcAccess.open(dst, true, SVNWCAccess.INFINITE_DEPTH);
SVNVersionedProperties srcProps = srcArea.getProperties(srcArea.getThisDirName());
SVNVersionedProperties dstProps = dstArea.getProperties(dstArea.getThisDirName());
SVNEntry dstParentEntry = dstParentArea.getEntry(dstParentArea.getThisDirName(), false);
String srcURL = srcEntry.getURL();
String srcCFURL = srcEntry.getCopyFromURL();
String dstURL = dstParentEntry.getURL();
String repositoryRootURL = dstParentEntry.getRepositoryRoot();
long srcRevision = srcEntry.getRevision();
long srcCFRevision = srcEntry.getCopyFromRevision();
dstURL = SVNPathUtil.append(dstURL, SVNEncodingUtil.uriEncode(dst.getName()));
if (srcEntry.isScheduledForAddition() && srcEntry.isCopied()) {
srcProps.copyTo(dstProps);
dstEntry.scheduleForAddition();
dstEntry.setKind(SVNNodeKind.DIR);
dstEntry.setCopied(true);
dstEntry.setCopyFromRevision(srcCFRevision);
dstEntry.setCopyFromURL(srcCFURL);
SVNEntry dstThisEntry = dstArea.getEntry(dstArea.getThisDirName(), false);
dstThisEntry.scheduleForAddition();
dstThisEntry.setKind(SVNNodeKind.DIR);
dstThisEntry.setCopyFromRevision(srcCFRevision);
dstThisEntry.setCopyFromURL(srcCFURL);
dstThisEntry.setRevision(srcRevision);
dstThisEntry.setCopied(true);
SVNLog log = dstArea.getLog();
dstArea.saveVersionedProperties(log, true);
dstParentArea.saveEntries(false);
log.save();
dstArea.runLogs();
// update URL in children.
dstArea.updateURL(dstURL, true);
dstParentArea.saveEntries(true);
} else if (!srcEntry.isCopied() && !srcEntry.isScheduledForAddition()) {
// versioned (deleted, replaced, or normal).
srcProps.copyTo(dstProps);
dstEntry.scheduleForAddition();
dstEntry.setKind(SVNNodeKind.DIR);
dstEntry.setCopied(true);
dstEntry.setCopyFromRevision(srcRevision);
dstEntry.setCopyFromURL(srcURL);
// update URL, CF-URL and CF-REV in children.
SVNEntry dstThisEntry = dstArea.getEntry(dstArea.getThisDirName(), false);
dstThisEntry.scheduleForAddition();
dstThisEntry.setKind(SVNNodeKind.DIR);
dstThisEntry.setCopied(true);
dstThisEntry.scheduleForAddition();
dstThisEntry.setKind(SVNNodeKind.DIR);
dstThisEntry.setCopyFromRevision(srcRevision);
dstThisEntry.setCopyFromURL(srcURL);
dstThisEntry.setURL(dstURL);
dstThisEntry.setRepositoryRoot(repositoryRootURL);
SVNLog log = dstArea.getLog();
dstArea.saveVersionedProperties(log, true);
dstArea.saveEntries(false);
log.save();
dstArea.runLogs();
updateCopiedDirectory(dstArea, dstArea.getThisDirName(), dstURL, repositoryRootURL, null, -1);
dstArea.saveEntries(true);
dstParentArea.saveEntries(true);
} else {
// unversioned entry (copied or added)
dstParentArea.deleteEntry(dst.getName());
dstParentArea.saveEntries(true);
SVNFileUtil.deleteAll(dst, this);
SVNFileUtil.copy(src, dst, false, false);
wcAccess.close();
myWCClient.doAdd(dst, false, false, false, SVNDepth.INFINITY, false, false);
}
}
// now delete src (if it is not the same as dst :))
try {
wcAccess.close();
myWCClient.doDelete(src, true, false);
} catch (SVNException e) {
//
}
} finally {
wcAccess.close();
}
}
}