private void copy( FSRevisionNode toNode, String entryName, FSRevisionNode fromNode, boolean preserveHistory, long fromRevision, String fromPath, String txnId) throws SVNException { FSID id = null; FSTransactionRoot txnRoot = getTxnRoot(); if (preserveHistory) { FSID srcId = fromNode.getId(); FSRevisionNode toRevNode = FSRevisionNode.dumpRevisionNode(fromNode); String copyId = reserveCopyId(txnId); toRevNode.setPredecessorId(srcId); if (toRevNode.getCount() != -1) { toRevNode.setCount(toRevNode.getCount() + 1); } String createdPath = SVNPathUtil.getAbsolutePath(SVNPathUtil.append(toNode.getCreatedPath(), entryName)); toRevNode.setCreatedPath(createdPath); toRevNode.setCopyFromPath(fromPath); toRevNode.setCopyFromRevision(fromRevision); toRevNode.setCopyRootPath(null); id = txnRoot.createSuccessor(srcId, toRevNode, copyId); } else { id = fromNode.getId(); } txnRoot.setEntry(toNode, entryName, id, fromNode.getType()); }
/** {@inheritDoc} */ @Override protected SCMRevision retrieve(String unparsedRevision, TaskListener listener) throws IOException, InterruptedException { try { listener.getLogger().println("Opening connection to " + remoteBase); SVNURL repoURL = SVNURL.parseURIEncoded(remoteBase); SVNRepositoryView repository = openSession(repoURL); String repoPath = SubversionSCM.DescriptorImpl.getRelativePath(repoURL, repository.getRepository()); String base; long revision; Matcher pathAtRev = Pattern.compile("(.+)@(\\d+)").matcher(unparsedRevision); if (pathAtRev.matches()) { base = pathAtRev.group(1); revision = Long.parseLong(pathAtRev.group(2)); } else { base = unparsedRevision; revision = -1; } String path = SVNPathUtil.append(repoPath, base); long resolvedRevision = repository.getNode(path, -1).getRevision(); if (resolvedRevision == -1) { listener.getLogger().println("Could not find " + path); return null; } return new SCMRevisionImpl(new SCMHead(base), revision == -1 ? resolvedRevision : revision); } catch (SVNException e) { throw new IOException(e); } }
@SuppressWarnings("unchecked") private List<ChangeInfo> logEntryToChangeInfos( final String rootPath, final String loggedPath, final SVNLogEntry entry, final boolean pathOnly) { final String fullLoggedPathFromAppend = SVNPathUtil.append(rootPath, loggedPath); final String fullLoggedPath = (!fullLoggedPathFromAppend.startsWith("/")) ? "/" + fullLoggedPathFromAppend : fullLoggedPathFromAppend; final List<ChangeInfo> results = new LinkedList<ChangeInfo>(); for (String changedPath : (Iterable<String>) entry.getChangedPaths().keySet()) { if (SVNPathUtil.isAncestor(rootPath, changedPath) && (!pathOnly || fullLoggedPath.equals(changedPath))) { ChangeInfo change = classifiedChange(entry, rootPath, changedPath); // Might want to put this at a higher level if we can ever do // something useful with 'other' changes. if (change.getKind() != StoreKind.OTHER) { results.add(change); } } } return results; }
public static Map adjustMergeInfoSourcePaths(Map mergeInfo, String walkPath, Map wcMergeInfo) { mergeInfo = mergeInfo == null ? new TreeMap() : mergeInfo; for (Iterator paths = wcMergeInfo.keySet().iterator(); paths.hasNext(); ) { String srcMergePath = (String) paths.next(); SVNMergeRangeList rangeList = (SVNMergeRangeList) wcMergeInfo.get(srcMergePath); mergeInfo.put( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(srcMergePath, walkPath)), rangeList); } return mergeInfo; }
@Nullable public FilePath getFilePath(final SvnVcs vcs) { if (!myHadChanged) return null; final SvnFileUrlMapping svnFileUrlMapping = vcs.getSvnFileUrlMapping(); final String absolutePath = SVNPathUtil.append(myRepositoryRoot, myCurrentPath); final String localPath = svnFileUrlMapping.getLocalPath(absolutePath); if (localPath == null) { LOG.info("Cannot find local path for url: " + absolutePath); return null; } return new FilePathImpl(new File(localPath), false); }
@Nullable private File getLocalPath(final String relativeToRepoPath) { // from source if not inverted final String pathToCheck = SVNPathUtil.append(myWcInfo.getRepositoryRoot(), relativeToRepoPath); final SvnBranchPointsCalculator.BranchCopyData wrapped = myCopyPoint.getWrapped(); final String relativeInSource = SVNPathUtil.getRelativePath( myCopyPoint.isInvertedSense() ? wrapped.getSource() : wrapped.getTarget(), pathToCheck); if (StringUtil.isEmptyOrSpaces(relativeInSource)) return null; final File local = new File(myWcInfo.getPath(), relativeInSource); return local; }
@Override public void run(ContinuationContext continuationContext) { final SVNURL branch = SvnBranchConfigurationManager.getInstance(myProject) .getSvnBranchConfigManager() .getWorkingBranchWithReload(myWcInfo.getUrl(), myRoot); if (branch != null && (!myWcInfo.getUrl().equals(branch))) { final String branchString = branch.toString(); if (SVNPathUtil.isAncestor(branchString, myWcInfo.getRootUrl())) { final String subPath = SVNPathUtil.getRelativePath(branchString, myWcInfo.getRootUrl()); mySourceUrl = SVNPathUtil.append(mySourceUrl, subPath); } } }
/** {@inheritDoc} */ @Override protected SCMRevision retrieve(@NonNull SCMHead head, @NonNull TaskListener listener) throws IOException { SVNRepositoryView repository = null; try { listener.getLogger().println("Opening connection to " + remoteBase); SVNURL repoURL = SVNURL.parseURIEncoded(remoteBase); repository = openSession(repoURL); String repoPath = SubversionSCM.DescriptorImpl.getRelativePath(repoURL, repository.getRepository()); String path = SVNPathUtil.append(repoPath, head.getName()); SVNRepositoryView.NodeEntry svnEntry = repository.getNode(path, -1); return new SCMRevisionImpl(head, svnEntry.getRevision()); } catch (SVNException e) { throw new IOException(e); } finally { closeSession(repository); } }
public FSRevisionNode makeEntry( FSRevisionNode parent, String parentPath, String entryName, boolean isDir, String txnId) throws SVNException { if (!SVNPathUtil.isSinglePathComponent(entryName)) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_NOT_SINGLE_PATH_COMPONENT, "Attempted to create a node with an illegal name ''{0}''", entryName); SVNErrorManager.error(err, SVNLogType.FSFS); } if (parent.getType() != SVNNodeKind.DIR) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_NOT_DIRECTORY, "Attempted to create entry in non-directory parent"); SVNErrorManager.error(err, SVNLogType.FSFS); } if (!parent.getId().isTxn()) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_NOT_MUTABLE, "Attempted to clone child of non-mutable node"); SVNErrorManager.error(err, SVNLogType.FSFS); } FSRevisionNode newRevNode = new FSRevisionNode(); newRevNode.setType(isDir ? SVNNodeKind.DIR : SVNNodeKind.FILE); String createdPath = SVNPathUtil.getAbsolutePath(SVNPathUtil.append(parentPath, entryName)); newRevNode.setCreatedPath(createdPath); newRevNode.setCopyRootPath(parent.getCopyRootPath()); newRevNode.setCopyRootRevision(parent.getCopyRootRevision()); newRevNode.setCopyFromRevision(SVNRepository.INVALID_REVISION); newRevNode.setCopyFromPath(null); FSID newNodeId = createNode(newRevNode, parent.getId().getCopyID(), txnId); FSRevisionNode childNode = myFSFS.getRevisionNode(newNodeId); FSTransactionRoot txnRoot = getTxnRoot(); txnRoot.setEntry(parent, entryName, childNode.getId(), newRevNode.getType()); return childNode; }
public void accept(final SVNLogEntry entry) { final Map changedPaths = entry.getChangedPaths(); if (changedPaths == null) return; for (Object o : changedPaths.values()) { final SVNLogEntryPath entryPath = (SVNLogEntryPath) o; if (entryPath != null && 'A' == entryPath.getType() && entryPath.getCopyPath() != null) { if (myCurrentPath.equals(entryPath.getPath())) { myHadChanged = true; myCurrentPath = entryPath.getCopyPath(); return; } else if (SVNPathUtil.isAncestor(entryPath.getPath(), myCurrentPath)) { final String relativePath = SVNPathUtil.getRelativePath(entryPath.getPath(), myCurrentPath); myCurrentPath = SVNPathUtil.append(entryPath.getCopyPath(), relativePath); myHadChanged = true; return; } } } }
public static boolean shouldElideMergeInfo( Map parentMergeInfo, Map childMergeInfo, String pathSuffix) { boolean elides = false; if (childMergeInfo != null) { if (childMergeInfo.isEmpty()) { if (parentMergeInfo == null || parentMergeInfo.isEmpty()) { elides = true; } } else if (!(parentMergeInfo == null || parentMergeInfo.isEmpty())) { Map pathTweakedMergeInfo = parentMergeInfo; if (pathSuffix != null) { pathTweakedMergeInfo = new TreeMap(); for (Iterator paths = parentMergeInfo.keySet().iterator(); paths.hasNext(); ) { String mergeSrcPath = (String) paths.next(); pathTweakedMergeInfo.put( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(mergeSrcPath, pathSuffix)), parentMergeInfo.get(mergeSrcPath)); } } elides = mergeInfoEquals(pathTweakedMergeInfo, childMergeInfo, true); } } return elides; }
void fetch( @NonNull TaskListener listener, @NonNull final SVNRepositoryView repository, long rev, @NonNull final String repoPath, @NonNull SortedSet<List<String>> paths, @NonNull List<String> prefix, @NonNull List<String> realPath, @NonNull SortedSet<List<String>> excludedPaths, @CheckForNull SCMSourceCriteria branchCriteria, @NonNull SCMHeadObserver observer) throws IOException, SVNException { String svnPath = SVNPathUtil.append(repoPath, StringUtils.join(realPath, '/')); assert prefix.size() == realPath.size(); assert wildcardStartsWith(realPath, prefix); SortedMap<List<String>, SortedSet<List<String>>> includePaths = groupPaths(paths, prefix); listener .getLogger() .println("Checking directory " + svnPath + (rev > -1 ? "@" + rev : "@HEAD")); SVNRepositoryView.NodeEntry node = repository.getNode(svnPath, rev); if (!SVNNodeKind.DIR.equals(node.getType()) || node.getChildren() == null) { return; } for (Map.Entry<List<String>, SortedSet<List<String>>> entry : includePaths.entrySet()) { for (List<String> path : entry.getValue()) { String name = path.get(prefix.size()); SVNRepositoryView.ChildEntry[] children = node.getChildren().clone(); Arrays.sort( children, new Comparator<SVNRepositoryView.ChildEntry>() { public int compare(SVNRepositoryView.ChildEntry o1, SVNRepositoryView.ChildEntry o2) { long diff = o2.getRevision() - o1.getRevision(); return diff < 0 ? -1 : diff > 0 ? 1 : 0; } }); for (final SVNRepositoryView.ChildEntry svnEntry : children) { if (svnEntry.getType() == SVNNodeKind.DIR && isMatch(svnEntry.getName(), name)) { List<String> childPrefix = copyAndAppend(prefix, name); List<String> childRealPath = copyAndAppend(realPath, svnEntry.getName()); if (wildcardStartsWith(childRealPath, excludedPaths)) { continue; } if (path.equals(childPrefix)) { final String childPath = StringUtils.join(childRealPath, '/'); final String candidateRootPath = SVNPathUtil.append(repoPath, childPath); final long candidateRevision = svnEntry.getRevision(); final long lastModified = svnEntry.getLastModified(); listener .getLogger() .println( "Checking candidate branch " + candidateRootPath + "@" + candidateRevision); if (branchCriteria == null || branchCriteria.isHead( new SCMSourceCriteria.Probe() { @Override public String name() { return childPath; } @Override public long lastModified() { return lastModified; } @Override public boolean exists(@NonNull String path) throws IOException { try { return repository.checkPath( SVNPathUtil.append(candidateRootPath, path), candidateRevision) != SVNNodeKind.NONE; } catch (SVNException e) { throw new IOException(e); } } }, listener)) { listener.getLogger().println("Met criteria"); SCMHead head = new SCMHead(childPath); observer.observe(head, new SCMRevisionImpl(head, svnEntry.getRevision())); if (!observer.isObserving()) { return; } } else { listener.getLogger().println("Does not meet criteria"); } } else { fetch( listener, repository, svnEntry.getRevision(), repoPath, paths, childPrefix, childRealPath, excludedPaths, branchCriteria, observer); } } } } } }
private static long merge( FSFS owner, String targetPath, FSRevisionNode target, FSRevisionNode source, FSRevisionNode ancestor, FSTransactionRoot txnRoot, StringBuffer conflictPath) throws SVNException { FSID sourceId = source.getId(); FSID targetId = target.getId(); FSID ancestorId = ancestor.getId(); long mergeInfoIncrement = 0; if (ancestorId.equals(targetId)) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_GENERAL, "Bad merge; target ''{0}'' has id ''{1}'', same as ancestor", new Object[] {targetPath, targetId}); SVNErrorManager.error(err, SVNLogType.FSFS); } if (ancestorId.equals(sourceId) || sourceId.equals(targetId)) { return mergeInfoIncrement; } if (source.getType() != SVNNodeKind.DIR || target.getType() != SVNNodeKind.DIR || ancestor.getType() != SVNNodeKind.DIR) { SVNErrorManager.error(FSErrors.errorConflict(targetPath, conflictPath), SVNLogType.FSFS); } if (!FSRepresentation.compareRepresentations( target.getPropsRepresentation(), ancestor.getPropsRepresentation())) { SVNErrorManager.error(FSErrors.errorConflict(targetPath, conflictPath), SVNLogType.FSFS); } Map sourceEntries = source.getDirEntries(owner); Map targetEntries = target.getDirEntries(owner); Map ancestorEntries = ancestor.getDirEntries(owner); Set removedEntries = new SVNHashSet(); for (Iterator ancestorEntryNames = ancestorEntries.keySet().iterator(); ancestorEntryNames.hasNext(); ) { String ancestorEntryName = (String) ancestorEntryNames.next(); FSEntry ancestorEntry = (FSEntry) ancestorEntries.get(ancestorEntryName); FSEntry sourceEntry = removedEntries.contains(ancestorEntryName) ? null : (FSEntry) sourceEntries.get(ancestorEntryName); FSEntry targetEntry = (FSEntry) targetEntries.get(ancestorEntryName); if (sourceEntry != null && ancestorEntry.getId().equals(sourceEntry.getId())) { /* * No changes were made to this entry while the transaction was * in progress, so do nothing to the target. */ } else if (targetEntry != null && ancestorEntry.getId().equals(targetEntry.getId())) { if (owner.supportsMergeInfo()) { FSRevisionNode targetEntryNode = owner.getRevisionNode(targetEntry.getId()); long mergeInfoStart = targetEntryNode.getMergeInfoCount(); mergeInfoIncrement -= mergeInfoStart; } if (sourceEntry != null) { if (owner.supportsMergeInfo()) { FSRevisionNode sourceEntryNode = owner.getRevisionNode(sourceEntry.getId()); long mergeInfoEnd = sourceEntryNode.getMergeInfoCount(); mergeInfoIncrement += mergeInfoEnd; } txnRoot.setEntry(target, ancestorEntryName, sourceEntry.getId(), sourceEntry.getType()); } else { txnRoot.deleteEntry(target, ancestorEntryName); } } else { if (sourceEntry == null || targetEntry == null) { SVNErrorManager.error( FSErrors.errorConflict( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(targetPath, ancestorEntryName)), conflictPath), SVNLogType.FSFS); } if (sourceEntry.getType() == SVNNodeKind.FILE || targetEntry.getType() == SVNNodeKind.FILE || ancestorEntry.getType() == SVNNodeKind.FILE) { SVNErrorManager.error( FSErrors.errorConflict( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(targetPath, ancestorEntryName)), conflictPath), SVNLogType.FSFS); } if (!sourceEntry.getId().getNodeID().equals(ancestorEntry.getId().getNodeID()) || !sourceEntry.getId().getCopyID().equals(ancestorEntry.getId().getCopyID()) || !targetEntry.getId().getNodeID().equals(ancestorEntry.getId().getNodeID()) || !targetEntry.getId().getCopyID().equals(ancestorEntry.getId().getCopyID())) { SVNErrorManager.error( FSErrors.errorConflict( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(targetPath, ancestorEntryName)), conflictPath), SVNLogType.FSFS); } FSRevisionNode sourceEntryNode = owner.getRevisionNode(sourceEntry.getId()); FSRevisionNode targetEntryNode = owner.getRevisionNode(targetEntry.getId()); FSRevisionNode ancestorEntryNode = owner.getRevisionNode(ancestorEntry.getId()); String childTargetPath = SVNPathUtil.getAbsolutePath(SVNPathUtil.append(targetPath, targetEntry.getName())); long subMergeInfoIncrement = merge( owner, childTargetPath, targetEntryNode, sourceEntryNode, ancestorEntryNode, txnRoot, conflictPath); if (owner.supportsMergeInfo()) { mergeInfoIncrement += subMergeInfoIncrement; } } removedEntries.add(ancestorEntryName); } for (Iterator sourceEntryNames = sourceEntries.keySet().iterator(); sourceEntryNames.hasNext(); ) { String sourceEntryName = (String) sourceEntryNames.next(); if (removedEntries.contains(sourceEntryName)) { continue; } FSEntry sourceEntry = (FSEntry) sourceEntries.get(sourceEntryName); FSEntry targetEntry = (FSEntry) targetEntries.get(sourceEntryName); if (targetEntry != null) { SVNErrorManager.error( FSErrors.errorConflict( SVNPathUtil.getAbsolutePath(SVNPathUtil.append(targetPath, targetEntry.getName())), conflictPath), SVNLogType.FSFS); } if (owner.supportsMergeInfo()) { FSRevisionNode sourceEntryNode = owner.getRevisionNode(sourceEntry.getId()); long mergeInfoCount = sourceEntryNode.getMergeInfoCount(); mergeInfoIncrement += mergeInfoCount; } txnRoot.setEntry(target, sourceEntry.getName(), sourceEntry.getId(), sourceEntry.getType()); } long sourceCount = source.getCount(); updateAncestry(owner, sourceId, targetId, targetPath, sourceCount); if (owner.supportsMergeInfo()) { txnRoot.incrementMergeInfoCount(target, mergeInfoIncrement); } return mergeInfoIncrement; }
public void execute() throws SVNException { String versionName = getRequestHeader(SVN_VERSION_NAME_HEADER); long version = DAVResource.INVALID_REVISION; try { version = Long.parseLong(versionName); } catch (NumberFormatException e) { } DAVRepositoryManager manager = getRepositoryManager(); // use latest version, if no version was specified SVNRepository resourceRepository = SVNGitRepositoryFactory.create(SVNURL.parseURIEncoded(manager.getResourceRepositoryRoot())); if (version == -1) { version = resourceRepository.getLatestRevision(); } resourceRepository.testConnection(); // to open the repository // get the source path to move or copy DAVResourceURI sourceURI = new DAVResourceURI( manager.getResourceContext(), manager.getResourcePathInfo(), null, false, version); String sourcePath = sourceURI.getPath(); sourcePath = DAVPathUtil.dropLeadingSlash(sourcePath); String destination = getRequestHeader(HTTPHeader.DESTINATION_HEADER); if (destination == null) { String netScapeHost = getRequestHeader(HTTPHeader.HOST_HEADER); String netScapeNewURI = getRequestHeader(HTTPHeader.NEW_URI_HEADER); if (netScapeHost != null && netScapeNewURI != null) { String path = SVNPathUtil.append(netScapeHost, netScapeNewURI); if (path.startsWith("/")) { path = path.substring(1); } destination = "http://" + path; } } if (destination == null) { SVNDebugLog.getDefaultLog() .logFine(SVNLogType.NETWORK, "The request is missing a Destination header."); sendError(HttpServletResponse.SC_BAD_REQUEST, null); return; } // get the destination path to move or copy URI uri = DAVServletUtil.lookUpURI(destination, getRequest(), true); String resourceContext = manager.getResourceContext(); String path = uri.getPath().substring(resourceContext.length()); DAVResourceURI destinationURI = new DAVResourceURI(manager.getResourceContext(), path, null, false, version); String destinationPath = destinationURI.getPath(); destinationPath = DAVPathUtil.dropLeadingSlash(destinationPath); TreeBuilder treeBuilder = SVNGitPropPatchHandler.treeBuilders.get(destinationURI.getActivityID()); if (treeBuilder == null) { sendError(HttpServletResponse.SC_BAD_REQUEST, null); return; } if (myIsMove) { treeBuilder.move(sourcePath, destinationPath); } else { treeBuilder.copy(sourcePath, destinationPath); } handleDAVCreated(destination.toString(), "Destination", false); // FIXME: always false? }
private static void list( SVNRepository repository, String path, long rev, SVNDepth depth, int entryFields, Map<SVNURL, SVNPropertyValue> externals, SVNURL externalParentUrl, String externalTarget, ISVNDirEntryHandler handler) throws SVNException { if (depth == SVNDepth.EMPTY) { return; } Collection entries = new TreeSet(); SVNProperties properties; try { properties = externals == null ? null : new SVNProperties(); entries = repository.getDir(path, rev, properties, entryFields, entries); } catch (SVNAuthenticationException e) { return; } catch (SVNException e) { if (e.getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_AUTHORIZED) { return; } throw e; } SVNPropertyValue svnExternalsVaule = properties == null ? null : properties.getSVNPropertyValue(SVNProperty.EXTERNALS); if (svnExternalsVaule != null) { SVNURL location = repository.getLocation(); externals.put(location.appendPath(path, false), svnExternalsVaule); } for (Iterator iterator = entries.iterator(); iterator.hasNext(); ) { SVNDirEntry entry = (SVNDirEntry) iterator.next(); String childPath = SVNPathUtil.append(path, entry.getName()); entry.setRelativePath(childPath); if (entry.getKind() == SVNNodeKind.FILE || depth == SVNDepth.IMMEDIATES || depth == SVNDepth.INFINITY) { entry.setExternalParentUrl(externalParentUrl); entry.setExternalTarget(externalTarget); handler.handleDirEntry(entry); } if (entry.getKind() == SVNNodeKind.DIR && entry.getDate() != null && depth == SVNDepth.INFINITY) { list( repository, childPath, rev, depth, entryFields, externals, externalParentUrl, externalTarget, handler); } } }
public void run() throws SVNException { List targets = getSVNEnvironment().combineTargets(new ArrayList(), true); if (targets.isEmpty()) { SVNErrorManager.error( SVNErrorMessage.create(SVNErrorCode.CL_INSUFFICIENT_ARGS), SVNLogType.CLIENT); } String lastTarget = (String) targets.get(targets.size() - 1); if (SVNCommandUtil.isURL(lastTarget)) { if (targets.size() == 1) { SVNPath target = new SVNPath(lastTarget, true); lastTarget = target.getURL().getPath(); lastTarget = SVNPathUtil.tail(lastTarget); } else { lastTarget = ""; } targets.add(lastTarget); } else if (targets.size() == 1) { SVNErrorManager.error( SVNErrorMessage.create(SVNErrorCode.CL_INSUFFICIENT_ARGS), SVNLogType.CLIENT); } SVNUpdateClient client = getSVNEnvironment().getClientManager().getUpdateClient(); if (!getSVNEnvironment().isQuiet()) { client.setEventHandler(new SVNNotifyPrinter(getSVNEnvironment(), true, false, false)); } SVNRevision revision = getSVNEnvironment().getStartRevision(); for (int i = 0; i < targets.size() - 1; i++) { String targetName = (String) targets.get(i); SVNPath target = new SVNPath(targetName, true); if (!target.isURL()) { SVNErrorManager.error( SVNErrorMessage.create( SVNErrorCode.BAD_URL, "''{0}'' doesn not appear to be a URL", targetName), SVNLogType.CLIENT); } String targetDir; SVNPath dstTarget; if (targets.size() == 2) { // url + path targetDir = lastTarget; dstTarget = new SVNPath(targetDir); } else { // all urls + base dst. targetDir = target.getURL().getPath(); targetDir = SVNPathUtil.tail(targetDir); targetDir = SVNPathUtil.append(lastTarget, targetDir); dstTarget = new SVNPath(targetDir); } SVNRevision pegRevision = target.getPegRevision(); if (revision == SVNRevision.UNDEFINED) { revision = pegRevision != SVNRevision.UNDEFINED ? pegRevision : SVNRevision.HEAD; } client.doCheckout( target.getURL(), dstTarget.getFile(), pegRevision, revision, getSVNEnvironment().getDepth(), getSVNEnvironment().isForce()); } }