subversion-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefan Sperling <>
Subject Re: unexpected tree conflict on merge for same source file
Date Thu, 18 Oct 2012 13:06:50 GMT
On Thu, Oct 18, 2012 at 02:10:25PM +0200, Sven Uhlig wrote:
> Am 17.10.2012 19:12, schrieb Stefan Sperling:
> > On Wed, Oct 17, 2012 at 05:30:14PM +0200, Sven Uhlig wrote:
> >> There could be
> >> changes that are commited to prj1 that are requried in prj2 because of
> >> e.g. some shared code.
> >> 
> >> I would do this with the following command:
> >>   svn merge -r A:B "^/branches/prj1"
> >> 
> >> Reintegration is not an option because the development will continue on
> >> both branches in parallel.
> > 
> > This approach sounds very chaotic to me.
> For me it sounds like the "Keep Alive Dance". (See also the very bottom
> of this mail.)

No, that is about something else. The keep-alive-dance and
cherry-picking are not in the same class of merge patterns.
The keep-alive dance is only used in sync-style merge patterns,
which merge all changes from their parent branch. Which isn't
what you are doing when cherry-picking changes between cousins.

> Yes, it makes merging more difficult. But that is what cherry-pick and
> svn:mergeinfo are for? svn:mergeinfo has all the required information if
> it looks into the past.

Looking into the past can be a rather complicated affair, especially
with mixed-revision copies ;)

> > In your case, why are the branches which need to share common code not
> > branches off a branch which contains the shared code?
> At the time when the branches were created there was no use of shared
> code. Later some functions seem to be unexpectedly usefull in the other
> branch.

That happens and is sometimes not avoidable, but it also indicates poor
planning and/or developer coordination. It should be the exception
rather than the norm in a well-managed project. I wasn't sure whether
or not it is an exceptional circumstance in your work flow. It sounds
like it is an exceptional circumstance, which means we're not talking
about a problem you are hitting often, which is good. Is that correct?

> > If the above won't work for some reason, maybe you shouldn't be using
> > branching/merging in the first place. Instead, you could treat the
> > shared code as an external dependency which your build system will
> > pull into the build.
> I think externals are not the right solutions if only single files or
> even only some lines of source code are to be shared.

That's right.

> Just before the conflict in r71 the paths for second.txt to it's
> original source (using your revisions) look like this:
> 1. prj1/second.txt@40 is the original file
> 2. prj2/second.txt@50 comes from prj1/second.txt@49
> 3. testing/second.txt@61 comes from prj1/second.txt@60
> When merging prj2/ into testing, then SVN has two files "second.txt" at
> hand:
> 1. prj2/second.txt@50
> 2. testing/second.txt@61
> But if SVN looked back in the history of those two files it would see
> both are from prj1/second.txt (@49 and @60)
> Looking back in the history since those two revisions r49 and r60 there
> was no change. So they are not from r49 an r60 but in fact from r40.

The problem happens because we're merging second.txt's parents.
Given the way Subversion's repository works the addition of a file is
an operation on the file's parent directory. SVN is merging prj2@70 and,
say, testing@70. It isn't merging prj2/second.txt@50 and testing/second.txt@61.

If you want to merge just second.txt you need to tell 'svn merge' that
second.txt is your merge target. We call this a "subtree merge" because
it is a merge that is anchored below an actual branch root directory.
Such merges can be useful to help resolve some tree conflicts, for example.
It might even be a viable approach to solving your problem if merging
just 'second.txt' is enough to share the common code.

And don't get me wrong, I'm just describing how Subversion works to
explain why you are seeing conflicts. I'm not saying these spurious
conflicts are a good thing.

However, I'm not sure if we really want to trace back history for every
single node involved in the merge to avoid flagging such conflicts, which
is what your proposal essentially amounts to in the general case.
That would be rather expensive.

It would be better to teach Subversion about resolving this kind of
tree conflict automatically after it has been recorded. It might be
possible to figure out whether or not such an 'add vs add' conflict
is spurious, and then auto-resolve this conflict when the conflict
resolver is running. Note that in 1.8 and later, the conflict resolver
will always run after the update or merge operation is done. It won't
run during the operation as it does in 1.7 and earlier. This was done
in preparation for future tree-conflict resolution improvements.

> I think that SVN records the wrong revisions for mergeinfo or copy
> because the file was not changed since addition but SVN still remembers
> a newer revision than the latest change and thus sees a conflict/difference.

It doesn't record wrong information in the sense that the information
is inaccurate.

> In the meantime I found the following document in the roadmap for SVN
> 1.8: "merge improvements"/"Symmetric Merging"
> I think this document discusses similar problems in the sections "1.6.
> The Keep-Alive Dance" and "1.9. Symmetric Merge with Criss-Cross Merge".
> Seeing the discussion over there, I hope to see some improvements in the
> merging algorithms :) Unfortunately it seems I have to use record-only
> merges until then.

Yes, there are some nice improvements coming in 1.8. But I don't
think the spurious add vs. add conflict we're talking about will be
automatically resolved in 1.8. Maybe in 1.9 or later.
We're currently still working on more basic problems in this area.

Reporting issues like this helps us to see what kinds of tree conflicts
people are hitting in practice. This is very valuable and helps the project.
And more help is always welcome, if you're interested :)

View raw message