[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Merge policies

From: Trent Nelson <trent_at_snakebite.org>
Date: Thu, 19 Apr 2012 10:59:31 -0700

On Apr 19, 2012, at 1:36 PM, Trent Nelson wrote:

> On Apr 19, 2012, at 8:38 AM, Stefan Sperling wrote:
>> On Thu, Apr 19, 2012 at 12:48:44PM +0200, Stefan Fuhrmann wrote:
>>> Hi all,
>>> After having a closer look at merge and discussing it
>>> with Julian on IRC, there seems to be no silver bullet.
>>> However, we identified a few things that could be changed
>>> and set of constellations that make merge harder than
>>> it needs to be.
>>> For the first, there will be another post soon. The second
>>> boils down to policy. Luckily, SVN has a mechanism to
>>> enforce policies: server-side hook scripts. My proposal
>>> is to develop a small set of scripts that a user can
>>> combine to prevent situations that her life harder than
>>> necessary.
>> I like the idea of providing pre-commit hook samples that each
>> implement a piece of a merge-policy puzzle.
>> At elego we often advise customers about branching/merging strategies.
>> It is true that virtually every shop has different requirements (i.e.
>> there is no silver bullet). This simply stems from the fact that every
>> software project is different. At the same time, a lot of shops end up
>> using the same or similar strategy and sometimes reinvent the wheel.
>> Subversion by itself enforces virtually no restrictions, and adding
>> restrictions to the system is often a major part of the work involved
>> in getting a production setup up and running. Often restrictions are
>> added over time as people repeatedly make mistakes that cause problems.
>> Having an officially supported set of high-quality hook scripts in
>> our tools/ directory that are documented well and support a wide
>> range of use cases in a modular fashion would help a lot. I believe
>> many users would be happy to deploy a hook collection that is officially
>> maintained by the Apache Subversion project rather than relying on
>> self-written or third-party hook scripts.
>> I would definitely be interested in contributing, and maybe others
>> at elego would, too. I'd be very happy to install "Apache Subversion"
>> branded hooks rather then "elego" branded hooks at customer sites and
>> share the development effort.
>> And maybe Trent can contribute some of his experience, if he has time?
> As the spirit of JFDI is so rife before bed, I'm proud to announce enversion 0.0.0: https://github.com/tpn/enversion!

It's probably worth noting this particular file:


That's a list of all the things Enversion currently detects/blocks/warns against. As you can see, lots of merge validation stuff.

I'll follow up tomorrow with more info in a separate thread rather than hijacking this one.


class _Notes(Constant):
    MergeinfoRemovedFromRepositoryRoot = 'svn:mergeinfo removed from repository root'
    SubtreeMergeinfoModified = 'subtree svn:mergeinfo modified'
    SubtreeMergeinfoRemoved = 'subtree svn:mergeinfo removed'
    Merge = 'merge'
    RootRemoved = 'root removed'
    ValidMultirootCommit = 'valid multi-root commit'
    MultipleUnknownAndKnowRootsVerifiedByExternals = 'multiple known and unknown roots verified by svn:externals'
    BranchRenamed = 'branch renamed'
    TrunkRelocated = 'trunk relocated'
    FileReplacedViaCopyDuringMerge = 'file replaced via copy during merge'
    FileUnchangedButParentCopyOrRenameBug = 'file is unchanged but there is a parent rename or copy action'
    DirUnchangedButParentCopyOrRenameBug = 'directory is unchanged but there is a parent rename or copy action'
    UnchangedFileDuringMerge = 'file unchanged during merge'
    UnchangedDirDuringMerge = 'dir unchanged during merge'
n = _Notes()
class _Warnings(Constant):
    KnownRootRemoved = 'known root removed'
w = _Warnings()
class _Errors(Constant):
    TagRenamed = 'tag renamed'
    TagModified = 'tag modified'
    MultipleUnknownAndKnownRootsModified = 'multiple known and unknown roots modified in the same commit'
    MixedRootNamesInMultiRootCommit = 'mixed root names in multi-root commit'
    MixedRootTypesInMultiRootCommit = 'mixed root types in multi-root commit'
    SubversionRepositoryCheckedIn = 'subversion repository checked in'
    MergeinfoAddedToRepositoryRoot = "svn:mergeinfo added to repository root '/'"
    MergeinfoModifiedOnRepositoryRoot = "svn:mergeinfo modified on repository root '/'"
    SubtreeMergeinfoAdded = 'svn:mergeinfo added to subtree'
    RootMergeinfoRemoved = 'svn:mergeinfo removed from root'
    DirectoryReplacedDuringMerge = 'directory replaced during merge'
    EmptyMergeinfoCreated = 'empty svn:mergeinfo property set on path'
    TagDirectoryCreatedManually = 'tag directory created manually'
    BranchDirectoryCreatedManually = 'branch directory created manually'
    BranchRenamedToTrunk = 'branch renamed to trunk'
    TrunkRenamedToBranch = 'trunk renamed to branch'
    TrunkRenamedToTag = 'trunk renamed to tag'
    BranchRenamedToTag = 'branch renamed to tag'
    BranchRenamedOutsideRootBaseDir = 'branch renamed to location outside root base dir'
    TagSubtreePathRemoved = 'tag subtree path removed'
    RenameAffectsMultipleRoots = 'rename affects multiple roots'
    UncleanRenameAffectsMultipleRoots = 'unclean rename affects multiple roots'
    MultipleRootsCopied = 'multiple roots copied'
    TagCopied = 'tag copied'
    UncleanCopy = 'unclean copy'
    FileRemovedFromTag = 'file removed from tag'
    CopyKnownRootSubtreeToValidAbsRootPath = 'copy known root subtree to valid absolute root path'
    MixedRootsNotClarifiedByExternals = 'multiple known and unknown roots in commit could not be clarified by svn:externals'
    CopyKnownRootToIncorrectlyNamedRootPath = 'known root copied to an incorrectly-named new root path'
    CopyKnownRootSubtreeToIncorrectlyNamedRootPath = 'known root subtree copied to incorrectly-named new root path'
    UnknownPathRenamedToIncorrectlyNamedNewRootPath = 'unknown path renamed incorrectly to new root path name'
    RenamedKnownRootToIncorrectlyNamedRootPath = 'renamed known root to incorrectly named root path'
    MixedChangeTypesInMultiRootCommit = 'mixed change types in multi-root commit'
    CopyKnownRootToKnownRootSubtree = 'copy known root to known root subtree'
    UnknownPathCopiedToIncorrectlyNamedNewRootPath = 'unknown path copied to incorrectly named new root path'
    RenamedKnownRootToKnownRootSubtree = 'renamed root to known root subtree'
    FileUnchangedAndNoParentCopyOrRename = 'file has no text or property changes, and no parent copy or rename actions can be found'
    DirUnchangedAndNoParentCopyOrRename = 'directory has not changed, and no parent copy or rename actions can be found'
    EmptyChangeSet = 'empty change set'
    RenameRelocatedPathOutsideKnownRoot = 'rename relocated path outside known root'
    TagRemoved = 'tag removed'
    CopyKnownRootToUnknownPath = 'known root copied to unknown path'
    CopyKnownRootSubtreeToInvalidRootPath = 'known root copied to invalid root path'
    NewRootCreatedByRenamingUnknownPath = 'new root created by renaming unknown path'
    UnknownPathCopiedToKnownRootSubtree = 'unknown path copied to known root subtree'
    NewRootCreatedByCopyingUnknownPath = 'new root created by copying unknown path'
    RenamedKnownRootToUnknownPath = 'known root renamed to unknown path'
    RenamedKnownRootSubtreeToUnknownPath = 'known root subtree renamed to unknown path'
    RenamedKnownRootSubtreeToValidRootPath = 'known root subtree renamed to valid root path'
    RenamedKnownRootSubtreeToIncorrectlyNamedRootPath = 'known root subtree renamed to incorrectly-named root path'
    UncleanRename = 'unclean rename'
    PathCopiedFromOutsideRootDuringNonMerge = 'path copied from outside root during non-merge'
    UnknownDirReplacedViaCopyDuringNonMerge = 'unknown directory replaced via copy during non-merge'
    DirReplacedViaCopyDuringNonMerge = 'directory replaced via copy during non-merge'
    DirectoryReplacedDuringNonMerge = 'directory replaced during non-merge'
    PreviousPathNotMatchedToPathsInMergeinfo = 'previous path not matched to paths in mergeinfo'
    PreviousRevDiffersFromParentCopiedFromRev = 'previous rev differs from parent copied-from rev'
    PreviousPathDiffersFromParentCopiedFromPath = 'previous path differs from parent copied-from path'
    PreviousRevDiffersFromParentRenamedFromRev = 'previous rev differs from parent renamed-from rev'
    PreviousPathDiffersFromParentRenamedFromPath = 'previous path differs from parent renamed-from path'
    KnownRootPathReplacedViaCopy = 'known root path replaced via copy'
    BranchesDirShouldBeCreatedManuallyNotCopied = "'branches' directory should be created manually not copied"
    TagsDirShouldBeCreatedManuallyNotCopied = "'tags' directory should be created manually not copied"
    CopiedFromPathNotMatchedToPathsInMergeinfo = 'copied-from path not matched to paths in mergeinfo'
    InvariantViolatedModifyContainsMismatchedPreviousPath = 'invariant violated: modify contains mismatched previous path'
    InvariantViolatedModifyContainsMismatchedPreviousRev = 'invariant violated: modify contains mismatched previous path'
    InvariantViolatedCopyNewPathInRootsButNotReplace = "invariant violated: the new path name created (via copy) is already a known root, but the change isn't marked as a replace."
    MultipleRootsAffectedByRemove = 'multiple roots affected by remove'
    InvariantViolatedDieCalledWithoutErrorInfo = "invariant violated: Repository.die() method called without any error information being set"
    VersionMismatch = "version mismatch: we are at version %d, but the 'evn:version' revision property found on revision 0 reports the repository is at version %d"
    MissingOrEmptyRevPropOnRev0 = "missing or empty 'evn:%s' revision property on revision 0"
    InvalidIntegerRevPropOnRev0 = "invalid value for 'evn:%s' revision property on revision 0; expected an integer greater than or equal to %d, got: %s"
    PropertyValueConversionFailed = "failed to convert property %s's value: %s"
    PropertyValueLiteralEvalFailed = "invalid value for property '%s': %s"
    LastRevTooHigh = "the value for the revision property 'evn:last_rev' on revision 0 of the repository is too high; it indicates the last processed revision was %d, however, the highest revision in the repository is only %d"
    RepositoryOutOfSyncTxn = "the repository is out of sync and can not be committed to at this time (base revision for this transaction: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    LastRevNotSetToBaseRevDuringPostCommit = "the repository is out of sync (last_rev is not set to base_rev during post-commit), preventing post-commit processing of this revision; is the pre-commit hook enabled? (this revision: %d, base revision: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    OutOfOrderRevisionProcessingAttempt = "unable to process repository revision %d until the base revision %d has been processed; however, the last processed revision reported by the repository is %d (current repository revision: %d)"
    RootsMissingFromBaseRevTxn = "missing or empty 'evn:roots' revision property on base revision (this transaction: %s, base revision: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    RootsMissingFromBaseRevDuringPostCommit = "missing or empty 'evn:roots' revision property on base revision, preventing post-commit processing of this revision; is the pre-commit hook enabled? (this revision: %d, base revision: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    ChangeSetOnlyApplicableForRev1AndHigher = "changeset only applicable to revisions 1 and higher"
    InvalidRootsForRev = "invalid value for 'evn:roots' revision property on revision (this revision: %d, base revision: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    StaleTxnProbablyDueToHighLoad = "please re-try your commit -- the repository is under load and your transaction became out-of-date while it was being queued for processing (base revision for this transaction: %d, repository last synchronised at revision: %d, current repository revision: %d)"
    AbsoluteRootOfRepositoryCopied = "absolute root of repository copied"
    PropertyChangedButOldAndNewValuesAreSame = "the property '%s' is recorded as having changed, but the old value and new value are identical ('%s')"
Received on 2012-04-19 20:00:08 CEST

This is an archived mail posted to the Subversion Dev mailing list.