"SVNUpdateEditor.closeFile(): fileInfo.baseFile = {0}, fileInfo.newBaseFile = {1}, " +
"fileInfo.copiedBaseText = {2}", new Object[] { fileInfo.baseFile, fileInfo.newBaseFile,
fileInfo.copiedBaseText });
SVNErrorManager.error(err, SVNLogType.DEFAULT);
}
SVNAdminArea adminArea = fileInfo.getAdminArea();
SVNEntry entry = adminArea.getEntry(fileInfo.Name, false);
boolean replaced = entry != null && entry.isScheduledForReplacement();
boolean useRevertBase = replaced && entry.getCopyFromURL() != null;
if (useRevertBase) {
fileInfo.baseFile = adminArea.getFile(SVNAdminUtil.getTextRevertPath(fileInfo.Name, false));
fileInfo.newBaseFile = adminArea.getFile(SVNAdminUtil.getTextRevertPath(fileInfo.Name, true));
} else {
fileInfo.baseFile = adminArea.getBaseFile(fileInfo.Name, false);
fileInfo.newBaseFile = adminArea.getBaseFile(fileInfo.Name, true);
}
SVNFileUtil.copyFile(fileInfo.copiedBaseText, fileInfo.newBaseFile, true);
fileInfo.Checksum = SVNFileUtil.computeChecksum(fileInfo.newBaseFile);
}
// check checksum.
String checksum = null;
boolean isTextUpdated = fileInfo.newBaseFile != null;
if (textChecksum != null && isTextUpdated) {
if (fileInfo.Checksum != null && !textChecksum.equals(fileInfo.Checksum)) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CHECKSUM_MISMATCH,
"Checksum mismatch for ''{0}''; expected: ''{1}'', actual: ''{2}''",
new Object[] {fileInfo.getPath(), textChecksum, fileInfo.Checksum});
SVNErrorManager.error(err, SVNLogType.WC);
}
checksum = textChecksum;
}
SVNAdminArea adminArea = fileInfo.getAdminArea();
SVNLog log = dirInfo.getLog();
String name = fileInfo.Name;
SVNEntry fileEntry = adminArea.getEntry(name, false);
if (fileEntry == null && !fileInfo.IsAdded) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNVERSIONED_RESOURCE,
"''{0}'' is not under version control", fileInfo.getPath());
SVNErrorManager.error(err, SVNLogType.WC);
}
long previousRevision = fileEntry != null ? fileEntry.getRevision() : -1;
SVNURL previousURL = fileEntry != null ? fileEntry.getSVNURL() : null;
// merge props.
SVNProperties modifiedWCProps = fileInfo.getChangedWCProperties();
SVNProperties modifiedEntryProps = fileInfo.getChangedEntryProperties();
SVNProperties modifiedProps = fileInfo.getChangedProperties();
String commitTime = fileInfo.CommitTime;
SVNProperties command = new SVNProperties();
SVNStatusType textStatus = SVNStatusType.UNCHANGED;
SVNStatusType lockStatus = SVNStatusType.LOCK_UNCHANGED;
if (myAdminInfo.isIncomplete(fileInfo.getPath()) && fileEntry != null) {
// delete all props.
SVNVersionedProperties oldBaseProps = adminArea.getBaseProperties(fileEntry.getName());
SVNProperties baseMap = oldBaseProps.asMap();
if (modifiedProps == null) {
modifiedProps = new SVNProperties();
}
for(Iterator names = baseMap.nameSet().iterator(); names.hasNext();) {
String propName = (String) names.next();
if (!modifiedProps.containsName(propName)) {
modifiedProps.put(propName, SVNPropertyValue.create(null));
}
}
}
boolean magicPropsChanged = false;
if (modifiedProps != null && !modifiedProps.isEmpty()) {
magicPropsChanged = modifiedProps.containsName(SVNProperty.EXECUTABLE) ||
modifiedProps.containsName(SVNProperty.NEEDS_LOCK) ||
modifiedProps.containsName(SVNProperty.KEYWORDS) ||
modifiedProps.containsName(SVNProperty.EOL_STYLE) ||
modifiedProps.containsName(SVNProperty.CHARSET) ||
modifiedProps.containsName(SVNProperty.SPECIAL);
}
SVNStatusType propStatus = adminArea.mergeProperties(name, null, fileInfo.copiedBaseProperties,
fileInfo.copiedWorkingProperties, modifiedProps, null, null, true, false, log);
if (modifiedEntryProps != null) {
lockStatus = log.logChangedEntryProperties(name, modifiedEntryProps);
}
if (modifiedWCProps != null) {
log.logChangedWCProperties(name, modifiedWCProps);
}
boolean isLocallyModified = false;
if (fileInfo.copiedWorkingText != null) {
isLocallyModified = true;
} else if (!fileInfo.isExisted) {
isLocallyModified = adminArea.hasTextModifications(name, false, false, false);
} else if (isTextUpdated) {
isLocallyModified = adminArea.hasVersionedFileTextChanges(adminArea.getFile(name),
fileInfo.newBaseFile, false);
}
boolean isReplaced = fileEntry != null && fileEntry.isScheduledForReplacement();
SVNProperties logAttributes = new SVNProperties();
if (fileInfo.isAddExisted) {
logAttributes.put(SVNLog.FORCE_ATTR, "true");
logAttributes.put(SVNProperty.shortPropertyName(SVNProperty.SCHEDULE), "");
}
log.logTweakEntry(name, fileInfo.URL, myTargetRevision);
String absDirPath = adminArea.getRoot().getAbsolutePath().replace(File.separatorChar, '/');
String basePath = null;
if (fileInfo.baseFile != null) {
String absBasePath = fileInfo.baseFile.getAbsolutePath().replace(File.separatorChar, '/');
basePath = absBasePath.substring(absDirPath.length());
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
}
String tmpBasePath = null;
if (fileInfo.newBaseFile != null) {
String absTmpBasePath = fileInfo.newBaseFile.getAbsolutePath().replace(File.separatorChar, '/');
tmpBasePath = absTmpBasePath.substring(absDirPath.length());
if (tmpBasePath.startsWith("/")) {
tmpBasePath = tmpBasePath.substring(1);
}
}
SVNStatusType mergeOutcome = SVNStatusType.UNCHANGED;
File workingFile = adminArea.getFile(name);
boolean deletedCopiedBaseText = false;
if (tmpBasePath != null) {
textStatus = SVNStatusType.CHANGED;
// there is a text to replace the working copy with.
if (!isLocallyModified && !isReplaced) {
if (fileEntry == null || !fileEntry.isScheduledForDeletion()) {
command.put(SVNLog.NAME_ATTR, tmpBasePath);
command.put(SVNLog.DEST_ATTR, name);
log.addCommand(SVNLog.COPY_AND_TRANSLATE, command, false);
command.clear();
}
} else {
SVNFileType kind = SVNFileType.getType(workingFile);
if (kind == SVNFileType.NONE && !fileInfo.addedWithHistory) {
command.put(SVNLog.NAME_ATTR, tmpBasePath);
command.put(SVNLog.DEST_ATTR, name);
log.addCommand(SVNLog.COPY_AND_TRANSLATE, command, false);
command.clear();
} else if (!fileInfo.isExisted) {
File mergeLeftFile = fileInfo.baseFile;
String pathExt = null;
if (myExtensionPatterns != null && myExtensionPatterns.length > 0) {
int dotInd = name.lastIndexOf('.');
if (dotInd != -1 && dotInd != 0 && dotInd != name.length() - 1) {
pathExt = name.substring(dotInd + 1);
}
if (pathExt != null && !"".equals(pathExt)) {
boolean matches = false;
for (int i = 0; i < myExtensionPatterns.length; i++) {
String extPattern = myExtensionPatterns[i];
matches = DefaultSVNOptions.matches(extPattern, pathExt);
if (matches) {
break;
}
}
if (!matches) {
pathExt = null;
}
}
}
boolean deleteLeftMergeFile = false;
boolean deleteCopiedBaseText = false;
if (fileInfo.isAddExisted && !isReplaced) {
deleteLeftMergeFile = true;
mergeLeftFile = SVNAdminUtil.createTmpFile(adminArea);
} else if (fileInfo.copiedBaseText != null) {
deleteLeftMergeFile = deleteCopiedBaseText = true;
mergeLeftFile = fileInfo.copiedBaseText;
}
String absMergeLeftFilePath = mergeLeftFile.getAbsolutePath().replace(File.separatorChar, '/');
String mergeLeftFilePath = absMergeLeftFilePath.substring(absDirPath.length());
if (mergeLeftFilePath.startsWith("/")) {
mergeLeftFilePath = mergeLeftFilePath.substring(1);
}
String leftLabel = null;
if (fileInfo.addedWithHistory) {
leftLabel = ".copied" + (pathExt != null ? "." + pathExt : "");
} else {
leftLabel = ".r" + fileEntry.getRevision() + (pathExt != null ? "." + pathExt : "");
}
String rightLabel = ".r" + myTargetRevision + (pathExt != null ? "." + pathExt : "");
String mineLabel = ".mine" + (pathExt != null ? "." + pathExt : "");
// do test merge.
mergeOutcome = adminArea.mergeText(name, mergeLeftFile, adminArea.getFile(tmpBasePath),
fileInfo.copiedWorkingText, mineLabel, leftLabel, rightLabel, modifiedProps, false,
null, log);
if (mergeOutcome == SVNStatusType.UNCHANGED) {
textStatus = SVNStatusType.MERGED;
}
if (deleteLeftMergeFile) {
command.put(SVNLog.NAME_ATTR, mergeLeftFilePath);
log.addCommand(SVNLog.DELETE, command, false);
command.clear();
if (deleteCopiedBaseText) {
deletedCopiedBaseText = true;
}
}
if (fileInfo.copiedWorkingText != null) {
String absCopiedWorkingTextPath = fileInfo.copiedWorkingText.getAbsolutePath().replace(File.separatorChar, '/');
String copiedWorkingTextPath = absCopiedWorkingTextPath.substring(absDirPath.length());
if (copiedWorkingTextPath.startsWith("/")) {
copiedWorkingTextPath = copiedWorkingTextPath.substring(1);
}
command.put(SVNLog.NAME_ATTR, copiedWorkingTextPath);
log.addCommand(SVNLog.DELETE, command, false);
command.clear();
}
}
}
} else {
if (magicPropsChanged && (workingFile.exists() || SVNFileType.getType(workingFile) == SVNFileType.SYMLINK)) {
// only props were changed, but we have to retranslate file.
// only if wc file exists (may be locally deleted), otherwise no
// need to retranslate...
String tmpPath = SVNAdminUtil.getTextBasePath(name, true);
command.put(SVNLog.NAME_ATTR, name);
command.put(SVNLog.DEST_ATTR, tmpPath);
log.addCommand(SVNLog.COPY_AND_DETRANSLATE, command, false);
command.clear();
command.put(SVNLog.NAME_ATTR, tmpPath);
command.put(SVNLog.DEST_ATTR, name);
log.addCommand(SVNLog.COPY_AND_TRANSLATE, command, false);
command.clear();
}
if (lockStatus == SVNStatusType.LOCK_UNLOCKED) {
command.put(SVNLog.NAME_ATTR, name);
log.addCommand(SVNLog.MAYBE_READONLY, command, false);
command.clear();
}
}
if (tmpBasePath != null) {
command.put(SVNLog.NAME_ATTR, tmpBasePath);
command.put(SVNLog.DEST_ATTR, basePath);
log.addCommand(SVNLog.MOVE, command, false);
command.clear();
command.put(SVNLog.NAME_ATTR, basePath);
log.addCommand(SVNLog.READONLY, command, false);
command.clear();
if (!isReplaced) {
logAttributes.put(SVNProperty.shortPropertyName(SVNProperty.CHECKSUM), checksum);
}
}
if (logAttributes.size() > 0) {
logAttributes.put(SVNLog.NAME_ATTR, name);
log.addCommand(SVNLog.MODIFY_ENTRY, logAttributes, false);
}
if (!isLocallyModified && (fileInfo.IsAdded || fileEntry.getSchedule() == null)) {
if (commitTime != null && !fileInfo.isExisted) {
command.put(SVNLog.NAME_ATTR, name);
command.put(SVNLog.TIMESTAMP_ATTR, commitTime);
log.addCommand(SVNLog.SET_TIMESTAMP, command, false);
command.clear();
}
if (tmpBasePath != null || magicPropsChanged) {
command.put(SVNLog.NAME_ATTR, name);
command.put(SVNProperty.shortPropertyName(SVNProperty.TEXT_TIME), SVNLog.WC_TIMESTAMP);
log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
command.clear();
}
command.put(SVNLog.NAME_ATTR, name);
command.put(SVNProperty.shortPropertyName(SVNProperty.WORKING_SIZE), SVNLog.WC_WORKING_SIZE);
log.addCommand(SVNLog.MODIFY_ENTRY, command, false);
command.clear();
}
if (fileInfo.copiedBaseText != null && !deletedCopiedBaseText) {
String absCopiedBaseTextPath = fileInfo.copiedBaseText.getAbsolutePath().replace(File.separatorChar, '/');
String copiedBaseTextPath = absCopiedBaseTextPath.substring(absDirPath.length());
if (copiedBaseTextPath.startsWith("/")) {
copiedBaseTextPath = copiedBaseTextPath.substring(1);
}
command.put(SVNLog.NAME_ATTR, copiedBaseTextPath);
log.addCommand(SVNLog.DELETE, command, false);
command.clear();
}
// bump.
maybeBumpDirInfo(dirInfo);
if (mergeOutcome == SVNStatusType.CONFLICTED_UNRESOLVED) {
textStatus = SVNStatusType.CONFLICTED_UNRESOLVED;
} else if (mergeOutcome == SVNStatusType.CONFLICTED) {
textStatus = SVNStatusType.CONFLICTED;
} else if (fileInfo.newBaseFile != null) {
if (isLocallyModified) {
textStatus = SVNStatusType.MERGED;
} else {
textStatus = SVNStatusType.CHANGED;
}
}
// notify.
if ((textStatus != SVNStatusType.UNCHANGED ||
propStatus != SVNStatusType.UNCHANGED ||
lockStatus != SVNStatusType.LOCK_UNCHANGED)) {
SVNEventAction action = SVNEventAction.UPDATE_UPDATE;
if (fileInfo.isExisted || fileInfo.isAddExisted) {
if (textStatus != SVNStatusType.CONFLICTED_UNRESOLVED && textStatus != SVNStatusType.CONFLICTED) {
action = SVNEventAction.UPDATE_EXISTS;
}
} else if (fileInfo.IsAdded) {
action = SVNEventAction.UPDATE_ADD;
}
SVNEvent event = SVNEventFactory.createSVNEvent(adminArea.getFile(fileInfo.Name), SVNNodeKind.FILE, null, myTargetRevision, textStatus, propStatus, lockStatus, action, null, null, null);
event.setPreviousRevision(previousRevision);
event.setPreviousURL(previousURL);
event.setURL(fileInfo.URL != null ? SVNURL.parseURIEncoded(fileInfo.URL) : null);
myWCAccess.handleEvent(event);
}