package org.tmatesoft.svn.core.internal.wc2.ng; import java.io.File; import java.util.List; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNNodeKind; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.internal.wc.SVNFileType; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import org.tmatesoft.svn.core.internal.wc17.SVNWCContext; import org.tmatesoft.svn.core.internal.wc17.SvnConflictReport; import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration; import org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec; import org.tmatesoft.svn.core.internal.wc2.ng.SvnNgMergeDriver.MergeSource; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc2.SvnMerge; import org.tmatesoft.svn.util.SVNLogType; public class SvnNgMergePegged extends SvnNgOperationRunner<Void, SvnMerge> { @Override public boolean isApplicable(SvnMerge operation, SvnWcGeneration wcGeneration) throws SVNException { return super.isApplicable(operation, wcGeneration) && !operation.isReintegrate() && operation.getSource() != null && operation.getRevisionRanges() != null; } @Override protected Void run(SVNWCContext context) throws SVNException { if (getOperation().getRevisionRanges() == null || getOperation().getRevisionRanges().isEmpty()) { return null; } SvnConflictReport conflictReport; File lockPath = getLockPath(getFirstTarget()); if (getOperation().isDryRun()) { SvnNgMergeDriver.MergeData mergeData = merge(getFirstTarget()); conflictReport = mergeData.conflictReport; } else { try { lockPath = context.acquireWriteLock(lockPath, false, true); SvnNgMergeDriver.MergeData mergeData = merge(getFirstTarget()); conflictReport = mergeData.conflictReport; } finally { context.releaseWriteLock(lockPath); sleepForTimestamp(); } } SvnNgMergeDriver.makeMergeConflictError(conflictReport); return null; } private File getLockPath(File firstTarget) throws SVNException { SVNNodeKind kind = getWcContext().readKind(firstTarget, false); if (kind == SVNNodeKind.DIR) { return firstTarget; } else { return SVNFileUtil.getParentFile(firstTarget); } } private SvnNgMergeDriver.MergeData merge(File target) throws SVNException { SVNFileType ft = SVNFileType.getType(target); if (ft == SVNFileType.NONE) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_PATH_NOT_FOUND, "Path ''{0}'' does not exist", target); SVNErrorManager.error(err, SVNLogType.WC); } SVNURL url = getRepositoryAccess().getTargetURL(getOperation().getSource()); if (url == null) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", getOperation().getSource()); SVNErrorManager.error(err, SVNLogType.WC); } SVNNodeKind targetKind = getWcContext().readKind(target, false); if (targetKind != SVNNodeKind.DIR && targetKind != SVNNodeKind.FILE) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ILLEGAL_TARGET, "Merge target ''{0}'' does not exist in the working copy", target); SVNErrorManager.error(err, SVNLogType.WC); } SvnNgMergeDriver mergeDriver = new SvnNgMergeDriver(getWcContext(), getOperation(), getRepositoryAccess(), getOperation().getMergeOptions()); mergeDriver.ensureWcIsSuitableForMerge(target, getOperation().isAllowMixedRevisions(), true, true); SVNURL wcReposRootURL = getWcContext().getNodeReposInfo(target).reposRootUrl; boolean sameRepos = true; SVNRepository repos = getRepositoryAccess().createRepository(url, null, false); List<MergeSource> sources = null; try { SVNURL sourceRootURL = repos.getRepositoryRoot(true); sources = mergeDriver.normalizeMergeSources(getOperation().getSource(), url, sourceRootURL, getOperation().getSource().getResolvedPegRevision(), SvnCodec.oldRevisionRanges(getOperation().getRevisionRanges()), repos); // if (!wcReposRootURL.equals(sourceRootURL)) { String targetUuid = getWcContext().getNodeReposInfo(target).reposUuid; String sourceUuid = repos.getRepositoryUUID(true); sameRepos = targetUuid.equals(sourceUuid); } return mergeDriver.doMerge(null, sources, target, repos, true, sameRepos, getOperation().isIgnoreMergeInfo(), getOperation().isIgnoreAncestry(), getOperation().isForce(), getOperation().isDryRun(), getOperation().isRecordOnly(), null, false, false, getOperation().getDepth(), getOperation().getMergeOptions()); } finally { repos.closeSession(); } } }