You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Shaun Pinney <sh...@bil.konicaminolta.us> on 2009/11/10 02:28:09 UTC

Unexpected tree conflict after merge

Hello,

I'm getting tree conflicts following a merge but don't see why they should
be occurring.  Is there something I'm missing?  Here are my steps:

1) Create branch1/ containing file.txt
2) Create branch2/ based on branch1/ - branch2/ now contains file.txt
3) Remove file.txt from branch1/ and commit
4) Merge from branch1/ to branch2/ and commit - file.txt is deleted from
branch2/
5) Merge from branch2/ to branch1/ - causes a tree conflict on file.txt

I would think the merge in step 4) would communicate to the server that the
deletion of branch2/file.txt was due to a merge from branch1/, so a merge in
the opposite direction (branch2/->branch1/) should not trigger a tree
conflict.  Is this possible?

FYI - I'm using TortoiseSVN to do these operations.  When I select "Edit
Tree Conflicts" in TortoiseSVN it says "The last merge operation tried to
delete/move/rename the file 'file.txt', but it was deleted, moved or renamed
locally."  

Thanks,
Shaun

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2415991

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Stefan Sperling <st...@elego.de>.
On Tue, Nov 10, 2009 at 10:56:13AM +0100, Stefan Sperling wrote:
> > FYI - I'm using TortoiseSVN to do these operations.  When I select "Edit
> > Tree Conflicts" in TortoiseSVN it says "The last merge operation tried to
> > delete/move/rename the file 'file.txt', but it was deleted, moved or renamed
> > locally."  
> 
> This message would be more correct if it said "... locally or in the
> history of the merge target (i.e. branch2)."

In step 5) the merge target is branch1 of course, not branch2. Sorry.

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416079

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Andrey Repin <an...@freemail.ru>.
Greetings, Shaun Pinney!

>> I'd like to take a step back first, and ask:
>> Why do you need to merge back and forth between two branches?

> I've often asked the same question :) So, with the partial info I've managed to
> obtain and a with good bit of guesswork thrown in...

> We'll have a trunk containing core code reused for many products.  Each
> product will have a branch based off the trunk (and hopefully few-to-zero
> branches off branches).  We'll be adding new core features to the trunk,
> and currently have a product which requires a core feature which isn't
> ready yet, so we'll need to merge from trunk to product branches as core
> features become available.  Also, I expect that after new core features
> are added, the product requirements for active projects will expand to
> include the new core features and a trunk-to-branch merge would occur
> again.

Make it the right way, implement core features as a library/framework to base
your other projects out of it. Much like Apache and Subversion based on APR.
You'll save yourself not just a day, trust me.


--
WBR,
 Andrey Repin (anrdaemon@freemail.ru) 12.11.2009, <12:32>

Sorry for my terrible english...

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416934

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Stefan Sperling <st...@elego.de>.
On Thu, Nov 12, 2009 at 12:30:31PM +0100, Stefan Sperling wrote:
>    E.g. you can merge
>    changes made in rX to foo/bar.c on monday and changes made in rX to
>    bloo/baz.c on wednesday, and Subversion will automatically track what
>    you've done.

Note that in this example, rX affected both foo/bar.c and bloo/baz.c
when rX was committed. Individual changes committed as part of rX are
then merged to other branches.

What I wrote could also be read as "merging all of rX into foo/bar.c on
monday, and merging all of rX again into bloo/baz.c on wednesday", but
that's not what I meant to say. It's still a valid interpretation however,
e.g. rX could be a one-line bug fix fixing a bug in some file on trunk,
a bug which also happened to occur in both foo/bar.c and bloo/baz.c on
another branch. Subversion would track such merges, too, with the
caveats I mentioned.

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2417006

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Stefan Sperling <st...@elego.de>.
On Wed, Nov 11, 2009 at 06:14:30PM -0800, Shaun Pinney wrote:
> > I'd like to take a step back first, and ask:
> > Why do you need to merge back and forth between two branches?
> 
> I've often asked the same question :) So, with the partial info I've managed to
> obtain and a with good bit of guesswork thrown in...
> 
> We'll have a trunk containing core code reused for many products.  Each
> product will have a branch based off the trunk (and hopefully few-to-zero
> branches off branches).  We'll be adding new core features to the trunk,
> and currently have a product which requires a core feature which isn't
> ready yet, so we'll need to merge from trunk to product branches as core
> features become available.  Also, I expect that after new core features
> are added, the product requirements for active projects will expand to
> include the new core features and a trunk-to-branch merge would occur
> again.
> 
> For the reverse case, there has been discussion about how to add useful
> product-specific features back into the core, so we can find ourselves
> wanting to merge from branch to trunk.

This is not gonna work. Well, it can be made to work, but you and your
team will have to do the heavy lifting. It will be a time sink.

The reason is that Subversion's merge isn't a magic device that can
pull entire features from one branch to another for you.
This may be what management thinks it is, but it's not.

Subversion's merge...

1) ... assumes that tree structures on both sides match -- if they don't
   you get conflicts flagged and you have to sort them out *yourself*
   (we want to add auto-resolution for trivial cases but it will still
   take us time). You wanna do refactoring for your new feature? You'd
   better talk to the other teams first, and try to break down the
   refactoring into several steps that fit into a human brain, and which
   you can merge to other branches without disrupting them. 
   Once you do a merge which says
     Tree conflicts: 245
   at the end, it's already too late. Even more than 10 is already
   really annoying to sort out.

2) ... distributes merge tracking information across the entire tree.
   This makes it very powerful because it allows you to do very
   fine-grained merges and still have them tracked. E.g. you can merge
   changes made in rX to foo/bar.c on monday and changes made in rX to
   bloo/baz.c on wednesday, and Subversion will automatically track what
   you've done. Not even merge-focused distributed version control
   tools like git support this, you can only track entire-revision-merges
   there. But this flexibility comes at a price.
   If you use it too much, you get a lot of meta data everywhere and it
   tends to travel from one branch to another as you do your merges.
   with all the mergeinfo everywhere it gets hard to understand what
   happened, both for users and for Subversion. User errors can cause
   holes in the meta data, causing more confusion down the road. People
   do merges which modify meta data on files they've never even touched
   on their own branch. If they do commit those property changes, they
   cause more subtree merginfo noise, if they don't, they cause holes in
   the meta data. Performance drops sharply. To avoid these situations
   you need to educate users (sometimes this is the hardest part), and
   regard any merge that creates subtree mergeinfo (i.e. anywhere except
   at branch roots) with great suspicion. It should be the exception rather
   than the norm, and there should be a really good reason for it.
   We're avoiding this ourselves, e.g. see the NB note here:
   http://svn.collab.net/viewvc/svn?view=revision&revision=40458

There are many who fall into these traps, and they end up hating
Subversion. The problem is that you aren't using the tool correctly
if you don't recognize its constraints and adjust your own use of the
tool to these constraints. Just because the tool allows you do to
diverge from best practices does not mean that you should do so on
a regular basis.

> I think this is likely if a product
> dev team adds a cool feature but hard-coded it in the branch.  So the core
> dev team would later merge the feature from the product branch to the trunk
> then add customizations to allow build-time scalability and possibly other
> changes.  Also, project management may want a feature available as part of
> the core so they can plan future products on specific features and to help
> avoid the need for new products to branch off of existing product branches
> solely to include a previous product feature yet having the side effect of
> ignoring bug fixes/feature enhancements made to the core in the meantime.

Don't push this complexity into the version control tool.
Put it into a build tool like Maven, or into program/library
relationships. If you can't understand what code is where and why,
your version control tool probably won't understand that either.
 
> > If you can simplify your process such that you only ever merge in one
> > direction for a given branch (either into the branch or out of the branch,
> > with the special exception of re-integration which causes a branch to die),
> > flow of change will be much easier to understand for developers and it
> > is much less likely that you'll run into merging issues in the first place.
> 
> Agreed.  I'm hopeful we'll not need two-way merges often but I'm planning
> for them based on the roles we've assigned to the branches and mgmt's desire
> to have the capability to merge in the core-to-product and product-to-core
> directions.

Why does management have that desire? Because "merge the feature from
core to product" sounds so much more 2009 than "make core a library
with a separate release cycle and design your products as a consumer of
this library"? The latter sounds like more work for the engineers on the
surface if you assume that merge works magically. But it is *less* work,
not more, in the long run.

The version control tool exists to track file content for you.
It does not exist to track "features".
 
> We've considered a no-branch approach by creating per-product directories in
> the trunk and restricting product teams to changes only their directories to
> remove the need for merging.  However, it seems impractical since the product
> teams generally work independently from the core team and have different
> schedule
> constraints.  The idea floating around is that product teams need to
> independently
> make quick mods to the core areas which are valid for their product
> requirements,
> but not useful for every product team, and probably would be considered "changed
> in the wrong place" from the core team's perspective (especially when changed
> hastily during product QA and bug fixing cycles).  So branches can allow our
> product teams to work independently of our core teams and other product teams on
> other active projects.  Would be interesting to hear other ideas.

Stop treating core as something special. It's just another component of
your systems, with its own release cycle.

Just take an extreme example that goes against your current plans:
What about putting core into a separate repository?
You can design a development process that works great even if you do this!
Just imagine what that really means for a second. You cannot merge from
core to product, just like you cannot merge to or from code you get
from third party suppliers. This can be a good thing because it reduces
complexity, since everyone knows what code is where and why.

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416990

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

RE: Unexpected tree conflict after merge

Posted by Shaun Pinney <sh...@bil.konicaminolta.us>.
> I'd like to take a step back first, and ask:
> Why do you need to merge back and forth between two branches?

I've often asked the same question :) So, with the partial info I've managed to
obtain and a with good bit of guesswork thrown in...

We'll have a trunk containing core code reused for many products.  Each
product will have a branch based off the trunk (and hopefully few-to-zero
branches off branches).  We'll be adding new core features to the trunk,
and currently have a product which requires a core feature which isn't
ready yet, so we'll need to merge from trunk to product branches as core
features become available.  Also, I expect that after new core features
are added, the product requirements for active projects will expand to
include the new core features and a trunk-to-branch merge would occur
again.

For the reverse case, there has been discussion about how to add useful
product-specific features back into the core, so we can find ourselves
wanting to merge from branch to trunk.  I think this is likely if a product
dev team adds a cool feature but hard-coded it in the branch.  So the core
dev team would later merge the feature from the product branch to the trunk
then add customizations to allow build-time scalability and possibly other
changes.  Also, project management may want a feature available as part of
the core so they can plan future products on specific features and to help
avoid the need for new products to branch off of existing product branches
solely to include a previous product feature yet having the side effect of
ignoring bug fixes/feature enhancements made to the core in the meantime.

> 
> If you can simplify your process such that you only ever merge in one
> direction for a given branch (either into the branch or out of the branch,
> with the special exception of re-integration which causes a branch to die),
> flow of change will be much easier to understand for developers and it
> is much less likely that you'll run into merging issues in the first place.

Agreed.  I'm hopeful we'll not need two-way merges often but I'm planning
for them based on the roles we've assigned to the branches and mgmt's desire
to have the capability to merge in the core-to-product and product-to-core
directions.

We've considered a no-branch approach by creating per-product directories in
the trunk and restricting product teams to changes only their directories to
remove the need for merging.  However, it seems impractical since the product
teams generally work independently from the core team and have different
schedule
constraints.  The idea floating around is that product teams need to
independently
make quick mods to the core areas which are valid for their product
requirements,
but not useful for every product team, and probably would be considered "changed
in the wrong place" from the core team's perspective (especially when changed
hastily during product QA and bug fixing cycles).  So branches can allow our
product teams to work independently of our core teams and other product teams on
other active projects.  Would be interesting to hear other ideas.

> Could you draw a diagram showing one instance of each type of line of
> history you need (e.g. release branch, main line, feature branch) and
> different kinds of arrows indicating types of merges you need to do (e.g.
> catch-up/rebase merge, cherry-pick merge, reintegrate merge)?
> Then we could work with that and think it through.
> Of course, the less lines and arrows you can get away with, the better :)

It'd be very incomplete - Translated: I'll find out what we need to do when
mgmt wants to do it :).  But I'm definitely of the opinion that the fewer merges
we need to do the better.

Cheers,
Shaun

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416858

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Stefan Sperling <st...@elego.de>.
On Wed, Nov 11, 2009 at 12:43:06PM -0800, Shaun Pinney wrote:
> > > I would think the merge in step 4) would communicate to the server that
> > > the deletion of branch2/file.txt was due to a merge from branch1/, so a
> > > merge in the opposite direction (branch2/->branch1/) should not trigger
> > > a tree conflict.  Is this possible?
> > 
> > No, unfortunately it's not possible.
> > 
> > The revisions you committed during steps 3) and 4) (let's call them
> > rX and rY) are two distinct identifiers for the same semantic change
> > which says "delete file.txt". But Subversion doesn't know that.
> > It only knows revision numbers, and paths.
> > ...
> 
> Hi Stefan,
> 
> Thanks for the info (and sorry for my delay in responding).  I'm working on
> how to instruct our team around the issue now.  If you have any advice to
> handle this issue it would be really great to reference.
> 
> My current idea is that since there is the potential for extraneous tree
> conflicts when merging back and forth between branches, it would be useful
> for team members to do an initial merge, then do a second test merge in the
> reverse direction to detect any tree conflicts which could affect future merges
> and resolve them immediately.  I think this will make the merging process
> easier since there won't be leftover issues from previous merges to worry
> about for future merges.

I'd like to take a step back first, and ask:
Why do you need to merge back and forth between two branches?

If you can simplify your process such that you only ever merge in one
direction for a given branch (either into the branch or out of the branch,
with the special exception of re-integration which causes a branch to die),
flow of change will be much easier to understand for developers and it
is much less likely that you'll run into merging issues in the first place.

I am not saying that your idea is wrong, just asking whether you've
considered if a simpler solution will do the job.

Could you draw a diagram showing one instance of each type of line of
history you need (e.g. release branch, main line, feature branch) and
different kinds of arrows indicating types of merges you need to do (e.g.
catch-up/rebase merge, cherry-pick merge, reintegrate merge)?
Then we could work with that and think it through.
Of course, the less lines and arrows you can get away with, the better :)

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416766

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

RE: Unexpected tree conflict after merge

Posted by Shaun Pinney <sh...@bil.konicaminolta.us>.
> > I would think the merge in step 4) would communicate to the server that
> > the deletion of branch2/file.txt was due to a merge from branch1/, so a
> > merge in the opposite direction (branch2/->branch1/) should not trigger
> > a tree conflict.  Is this possible?
> 
> No, unfortunately it's not possible.
> 
> The revisions you committed during steps 3) and 4) (let's call them
> rX and rY) are two distinct identifiers for the same semantic change
> which says "delete file.txt". But Subversion doesn't know that.
> It only knows revision numbers, and paths.
> ...

Hi Stefan,

Thanks for the info (and sorry for my delay in responding).  I'm working on
how to instruct our team around the issue now.  If you have any advice to
handle this issue it would be really great to reference.

My current idea is that since there is the potential for extraneous tree
conflicts when merging back and forth between branches, it would be useful
for team members to do an initial merge, then do a second test merge in the
reverse direction to detect any tree conflicts which could affect future merges
and resolve them immediately.  I think this will make the merging process
easier since there won't be leftover issues from previous merges to worry
about for future merges.

Then, if tree conflicts are found, do the second full merge (not test merge),
carefully resolve the tree conflicts, and then commit the parent directory
containing the resolved conflicts to the server.  I think only directory names
and not files can be committed in this step to help keep the svn:mergeinfo as
clean as possible for things like Revision Graphing, etc.

Best,
Shaun

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416741

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

Re: Unexpected tree conflict after merge

Posted by Stefan Sperling <st...@elego.de>.
On Mon, Nov 09, 2009 at 06:28:09PM -0800, Shaun Pinney wrote:
> Hello,
> 
> I'm getting tree conflicts following a merge but don't see why they should
> be occurring.  Is there something I'm missing?  Here are my steps:
> 
> 1) Create branch1/ containing file.txt
> 2) Create branch2/ based on branch1/ - branch2/ now contains file.txt
> 3) Remove file.txt from branch1/ and commit
> 4) Merge from branch1/ to branch2/ and commit - file.txt is deleted from
> branch2/
> 5) Merge from branch2/ to branch1/ - causes a tree conflict on file.txt
> 
> I would think the merge in step 4) would communicate to the server that the
> deletion of branch2/file.txt was due to a merge from branch1/, so a merge in
> the opposite direction (branch2/->branch1/) should not trigger a tree
> conflict.  Is this possible?

No, unfortunately it's not possible.

The revisions you committed during steps 3) and 4) (let's call them
rX and rY) are two distinct identifiers for the same semantic change
which says "delete file.txt". But Subversion doesn't know that.
It only knows revision numbers, and paths.

When you tell svn to merge from branch2 to branch1 during 5), it checks
mergeinfo to see if branch2 already has received rY from branch1.
Since it does not, it tries to merge that revision. So the client asks
the server "tell me everything about rY" and the client receives a delta
telling it to delete file.txt.

> FYI - I'm using TortoiseSVN to do these operations.  When I select "Edit
> Tree Conflicts" in TortoiseSVN it says "The last merge operation tried to
> delete/move/rename the file 'file.txt', but it was deleted, moved or renamed
> locally."  

This message would be more correct if it said "... locally or in the
history of the merge target (i.e. branch2)."

Since the client is told to delete file.txt which is missing in the merge
target, the client figures that any of the following could have happened
since the branches were created:

- file.txt was deleted in both branches (svn mistakenly flags a conflict)
- file.txt was renamed in one branch and deleted in the other
- file.txt was renamed in both branches (potentially to different names)

The client does not know which of these happened (just that one of them
happened), and it cannot reliably find out more than it already knows.
So for now, we have to treat all these situations the same because we
cannot tell them apart from one another. That's why TortoiseSVN prints
this message.
We'd have to go back in time to the year 2000 and tell the original
designers of Subversion to make the client<->server interface a little
bit smarter about renames. Since then, people have built pretty much
everything else of Subversion around this somewhat limited interface.
We're working on amending this interface (search the dev@ archives for
'editor v2'), but it is a lot of work and will still take some time.

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2416077

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].