コード例 #1
0
  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);
      }
    }
  }
コード例 #2
0
  public void deleteNode(String path) throws SVNException {
    FSTransactionRoot txnRoot = getTxnRoot();
    FSParentPath parentPath = txnRoot.openPath(path, true, true);
    SVNNodeKind kind = parentPath.getRevNode().getType();
    if (parentPath.getParent() == null) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.FS_ROOT_DIR, "The root directory cannot be deleted");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    if ((txnRoot.getTxnFlags() & FSTransactionRoot.SVN_FS_TXN_CHECK_LOCKS) != 0) {
      allowLockedOperation(myFSFS, path, myAuthor, myLockTokens, true, false);
    }

    makePathMutable(parentPath.getParent(), path);
    txnRoot.deleteEntry(parentPath.getParent().getRevNode(), parentPath.getEntryName());
    txnRoot.removeRevNodeFromCache(parentPath.getAbsPath());
    if (myFSFS.supportsMergeInfo()) {
      long mergeInfoCount = parentPath.getRevNode().getMergeInfoCount();
      if (mergeInfoCount > 0) {
        incrementMergeInfoUpTree(parentPath.getParent(), -mergeInfoCount);
      }
    }
    addChange(
        path,
        parentPath.getRevNode().getId(),
        FSPathChangeKind.FS_PATH_CHANGE_DELETE,
        false,
        false,
        SVNRepository.INVALID_REVISION,
        null,
        kind);
  }
コード例 #3
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);
 }
コード例 #4
0
 public String reserveCopyId(String txnId) throws SVNException {
   FSTransactionRoot txnRoot = getTxnRoot();
   String[] nextIds = txnRoot.readNextIDs();
   String copyId = FSRepositoryUtil.generateNextKey(nextIds[1]);
   myFSFS.writeNextIDs(txnId, nextIds[0], copyId);
   return "_" + nextIds[1];
 }
コード例 #5
0
 public static void abortTransaction(FSFS fsfs, String txnId) throws SVNException {
   File txnDir = fsfs.getTransactionDir(txnId);
   SVNFileUtil.deleteAll(txnDir, true);
   if (txnDir.exists()) {
     SVNErrorMessage err =
         SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "Transaction cleanup failed");
     SVNErrorManager.error(err, SVNLogType.FSFS);
   }
 }
コード例 #6
0
 private FSID createNode(FSRevisionNode revNode, String copyId, String txnId) throws SVNException {
   FSTransactionRoot txnRoot = getTxnRoot();
   String nodeId = txnRoot.getNewTxnNodeId();
   FSID id = FSID.createTxnId(nodeId, copyId, txnId);
   revNode.setId(id);
   revNode.setIsFreshTxnRoot(false);
   myFSFS.putTxnRevisionNode(id, revNode);
   return id;
 }
コード例 #7
0
  private void commit(
      String startNodeId,
      String startCopyId,
      long newRevision,
      OutputStream protoFileOS,
      FSID newRootId,
      FSTransactionRoot txnRoot,
      File revisionPrototypeFile,
      long offset)
      throws SVNException {
    try {
      protoFileOS = SVNFileUtil.openFileForWriting(revisionPrototypeFile, true);
      FSID rootId = FSID.createTxnId("0", "0", myTxn.getTxnId());

      CountingOutputStream revWriter = new CountingOutputStream(protoFileOS, offset);
      newRootId =
          txnRoot.writeFinalRevision(
              newRootId, revWriter, newRevision, rootId, startNodeId, startCopyId);
      long changedPathOffset = txnRoot.writeFinalChangedPathInfo(revWriter);

      String offsetsLine = "\n" + newRootId.getOffset() + " " + changedPathOffset + "\n";
      protoFileOS.write(offsetsLine.getBytes("UTF-8"));
    } catch (IOException ioe) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    } finally {
      SVNFileUtil.closeFile(protoFileOS);
    }

    SVNProperties txnProps = myFSFS.getTransactionProperties(myTxn.getTxnId());
    if (txnProps != null && !txnProps.isEmpty()) {
      if (txnProps.getStringValue(SVNProperty.TXN_CHECK_OUT_OF_DATENESS) != null) {
        myFSFS.setTransactionProperty(
            myTxn.getTxnId(), SVNProperty.TXN_CHECK_OUT_OF_DATENESS, null);
      }
      if (txnProps.getStringValue(SVNProperty.TXN_CHECK_LOCKS) != null) {
        myFSFS.setTransactionProperty(myTxn.getTxnId(), SVNProperty.TXN_CHECK_LOCKS, null);
      }
    }
  }
コード例 #8
0
ファイル: FSInputStream.java プロジェクト: madcap99/OVC
  private FSRepresentationState buildRepresentationList(
      FSRepresentation firstRep, LinkedList result, FSFS owner) throws SVNException {
    FSFile file = null;
    FSRepresentation rep = new FSRepresentation(firstRep);
    ByteBuffer buffer = ByteBuffer.allocate(4);
    try {
      while (true) {
        file = owner.openAndSeekRepresentation(rep);
        FSRepresentationState repState = readRepresentationLine(file);
        repState.myFile = file;
        repState.myStart = file.position();
        repState.myOffset = repState.myStart;
        repState.myEnd = repState.myStart + rep.getSize();
        if (!repState.myIsDelta) {
          return repState;
        }
        buffer.clear();
        int r = file.read(buffer);

        byte[] header = buffer.array();
        if (!(header[0] == 'S' && header[1] == 'V' && header[2] == 'N' && r == 4)) {
          SVNErrorMessage err =
              SVNErrorMessage.create(
                  SVNErrorCode.FS_CORRUPT, "Malformed svndiff data in representation");
          SVNErrorManager.error(err, SVNLogType.FSFS);
        }
        repState.myVersion = header[3];
        repState.myChunkIndex = 0;
        repState.myOffset += 4;
        /*
         * Push this rep onto the list. If it's self-compressed, we're
         * done.
         */
        result.addLast(repState);
        if (repState.myIsDeltaVsEmpty) {
          return null;
        }
        rep.setRevision(repState.myBaseRevision);
        rep.setOffset(repState.myBaseOffset);
        rep.setSize(repState.myBaseLength);
        rep.setTxnId(null);
      }
    } catch (IOException ioe) {
      file.close();
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    } catch (SVNException svne) {
      file.close();
      throw svne;
    }
    return null;
  }
コード例 #9
0
  public void changeNodeProperty(String path, String name, SVNPropertyValue propValue)
      throws SVNException {
    FSRepositoryUtil.validateProperty(name, propValue);
    FSTransactionRoot txnRoot = getTxnRoot();
    FSParentPath parentPath = txnRoot.openPath(path, true, true);
    SVNNodeKind kind = parentPath.getRevNode().getType();

    if ((txnRoot.getTxnFlags() & FSTransactionRoot.SVN_FS_TXN_CHECK_LOCKS) != 0) {
      FSCommitter.allowLockedOperation(myFSFS, path, myAuthor, myLockTokens, false, false);
    }

    makePathMutable(parentPath, path);
    SVNProperties properties = parentPath.getRevNode().getProperties(myFSFS);

    if (properties.isEmpty() && propValue == null) {
      return;
    }

    if (myFSFS.supportsMergeInfo() && name.equals(SVNProperty.MERGE_INFO)) {
      long increment = 0;
      boolean hadMergeInfo = parentPath.getRevNode().hasMergeInfo();
      if (propValue != null && !hadMergeInfo) {
        increment = 1;
      } else if (propValue == null && hadMergeInfo) {
        increment = -1;
      }
      if (increment != 0) {
        parentPath.getRevNode().setHasMergeInfo(propValue != null);
        incrementMergeInfoUpTree(parentPath, increment);
      }
    }

    if (propValue == null) {
      properties.remove(name);
    } else {
      properties.put(name, propValue);
    }

    txnRoot.setProplist(parentPath.getRevNode(), properties);
    addChange(
        path,
        parentPath.getRevNode().getId(),
        FSPathChangeKind.FS_PATH_CHANGE_MODIFY,
        false,
        true,
        SVNRepository.INVALID_REVISION,
        null,
        kind);
  }
コード例 #10
0
  public static void replay(
      FSFS fsfs,
      FSRoot root,
      String basePath,
      long lowRevision,
      boolean sendDeltas,
      ISVNEditor editor)
      throws SVNException {
    Map fsChanges = root.getChangedPaths();
    basePath = basePath.startsWith("/") ? basePath.substring(1) : basePath;
    Collection interestingPaths = new LinkedList();
    Map changedPaths = new HashMap();
    for (Iterator paths = fsChanges.keySet().iterator(); paths.hasNext(); ) {
      String path = (String) paths.next();
      FSPathChange change = (FSPathChange) fsChanges.get(path);

      path = path.startsWith("/") ? path.substring(1) : path;
      if ("".equals(basePath)
          || (path.startsWith(basePath)
              && (path.charAt(basePath.length()) == '/' || path.length() == basePath.length()))) {
        path = path.startsWith("/") ? path.substring(1) : path;
        interestingPaths.add(path);
        changedPaths.put(path, change);
      }
    }
    if (FSRepository.isInvalidRevision(lowRevision)) {
      lowRevision = 0;
    }

    FSRoot compareRoot = null;
    if (sendDeltas && root instanceof FSRevisionRoot) {
      FSRevisionRoot revRoot = (FSRevisionRoot) root;
      compareRoot = fsfs.createRevisionRoot(revRoot.getRevision() - 1);
    }

    if (root instanceof FSRevisionRoot) {
      FSRevisionRoot revRoot = (FSRevisionRoot) root;
      editor.targetRevision(revRoot.getRevision());
    }

    ISVNCommitPathHandler handler =
        new FSReplayPathHandler(fsfs, root, compareRoot, changedPaths, basePath, lowRevision);
    SVNCommitUtil.driveCommitEditor(handler, interestingPaths, editor, -1);
  }
コード例 #11
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;
  }
コード例 #12
0
ファイル: FSOutputStream.java プロジェクト: nero520/svnkit
  public void close() throws IOException {
    if (myIsClosed) {
      return;
    }
    myIsClosed = true;
    final long truncateToSize[] = new long[] {-1};
    try {
      ByteArrayInputStream target = new ByteArrayInputStream(myTextBuffer.toByteArray());
      myDeltaGenerator.sendDelta(null, mySourceStream, mySourceOffset, target, this, false);

      final FSRepresentation rep = new FSRepresentation();
      rep.setOffset(myRepOffset);

      long offset = myTargetFileOS.getPosition();

      rep.setSize(offset - myDeltaStart);
      rep.setExpandedSize(myRepSize);
      rep.setTxnId(myRevNode.getId().getTxnID());
      String uniqueSuffix = myTxnRoot.getNewTxnNodeId();
      String uniquifier = rep.getTxnId() + '/' + uniqueSuffix;
      rep.setUniquifier(uniquifier);
      rep.setRevision(SVNRepository.INVALID_REVISION);

      rep.setMD5HexDigest(SVNFileUtil.toHexDigest(myMD5Digest));
      rep.setSHA1HexDigest(SVNFileUtil.toHexDigest(mySHA1Digest));

      FSFS fsfs = myTxnRoot.getOwner();
      final IFSRepresentationCacheManager reposCacheManager = fsfs.getRepositoryCacheManager();
      if (reposCacheManager != null) {
        try {
          reposCacheManager.runReadTransaction(
              new IFSSqlJetTransaction() {
                public void run() throws SVNException {
                  final FSRepresentation oldRep =
                      reposCacheManager.getRepresentationByHash(rep.getSHA1HexDigest());
                  if (oldRep != null) {
                    oldRep.setUniquifier(rep.getUniquifier());
                    oldRep.setMD5HexDigest(rep.getMD5HexDigest());
                    truncateToSize[0] = myRepOffset;
                    myRevNode.setTextRepresentation(oldRep);
                  }
                }
              });
        } catch (SVNException e) {
          // explicitly ignore.
          SVNDebugLog.getDefaultLog().logError(SVNLogType.FSFS, e);
        }
      }
      if (truncateToSize[0] < 0) {
        myTargetFileOS.write("ENDREP\n".getBytes("UTF-8"));
        myRevNode.setTextRepresentation(rep);
      }
      myRevNode.setIsFreshTxnRoot(false);
      fsfs.putTxnRevisionNode(myRevNode.getId(), myRevNode);
    } catch (SVNException svne) {
      throw new IOException(svne.getMessage());
    } finally {
      closeStreams(truncateToSize[0]);
      try {
        myTxnLock.unlock();
      } catch (SVNException e) {
        //
      }
      FSWriteLock.release(myTxnLock);
    }
  }
コード例 #13
0
 private FSTransactionRoot getTxnRoot() throws SVNException {
   if (myTxnRoot == null && myTxn != null) {
     myTxnRoot = myFSFS.createTransactionRoot(myTxn);
   }
   return myTxnRoot;
 }
コード例 #14
0
  public void makeCopy(
      FSRevisionRoot fromRoot, String fromPath, String toPath, boolean preserveHistory)
      throws SVNException {
    FSTransactionRoot txnRoot = getTxnRoot();
    String txnId = txnRoot.getTxnID();
    FSRevisionNode fromNode = fromRoot.getRevisionNode(fromPath);

    FSParentPath toParentPath = txnRoot.openPath(toPath, false, true);
    if ((txnRoot.getTxnFlags() & FSTransactionRoot.SVN_FS_TXN_CHECK_LOCKS) != 0) {
      FSCommitter.allowLockedOperation(myFSFS, toPath, myAuthor, myLockTokens, true, false);
    }

    if (toParentPath.getRevNode() != null
        && toParentPath.getRevNode().getId().equals(fromNode.getId())) {
      return;
    }

    FSPathChangeKind changeKind;
    long mergeInfoStart = 0;
    if (toParentPath.getRevNode() != null) {
      changeKind = FSPathChangeKind.FS_PATH_CHANGE_REPLACE;
      if (myFSFS.supportsMergeInfo()) {
        mergeInfoStart = toParentPath.getRevNode().getMergeInfoCount();
      }
    } else {
      changeKind = FSPathChangeKind.FS_PATH_CHANGE_ADD;
    }

    makePathMutable(toParentPath.getParent(), toPath);
    String fromCanonPath = SVNPathUtil.canonicalizeAbsolutePath(fromPath);
    copy(
        toParentPath.getParent().getRevNode(),
        toParentPath.getEntryName(),
        fromNode,
        preserveHistory,
        fromRoot.getRevision(),
        fromCanonPath,
        txnId);

    if (changeKind == FSPathChangeKind.FS_PATH_CHANGE_REPLACE) {
      txnRoot.removeRevNodeFromCache(toParentPath.getAbsPath());
    }

    long mergeInfoEnd = 0;
    if (myFSFS.supportsMergeInfo()) {
      mergeInfoEnd = fromNode.getMergeInfoCount();
      if (mergeInfoStart != mergeInfoEnd) {
        incrementMergeInfoUpTree(toParentPath.getParent(), mergeInfoEnd - mergeInfoStart);
      }
    }

    FSRevisionNode newNode = txnRoot.getRevisionNode(toPath);
    addChange(
        toPath,
        newNode.getId(),
        changeKind,
        false,
        false,
        fromRoot.getRevision(),
        fromCanonPath,
        fromNode.getType());
  }
コード例 #15
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;
  }
コード例 #16
0
  public long commitTxn(
      boolean runPreCommitHook,
      boolean runPostCommitHook,
      SVNErrorMessage[] postCommitHookError,
      StringBuffer conflictPath)
      throws SVNException {
    if (myFSFS.isHooksEnabled() && runPreCommitHook) {
      FSHooks.runPreCommitHook(myFSFS.getRepositoryRoot(), myTxn.getTxnId());
    }

    long newRevision = SVNRepository.INVALID_REVISION;

    while (true) {
      long youngishRev = myFSFS.getYoungestRevision();
      FSRevisionRoot youngishRoot = myFSFS.createRevisionRoot(youngishRev);

      FSRevisionNode youngishRootNode = youngishRoot.getRevisionNode("/");

      mergeChanges(myFSFS, getTxnRoot(), youngishRootNode, conflictPath);
      myTxn.setBaseRevision(youngishRev);

      FSWriteLock writeLock = FSWriteLock.getWriteLockForDB(myFSFS);
      synchronized (writeLock) {
        try {
          writeLock.lock();
          newRevision = commit();
        } catch (SVNException svne) {
          if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.FS_TXN_OUT_OF_DATE) {
            long youngestRev = myFSFS.getYoungestRevision();
            if (youngishRev == youngestRev) {
              throw svne;
            }
            continue;
          }
          throw svne;
        } finally {
          writeLock.unlock();
          FSWriteLock.release(writeLock);
        }
      }
      break;
    }

    if (myFSFS.isHooksEnabled() && runPostCommitHook) {
      try {
        FSHooks.runPostCommitHook(myFSFS.getRepositoryRoot(), newRevision);
      } catch (SVNException svne) {
        SVNErrorMessage errorMessage =
            SVNErrorMessage.create(
                SVNErrorCode.REPOS_POST_COMMIT_HOOK_FAILED,
                "Commit succeeded, but post-commit hook failed",
                SVNErrorMessage.TYPE_WARNING);
        errorMessage.initCause(svne);
        SVNErrorMessage childErr = svne.getErrorMessage();
        childErr.setDontShowErrorCode(true);
        errorMessage.setChildErrorMessage(childErr);

        if (postCommitHookError != null && postCommitHookError.length > 0) {
          postCommitHookError[0] = errorMessage;
        } else {
          SVNErrorManager.error(errorMessage, SVNLogType.FSFS);
        }
      }
    }
    return newRevision;
  }
コード例 #17
0
  private long commit() throws SVNException {
    long oldRev = myFSFS.getYoungestRevision();

    if (myTxn.getBaseRevision() != oldRev) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.FS_TXN_OUT_OF_DATE, "Transaction out of date");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    verifyLocks();

    final String startNodeId;
    final String startCopyId;
    if (myFSFS.getDBFormat() < FSFS.MIN_NO_GLOBAL_IDS_FORMAT) {
      String[] ids = myFSFS.getNextRevisionIDs();
      startNodeId = ids[0];
      startCopyId = ids[1];
    } else {
      startNodeId = null;
      startCopyId = null;
    }

    final long newRevision = oldRev + 1;
    final OutputStream protoFileOS = null;
    final FSID newRootId = null;
    final FSTransactionRoot txnRoot = getTxnRoot();
    FSWriteLock txnWriteLock = FSWriteLock.getWriteLockForTxn(myTxn.getTxnId(), myFSFS);
    synchronized (txnWriteLock) {
      try {
        // start transaction.
        txnWriteLock.lock();
        final File revisionPrototypeFile = txnRoot.getTransactionProtoRevFile();
        final long offset = revisionPrototypeFile.length();
        if (myFSFS.getRepositoryCacheManager() != null) {
          myFSFS
              .getRepositoryCacheManager()
              .runWriteTransaction(
                  new IFSSqlJetTransaction() {
                    public void run() throws SVNException {
                      commit(
                          startNodeId,
                          startCopyId,
                          newRevision,
                          protoFileOS,
                          newRootId,
                          txnRoot,
                          revisionPrototypeFile,
                          offset);
                    }
                  });
        } else {
          commit(
              startNodeId,
              startCopyId,
              newRevision,
              protoFileOS,
              newRootId,
              txnRoot,
              revisionPrototypeFile,
              offset);
        }
        File dstRevFile = myFSFS.getNewRevisionFile(newRevision);
        SVNFileUtil.rename(revisionPrototypeFile, dstRevFile);
      } finally {
        txnWriteLock.unlock();
        FSWriteLock.release(txnWriteLock);
      }
    }

    String commitTime = SVNDate.formatDate(new Date(System.currentTimeMillis()));
    SVNProperties presetRevisionProperties = myFSFS.getTransactionProperties(myTxn.getTxnId());
    if (presetRevisionProperties == null
        || !presetRevisionProperties.containsName(SVNRevisionProperty.DATE)) {
      myFSFS.setTransactionProperty(
          myTxn.getTxnId(), SVNRevisionProperty.DATE, SVNPropertyValue.create(commitTime));
    }

    File txnPropsFile = myFSFS.getTransactionPropertiesFile(myTxn.getTxnId());

    if (myFSFS.getDBFormat() < FSFS.MIN_PACKED_REVPROP_FORMAT
        || newRevision >= myFSFS.getMinUnpackedRevProp()) {
      File dstRevPropsFile = myFSFS.getNewRevisionPropertiesFile(newRevision);
      SVNFileUtil.rename(txnPropsFile, dstRevPropsFile);
    } else {
      /* Read the revprops, and commit them to the permenant sqlite db. */
      FSFile fsfProps = new FSFile(txnPropsFile);
      try {
        final SVNProperties revProperties = fsfProps.readProperties(false, true);
        final SVNSqlJetStatement stmt =
            myFSFS.getRevisionProperitesDb().getStatement(SVNWCDbStatements.FSFS_SET_REVPROP);
        try {
          stmt.insert(
              new Object[] {newRevision, SVNSkel.createPropList(revProperties.asMap()).getData()});
        } finally {
          stmt.reset();
        }
      } finally {
        fsfProps.close();
      }
    }

    try {
      txnRoot.writeFinalCurrentFile(newRevision, startNodeId, startCopyId);
    } catch (IOException ioe) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    }
    myFSFS.setYoungestRevisionCache(newRevision);
    myFSFS.purgeTxn(myTxn.getTxnId());
    return newRevision;
  }
コード例 #18
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);
  }