Am 19.04.2012 16:02, schrieb Julian Foad:
Stefan Fuhrmann wrote:
The following pre-commit scripts / policies would be useful.
* Common parts [not a policy]
We first check whether the commit contains a changed
svn:merge-info property. This limits the performance
impact on non-merge commits and we need to identify
all changed svn:merge-info anyway.
Also, the merges that happened on the source branch
from a different location than the target branch are
of no interest for the policy checkers. E.g.:
r20: merge r19 from ^/sub-branch to ^/branch
txn: merge r10-20 from ^/branch to ^/trunk
Both merges will show up in the merge-info delta but
we only need to evaluate the second one.
It took me a few minutes to realize that you mean
Sorry for that! I often work out details of my ideas
while I'm writing them down. So, the presentation
isn't as refined as it could be ...
the hook is analyzing a commit to ^/trunk and is seeing mergeinfo additions
that indicate both a merge from ^/sub-branch and a merge from ^/branch. And in
this example the merge from ^/sub-branch was in fact a merge to ^/branch, which
was committed in r20, and which is now propagating to ^/trunk.
In order for the hook to figure that out, starting from just looking at the
mergeinfo change (which doesn't say what the target of each merge was), it has
to examine revisions 10-20 of ^branch and notice that one of those revisions
(r20, in fact) was the other merge that it's considering.
That's OK, it can do that; I'm just clarifying how it can figure out which merges
"happened on the source branch".
And it might get costly. But that remains to be seen.
I'll assume the admin can configure each of these policies to apply differently
on different branches. That's mostly just a matter of inventing a suitable
configuration scheme, presumably with branch name pattern matching or similar,
and that would be totally necessary in a large project.
Agreed. There could also be user-based exceptions,
i.e. experts might get full freedom as a fallback option.
* No distributive merges
For each path being merged (i.e. having a merge-info
delta), the relative paths in source and target must
correspond (i.e. start as the same and then may get
renamed etc.). This is basically the same as the
"sophisticated" part of the check for strict merges.
In other words: in any subtree merge (that is, when a subtree of the branch
root is being merged separately or differently from its parent or the branch
root), the 'source-left' subtree and the 'target' subtree must be traceable
back to a common ancestor. In the absence of any renames or replacements
inside either branch, this would mean that the two subtrees have the same
relpath within each respective branch.
What we're rejecting here is any attempt such as:
mkdir trunk/subtree1 trunk/subtree2
copy trunk branch
merge "trunk/subtree1" into "branch/subtree2"
Correct. And some users might do that accidentally
depending on the size / complexity of the source tree.
Agreed, that policy is both almost universally useful, and is required from a functional
point of view when we're doing "automatic" merges because the merge code needs
to be able to trace them toward a common ancestor.
So I think such a merge would be rejected by the current (1.7) automatic-merge
code already. (Haven't tried.)
Note: We also support a non-automatic merge, called a "2-URL" merge, where
merge tracking is not attempted, and that (as I understand it) may allow such a merge.
Basically a merge between unrelated paths.
* No criss-crossing
Prevent situations like the criss-cross examples here:
http://wiki.apache.org/subversion/SymmetricMerge
For a merge A->B, abort if there has been a merge
B->A after the last revision of A to be merged to B.
Agreed. I believe getting into a criss-cross situation would very rarely be
intentional and would in general make the next merge more difficult than it
would otherwise be.
This only valid for non-cherry-picking merges and
only if the change sets of both merges overlap.
Yes; I haven't fully grokked the detail, but I agree there's no need to stop
cherry-picks crossing over.
Except for the last one those checks will simply verify
that the user followed certain policies. They should,
therefore, rarely reject a commit.
Why do you suggest "no criss-crossing" is an exception? It seems also to be
just verifying that the user followed certain policies.
Criss-crossing is hard to prevent by pure policy.
As soon as more than one user can do merges
(e.g. one pulling in from the branch while another
updates that branch), those processes may overlap
in time. That causes a criss-crossing merge graph.
-- Stefan^2.