Example #1
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);
      }
    }
  }
Example #2
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);
  }
Example #3
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;
  }
Example #4
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;
  }