Esempio n. 1
0
 private static void updateAncestry(
     FSFS owner, FSID sourceId, FSID targetId, String targetPath, long sourcePredecessorCount)
     throws SVNException {
   if (!targetId.isTxn()) {
     SVNErrorMessage err =
         SVNErrorMessage.create(
             SVNErrorCode.FS_NOT_MUTABLE, "Unexpected immutable node at ''{0}''", targetPath);
     SVNErrorManager.error(err, SVNLogType.FSFS);
   }
   FSRevisionNode revNode = owner.getRevisionNode(targetId);
   revNode.setPredecessorId(sourceId);
   revNode.setCount(
       sourcePredecessorCount != -1 ? sourcePredecessorCount + 1 : sourcePredecessorCount);
   revNode.setIsFreshTxnRoot(false);
   owner.putTxnRevisionNode(targetId, revNode);
 }
Esempio n. 2
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;
  }
Esempio n. 3
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;
  }
Esempio n. 4
0
  public void makePathMutable(FSParentPath parentPath, String errorPath) throws SVNException {
    FSTransactionRoot txnRoot = getTxnRoot();
    String txnId = txnRoot.getTxnID();

    if (parentPath.getRevNode().getId().isTxn()) {
      return;
    }
    FSRevisionNode clone = null;

    if (parentPath.getParent() != null) {
      makePathMutable(parentPath.getParent(), errorPath);
      FSID parentId = null;
      String copyId = null;

      switch (parentPath.getCopyStyle()) {
        case FSCopyInheritance.COPY_ID_INHERIT_PARENT:
          parentId = parentPath.getParent().getRevNode().getId();
          copyId = parentId.getCopyID();
          break;
        case FSCopyInheritance.COPY_ID_INHERIT_NEW:
          copyId = reserveCopyId(txnId);
          break;
        case FSCopyInheritance.COPY_ID_INHERIT_SELF:
          copyId = null;
          break;
        case FSCopyInheritance.COPY_ID_INHERIT_UNKNOWN:
        default:
          SVNErrorMessage err =
              SVNErrorMessage.create(
                  SVNErrorCode.UNKNOWN,
                  "FATAL error: can not make path ''{0}'' mutable",
                  errorPath);
          SVNErrorManager.error(err, SVNLogType.FSFS);
      }

      String copyRootPath = parentPath.getRevNode().getCopyRootPath();
      long copyRootRevision = parentPath.getRevNode().getCopyRootRevision();

      FSRoot copyrootRoot = myFSFS.createRevisionRoot(copyRootRevision);
      FSRevisionNode copyRootNode = copyrootRoot.getRevisionNode(copyRootPath);
      FSID childId = parentPath.getRevNode().getId();
      FSID copyRootId = copyRootNode.getId();
      boolean isParentCopyRoot = false;
      if (!childId.getNodeID().equals(copyRootId.getNodeID())) {
        isParentCopyRoot = true;
      }

      String clonePath = parentPath.getParent().getAbsPath();
      clone =
          txnRoot.cloneChild(
              parentPath.getParent().getRevNode(),
              clonePath,
              parentPath.getEntryName(),
              copyId,
              isParentCopyRoot);

      txnRoot.putRevNodeToCache(parentPath.getAbsPath(), clone);
    } else {
      FSTransactionInfo txn = txnRoot.getTxn();

      if (txn.getRootID().equals(txn.getBaseID())) {
        SVNErrorMessage err =
            SVNErrorMessage.create(
                SVNErrorCode.UNKNOWN,
                "FATAL error: txn ''{0}'' root id ''{1}'' matches base id ''{2}''",
                new Object[] {txnId, txn.getRootID(), txn.getBaseID()});
        SVNErrorManager.error(err, SVNLogType.FSFS);
      }
      clone = myFSFS.getRevisionNode(txn.getRootID());
    }

    parentPath.setRevNode(clone);
  }