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()); }
@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; }
@Override public void run(ContinuationContext continuationContext) { if (SVNPathUtil.isAncestor(mySourceUrl, myWcInfo.getRootUrl()) || SVNPathUtil.isAncestor(myWcInfo.getRootUrl(), mySourceUrl)) { finishWithError(continuationContext, "Cannot merge from self", true); return; } if (!checkForSwitchedRoots()) { continuationContext.cancelEverything(); } }
@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); } } }
public SVNDirEntry info(String path, long revision) throws SVNException { try { openConnection(); String fullPath = getFullPath(path); SVNURL url = getLocation().setPath(fullPath, false); path = getRepositoryPath(path); Object[] buffer = new Object[] {"stat", path, getRevisionObject(revision)}; write("(w(s(n)))", buffer); authenticate(); read("[((?F))]", buffer, true); SVNDirEntry entry = (SVNDirEntry) buffer[0]; if (entry != null) { entry = new SVNDirEntry( url, SVNPathUtil.tail(path), entry.getKind(), entry.getSize(), entry.hasProperties(), entry.getRevision(), entry.getDate(), entry.getAuthor()); } return entry; } catch (SVNException e) { closeSession(); handleUnsupportedCommand(e, "'stat' not implemented"); } finally { closeConnection(); } return null; }
public static void allowLockedOperation( FSFS fsfs, String path, final String username, final Collection lockTokens, boolean recursive, boolean haveWriteLock) throws SVNException { path = SVNPathUtil.canonicalizeAbsolutePath(path); if (recursive) { ISVNLockHandler handler = new ISVNLockHandler() { private String myUsername = username; private Collection myTokens = lockTokens; public void handleLock(String path, SVNLock lock, SVNErrorMessage error) throws SVNException { verifyLock(lock, myTokens, myUsername); } public void handleUnlock(String path, SVNLock lock, SVNErrorMessage error) throws SVNException {} }; fsfs.walkDigestFiles(fsfs.getDigestFileFromRepositoryPath(path), handler, haveWriteLock); } else { SVNLock lock = fsfs.getLockHelper(path, haveWriteLock); if (lock != null) { verifyLock(lock, lockTokens, username); } } }
public void addChange( String path, FSID id, FSPathChangeKind changeKind, boolean textModified, boolean propsModified, long copyFromRevision, String copyFromPath, SVNNodeKind kind) throws SVNException { path = SVNPathUtil.canonicalizeAbsolutePath(path); OutputStream changesFile = null; try { FSTransactionRoot txnRoot = getTxnRoot(); changesFile = SVNFileUtil.openFileForWriting(txnRoot.getTransactionChangesFile(), true); FSPathChange pathChange = new FSPathChange( path, id, changeKind, textModified, propsModified, copyFromPath, copyFromRevision, kind); txnRoot.writeChangeEntry(changesFile, pathChange, true); } catch (IOException ioe) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage()); SVNErrorManager.error(err, ioe, SVNLogType.FSFS); } finally { SVNFileUtil.closeFile(changesFile); } }
public void makeDir(String path) throws SVNException { SVNPathUtil.checkPathIsValid(path); FSTransactionRoot txnRoot = getTxnRoot(); String txnId = txnRoot.getTxnID(); FSParentPath parentPath = txnRoot.openPath(path, false, true); if (parentPath.getRevNode() != null) { SVNErrorManager.error(FSErrors.errorAlreadyExists(txnRoot, path, myFSFS), SVNLogType.FSFS); } if ((txnRoot.getTxnFlags() & FSTransactionRoot.SVN_FS_TXN_CHECK_LOCKS) != 0) { FSCommitter.allowLockedOperation(myFSFS, path, myAuthor, myLockTokens, true, false); } makePathMutable(parentPath.getParent(), path); FSRevisionNode subDirNode = makeEntry( parentPath.getParent().getRevNode(), parentPath.getParent().getAbsPath(), parentPath.getEntryName(), true, txnId); txnRoot.putRevNodeToCache(parentPath.getAbsPath(), subDirNode); addChange( path, subDirNode.getId(), FSPathChangeKind.FS_PATH_CHANGE_ADD, false, false, SVNRepository.INVALID_REVISION, null, SVNNodeKind.DIR); }
/** {@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); } }
private void verifyLocks() throws SVNException { FSTransactionRoot txnRoot = getTxnRoot(); Map changes = txnRoot.getChangedPaths(); Object[] changedPaths = changes.keySet().toArray(); Arrays.sort(changedPaths); String lastRecursedPath = null; for (int i = 0; i < changedPaths.length; i++) { String changedPath = (String) changedPaths[i]; boolean recurse = true; if (lastRecursedPath != null && SVNPathUtil.getPathAsChild(lastRecursedPath, changedPath) != null) { continue; } FSPathChange change = (FSPathChange) changes.get(changedPath); if (change.getChangeKind() == FSPathChangeKind.FS_PATH_CHANGE_MODIFY) { recurse = false; } allowLockedOperation(myFSFS, changedPath, myAuthor, myLockTokens, recurse, true); if (recurse) { lastRecursedPath = changedPath; } } }
@Nullable public String getUrlRootForUrl(final String currentUrl) { for (String url : myMapping.getUrls()) { if (SVNPathUtil.isAncestor(url, currentUrl)) { return url; } } return null; }
// TODO: this makes sense only for directories, but should always return true if something under // the directory was changed in revision // TODO: as svn will provide child changes in history for directory private boolean checkForChildChanges(LogEntry logEntry) { final String lastPathBefore = myLastPathCorrector.getBefore(); for (String key : logEntry.getChangedPaths().keySet()) { if (SVNPathUtil.isAncestor(lastPathBefore, key)) { return true; } } return false; }
private boolean checkForParentChanges(LogEntry logEntry) { final String lastPathBefore = myLastPathCorrector.getBefore(); String path = SVNPathUtil.removeTail(lastPathBefore); while (path.length() > 0) { final LogEntryPath entryPath = logEntry.getChangedPaths().get(path); // A & D are checked since we are not interested in parent folders property changes, only in // structure changes // TODO: seems that R (replaced) should also be checked here if (entryPath != null && (entryPath.getType() == 'A' || entryPath.getType() == 'D')) { if (entryPath.getCopyPath() != null) { return true; } break; } path = SVNPathUtil.removeTail(path); } return false; }
@Nullable public static SvnBranchConfigurationNew loadDefaultConfiguration( final Project project, final VirtualFile vcsRoot) { try { final SvnVcs vcs = SvnVcs.getInstance(project); File rootFile = new File(vcsRoot.getPath()); final Info info = vcs.getInfo(rootFile); if (info == null || info.getURL() == null) { LOG.info("Directory is not a working copy: " + vcsRoot.getPresentableUrl()); return null; } SVNURL baseUrl = info.getURL(); final SvnBranchConfigurationNew result = new SvnBranchConfigurationNew(); result.setTrunkUrl(baseUrl.toString()); while (true) { final String s = SVNPathUtil.tail(baseUrl.getPath()); if (s.equalsIgnoreCase(DEFAULT_TRUNK_NAME) || s.equalsIgnoreCase(DEFAULT_BRANCHES_NAME) || s.equalsIgnoreCase(DEFAULT_TAGS_NAME)) { SVNURL rootPath = baseUrl.removePathTail(); SvnTarget target = SvnTarget.fromURL(rootPath); vcs.getFactory(target) .createBrowseClient() .list(target, SVNRevision.HEAD, Depth.IMMEDIATES, createHandler(result, rootPath)); break; } if (SVNPathUtil.removeTail(baseUrl.getPath()).length() == 0) { break; } baseUrl = baseUrl.removePathTail(); } return result; } catch (SVNException e) { LOG.info(e); return null; } catch (VcsException e) { LOG.info(e); return null; } }
static ChangeInfo classifiedChange(final SVNLogEntry entry, String rootPath, final String path) { StoreKind kind = StoreKind.OTHER; // Be sure the root path ends with a slash because the 'path' will always have the slash. if (!rootPath.endsWith("/")) { rootPath = rootPath + "/"; } String name = path.length() > rootPath.length() ? path.substring(rootPath.length()) : path; String page = null; Matcher matcher = PAGE_PATH.matcher(name); if (matcher.matches() && !name.endsWith("-attachments")) { kind = StoreKind.PAGE; page = name; } else { matcher = ATTACHMENT_PATH.matcher(name); if (matcher.matches()) { kind = StoreKind.ATTACHMENT; page = matcher.group(1); name = matcher.group(2); } } String user = entry.getAuthor(); Date date = entry.getDate(); SVNLogEntryPath logForPath = (SVNLogEntryPath) entry.getChangedPaths().get(path); String copiedFrom = logForPath.getCopyPath(); long copiedFromRevision = -1; if (SVNPathUtil.isAncestor(rootPath, copiedFrom)) { copiedFrom = SVNPathUtil.tail(copiedFrom); copiedFromRevision = logForPath.getCopyRevision(); } else { copiedFrom = null; } return new ChangeInfo( page, name, user, date, entry.getRevision(), entry.getMessage(), kind, ChangeType.forCode(logForPath.getType()), copiedFrom, copiedFromRevision); }
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 copy( final ISVNEditor commitEditor, final String fromPath, final long fromRevision, final String toPath) throws SVNException { String dir = SVNPathUtil.removeTail(toPath); commitEditor.openDir(dir, -1); commitEditor.addFile(toPath, fromPath, fromRevision); commitEditor.closeDir(); }
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; } } } }
@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); }
public void moveDir( final ISVNEditor commitEditor, final String fromPath, final long baseRevision, final String toPath) throws SVNException { String dir = SVNPathUtil.removeTail(toPath); commitEditor.openDir(dir, -1); commitEditor.deleteEntry(fromPath, baseRevision); commitEditor.addDir(toPath, fromPath, baseRevision); commitEditor.closeDir(); }
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; }
/** {@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 boolean handleCommitPath(String path, ISVNEditor editor) throws SVNException { ElideMergeInfoEditor elideEditor = (ElideMergeInfoEditor) editor; String inheritedMergeInfoPath = elideEditor.getInheritedMergeInfoPath(); if (inheritedMergeInfoPath == null || "/".equals(path)) { return false; } String pathSuffix = SVNPathUtil.getPathAsChild(inheritedMergeInfoPath, path); if (pathSuffix == null) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "path suffix is null"); SVNErrorManager.error(err, SVNLogType.DEFAULT); } boolean elides = shouldElideMergeInfo( (Map) myMergeInfoCatalog.get(inheritedMergeInfoPath), (Map) myMergeInfoCatalog.get(path), pathSuffix); if (elides) { myElidablePaths.add(path); } return false; }
protected void initOptions(SVNCommandLine commandLine) throws SVNException { super.initOptions(commandLine); if (getCommand().getClass() == SVNDumpFilterHelpCommand.class) { return; } List arguments = getArguments(); myPrefixes = new LinkedList(); if (arguments != null) { for (Iterator prefixesIter = arguments.iterator(); prefixesIter.hasNext(); ) { String prefix = (String) prefixesIter.next(); prefix = prefix.replace(File.separatorChar, '/'); prefix = SVNPathUtil.canonicalizePath(prefix); if (!prefix.startsWith("/")) { prefix = "/" + prefix; } myPrefixes.add(prefix); } } if (myTargetsFile != null) { File targetsFile = new File(myTargetsFile); String contents = new String(readFromFile(targetsFile)); for (StringTokenizer tokens = new StringTokenizer(contents, "\n\r"); tokens.hasMoreTokens(); ) { String prefix = tokens.nextToken(); myPrefixes.add(prefix); } } if (myPrefixes.isEmpty()) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CL_INSUFFICIENT_ARGS, "Error: no prefixes supplied."); SVNErrorManager.error(err, SVNLogType.CLIENT); } }
private boolean isLocalRevisionMergeIteration( final TreeStructureNode<SVNLogEntry> tree, final String localURL, ProgressIndicator indicator) { final LinkedList<TreeStructureNode<SVNLogEntry>> queue = new LinkedList<TreeStructureNode<SVNLogEntry>>(); queue.addLast(tree); while (!queue.isEmpty()) { final TreeStructureNode<SVNLogEntry> element = queue.removeFirst(); indicator.checkCanceled(); final Map map = element.getMe().getChangedPaths(); for (Object o : map.values()) { final SVNLogEntryPath path = (SVNLogEntryPath) o; if (SVNPathUtil.isAncestor(localURL, path.getPath())) { return true; } break; // do not check all. first should match or fail } queue.addAll(element.getChildren()); } return false; }
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); } } } } } }
/** validate the value for a remote (repository) location. */ public FormValidation doCheckCredentialsId( StaplerRequest req, @AncestorInPath SCMSourceOwner context, @QueryParameter String remoteBase, @QueryParameter String value) { // TODO suspiciously similar to // SubversionSCM.ModuleLocation.DescriptorImpl.checkCredentialsId; refactor into shared // method? // Test the connection only if we may use the credentials if (context == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER) || context != null && !context.hasPermission(CredentialsProvider.USE_ITEM)) { return FormValidation.ok(); } // if check remote is reporting an issue then we don't need to String url = Util.fixEmptyAndTrim(remoteBase); if (url == null) return FormValidation.ok(); if (!URL_PATTERN.matcher(url).matches()) return FormValidation.ok(); try { String urlWithoutRevision = SvnHelper.getUrlWithoutRevision(url); SVNURL repoURL = SVNURL.parseURIDecoded(urlWithoutRevision); StandardCredentials credentials = value == null ? null : CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials( StandardCredentials.class, context, ACL.SYSTEM, URIRequirementBuilder.fromUri(repoURL.toString()).build()), CredentialsMatchers.withId(value)); if (checkRepositoryPath(context, repoURL, credentials) != SVNNodeKind.NONE) { // something exists; now check revision if any SVNRevision revision = getRevisionFromRemoteUrl(url); if (revision != null && !revision.isValid()) { return FormValidation.errorWithMarkup( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_invalidRevision()); } return FormValidation.ok(); } SVNRepository repository = null; try { repository = getRepository( context, repoURL, credentials, Collections.<String, Credentials>emptyMap(), null); long rev = repository.getLatestRevision(); // now go back the tree and find if there's anything that exists String repoPath = getRelativePath(repoURL, repository); String p = repoPath; while (p.length() > 0) { p = SVNPathUtil.removeTail(p); if (repository.checkPath(p, rev) == SVNNodeKind.DIR) { // found a matching path List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>(); repository.getDir(p, rev, false, entries); // build up the name list List<String> paths = new ArrayList<String>(); for (SVNDirEntry e : entries) if (e.getKind() == SVNNodeKind.DIR) paths.add(e.getName()); String head = SVNPathUtil.head(repoPath.substring(p.length() + 1)); String candidate = EditDistance.findNearest(head, paths); return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPathSuggest( p, head, candidate != null ? "/" + candidate : "")); } } return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPath(repoPath)); } finally { if (repository != null) repository.closeSession(); } } catch (SVNException e) { LOGGER.log(Level.INFO, "Failed to access subversion repository " + url, e); String message = hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_exceptionMsg1( Util.escape(url), Util.escape(e.getErrorMessage().getFullMessage()), "javascript:document.getElementById('svnerror').style.display='block';" + "document.getElementById('svnerrorlink').style.display='none';" + "return false;") + "<br/><pre id=\"svnerror\" style=\"display:none\">" + Functions.printThrowable(e) + "</pre>"; return FormValidation.errorWithMarkup(message); } }
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; }