On Wed, Aug 5, 2009 at 7:04 PM, Greg Troxel<gdt_at_ir.bbn.com> wrote:
> Paul Burba <ptburba_at_gmail.com> writes:
>> One thing to keep in mind if I didn't make this clear: The recording
>> of mergeinfo on the *root* of the merge target is unchanged in this
>> branch. If you merge ^/trunk -rM:N to branch_wc, branch_wc gets
>> mergeinfo of '/trunk:(M+1):N' added to it, *always* (unless of course
>> the merge is not mergeinfo aware, e.g. --ignore-ancestry). This
>> branch only effects how subtree mergeinfo is recorded.
> Yes, I did follow that.
>>> But, I think the rationalization
>>> is that it can't ever matter if changes that aren't actually changes are
>>> recorded. I'm trying to articulate the rules to see if I can convince
>>> myself this is ok, and having trouble. (I know I'm being redundant in
>>> my comments below, but I'm just barely following myself.)
>>> Normally (if people follow the most straightforward CM rules), mergeinfo
>>> is only at a module root. Each lower level object has implicit
>>> mergeinfo which is the same.
>> A point on terminology, you are talking about *inherited* mergeinfo
>> here. Implicit mergeinfo is a path's history represented as
>> mergeinfo. For example, say 'trunk' was created in r10. In r20 we
>> copied trunk_at_19 to branch. The implicit mergeinfo for branch at that
>> point would be '/trunk:10-19', a.k.a. it's 'natural history'. If
>> that's not clear see
> I understood the concepts but got the terms wrong - thanks for
> clarifying, as this is hard even if we all use the same words.
>>> This means that --reintegrate, for example has to be able to say:
>>> every revision on the source path has been merged into every node
>>> that is a child of the destination path
>> Yes, which is what it has done since r34091 'Reintegrate the
>> reintegrate-improvements branch back to trunk'.
> I was trying to be careful about
> r10: /branches/a copied to /branches/b
> r11: /branches/a/bar gets subtree mergeinfo of /branches/c:9 (somehow)
> r12: commits on /branches/a/foo
> r13: /branches/a merged to /branches/b
> so now
> /branches/b has mergeinfo of branches/a:11-12
> /branches/b/bar has mergeinfo of branches/c:9 [and no branches/a]
Actually, in the scenario you describe, /branches/b/bar should have
the following mergeinfo:
This is because the merge notices that a new subtree with mergeinfo
(i.e. branches/b/bar) is introduced by the merge and records mergeinfo
on it describing the merge (trunk and the subtree-mergeinfo branch
both do this in this case, the latter does because branches/b/bar
*was* touched by the merge). Then you would be able to reintegrate
merge branches/b back to branches/a.
If you are seeing something different let me know.
> In this condition, every child of branches/b does not have effective
> mergeinfo that indicates that all revisions that affect branches/a have
> been merged.
> It does meet the weaker condition that every child of branches/b (and
> branches/b) has effective mergeinfo that indicates all non-null
> revisions of the corresponding child of branches/a have been merged.
> I am unclear what the current reintegration code checks.
>> It depends what you mean by "do that again". A current trunk/1.6
>> client would "do it again" by driving the merge editor for those
>> missing revisions, even though the drives would be inoperative. If
>> you had sufficiently large numbers of subtrees with explicit mergeinfo
>> it might have to make these inoperative drives hundreds or even
>> thousands of times. It will eventually do the right thing, it will
>> just take a very long time to do it. The subtree-mergeinfo branch
>> "does it again" by making a single call to svn_ra_get_log2() after
>> which it can quickly figure out what parts of the requested merge are
>> inoperative on the subtrees' remaining ranges. In many cases this log
>> call won't be needed and won't happen (e.g. a release branch where the
>> root and every subtree typically need the same set of revisions).
> ok, that makes sense.
>>> Reintegration: The subtree is not up to date because it is missing some
>>> revisions. Now if you go check those revisions and verify that they
>>> don't affect the subtree, you can say that it is up to date by a new
>>> rule. Perhaps this new rule is easy, because one already has to allow
>>> revisions that exist but aren't on the source path not to be in the
>>> target mergeinfo.
>> I've just spent some time looking at the reintegrate code and am now
>> confident that no new changes are needed, reintegrate already does the
>> right thing. As mentioned above, the reintegrate-improvements branch
>> merged back to trunk in r34091 takes care of the case where the
>> reintegrate source has subtrees with explicit mergeinfo. And since
>> the dawn of reintegrate (i.e. r28979), the feature has handled
>> inoperative gaps in the reintegrate's source that make it *seem* like
>> the source is not fully synced with the target, see
>> Combined, these are sufficient to make reintegrate handle the changes
>> the subtree-mergeinfo branch introduces.
> OK, then this all seems fine.
> In my project we have about 20 people working in a tree with a long-term
> branch for isolation of two subgroups, lots of ticket branches, and a
> few stable branches. Once we have avoided the following:
> stray subtree merginfo from early 1.5
> people merging at other than module roots
> people commit changes to files during merges but not the mergeinfo
> proper record-only reverse merge of the reintegration changeset when
> reintegrating a branch and not deleting it
> we have mostly been ok. Our remaining problem, not necessarily related
> to your change, but perhaps is given by the following example.
> The basic workflow is to create a branch where we manually choose
> changesets to merge from parent to branch and back, often for a demo,
> release, etc. Then when it's over, we merge all unmerged changesets
> From parent to branch, and reintegrate. This is sort of a delayed
> feature branch.
> create 'stable' branch (by stable, we mean that we don't routinely do
> a merge (of all unmerged changesets) from the branch's parent to the
> cherrypick some revisions from parent to branch (via svn merge -c N
> parentpath). This works fine, and when we later get all unmerged
> revisions there is no issue.
> cherrypick some revisions from the branch to the parent (because the
> parent people want that fix right away)
> Then, we we merge from parent to branch, we get self-conflicts.
Yes, that is expected. Cyclical (a.k.a. reflected) merges have long
been known to cause problems, see
> I think what is needed is to do a record-only forward merge of the
> reverse cherrypick merge.
If what you mean is something like this:
svn merge STABLE_BRANCH_URL parent_wc -c100
svn ci -m "Cherry pick r100 back to the parent, we need it right away!"
Committed revision 237.
svn merge PARENT_URL stable_branch_wc -c237 --record-only
svn ci -m "Record only merge of r237 from trunk, we don't want to
merge this from "
Then yes, you should avoid the conflict when later merging all
available revisions from parent to branch.
Another note on terminology, when we use "reverse" and "merge"
together we typically mean a merge where the starting rev is younger
the ending rev, e.g. svn merge -r50:35. What you are calling a
"reverse cherrypick merge" is probably better termed a 'reflective' or
> It would be really cool if this were
> automatic, or somehow recorded so that this happened automatically.
Problem is that when you do the cherry pick merge back to the parent
you might not have the WC for the branch to update the mergeinfo.
> But, I don't think my problem is changed by avoiding recording
> inoperative subtree mergeinfo changes.
No, I don't see that the subtree-mergeinfo branch will have any impact
on the existing limitations of cyclic merges.
Received on 2009-08-06 18:51:05 CEST