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); }
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; }
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; }
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); }