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;
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
    @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();
      }
    }
Beispiel #5
0
 @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;
 }
Beispiel #6
0
 @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);
   }
 }
Beispiel #10
0
  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);
   }
 }
Beispiel #12
0
  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;
 }
Beispiel #14
0
 // 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;
 }
Beispiel #15
0
 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);
 }
Beispiel #18
0
  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();
 }
Beispiel #23
0
 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);
   }
 }
Beispiel #25
0
 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);
    }
  }
Beispiel #27
0
    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);
      }
    }
Beispiel #30
0
  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;
  }