You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Martin Bischoff <ti...@gmail.com> on 2012/10/09 17:23:30 UTC
How to merge a rename of a folder
I have a project which is being developed on /trunk, and at the same time I
have a branch (/branches/1.x) for maintenance of version 1.x.
Now I'd like to rename a folder of the project, e.g. /trunk/a to /trunk/b.
The same folder should also be renamed on the maintenance branch, so that
future bugfixes (made inside /trunk/b) can be merged to the branch.
If I merge the revision (in which /trunk/a was renamed to /trunk/b) to the
branch, then it seems that files inside /branches/1.x/b will then be
identical copies of the files inside /trunk/b at the HEAD revision. This
means, that for example, any changes made directly on /branches/a/text.txt
are then lost.
Obviously I'm doing something wrong!
What is the correct procedure to merge a rename of a folder to a branch?
Should I rename the folder independently on both trunk and the branch? Will
I then still be able to merge changes from /trunk/b to /branches/1.x/b?
BTW: I'm using the current version of TortoiseSVN, so I can't give the
exact svn commands that were used.
Thanks a lot for any help.
-Martin
Re: How to merge a rename of a folder
Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, Oct 10, 2012 at 22:14:49 +0200:
> On Tue, Oct 09, 2012 at 09:10:41PM +0200, Martin Bischoff wrote:
> > Instead of merging revision N and resolving the conflicts, would a
> > record-only merge of revision N give the same result?
>
> Yes, except that record-only merges will update all subtree
> mergeinfo within the merge target, if any exists.
... which matters if rN contained changes other than renaming
a directory.
Re: How to merge a rename of a folder
Posted by Stefan Sperling <st...@elego.de>.
On Tue, Oct 09, 2012 at 09:10:41PM +0200, Martin Bischoff wrote:
> Thanks a lot for the detailed information. Please see below for some
> additional questions.
Sure.
> > The incoming delete of A conflicts with the local delete of A.
> > This happened because both sides (trunk, and branch) decided to
> > rename A to B, and Subversion cannot yet tell the difference
> > between a normal deletion and a deletion that happens as part
> > of a move (which sucks, and we're trying to fix this, but that's
> > a separate discussion). In this particular case, deleting A is the
> >
>
> Will the (hopefully soon-to-be-released) version 1.8 already contain some
> improvements in that area?
Not for incoming moves, no. Maybe for moves which exist as local changes
in the working copy. But that helps mostly during updates, not so much
during merges.
> Instead of merging revision N and resolving the conflicts, would a
> record-only merge of revision N give the same result?
Yes, except that record-only merges will update all subtree
mergeinfo within the merge target, if any exists.
> Is the same procedure required when renaming files instead of folders, or
> does this issue only happen when renaming folders?
It happens with files, too, and the workaround should be pretty
much the same.
Re: How to merge a rename of a folder
Posted by Martin Bischoff <ti...@gmail.com>.
Thanks a lot for the detailed information. Please see below for some
additional questions.
On Tue, Oct 9, 2012 at 7:05 PM, Stefan Sperling <st...@elego.de> wrote:
> On Tue, Oct 09, 2012 at 05:23:30PM +0200, Martin Bischoff wrote:
> > I have a project which is being developed on /trunk, and at the same
> time I
> > have a branch (/branches/1.x) for maintenance of version 1.x.
> >
> > Now I'd like to rename a folder of the project, e.g. /trunk/a to
> /trunk/b.
> > The same folder should also be renamed on the maintenance branch, so that
> > future bugfixes (made inside /trunk/b) can be merged to the branch.
> >
> > If I merge the revision (in which /trunk/a was renamed to /trunk/b) to
> the
> > branch, then it seems that files inside /branches/1.x/b will then be
> > identical copies of the files inside /trunk/b at the HEAD revision. This
> > means, that for example, any changes made directly on
> /branches/a/text.txt
> > are then lost.
> >
> > Obviously I'm doing something wrong!
> >
> > What is the correct procedure to merge a rename of a folder to a branch?
> >
> > Should I rename the folder independently on both trunk and the branch?
> Will
> > I then still be able to merge changes from /trunk/b to /branches/1.x/b?
>
> Yes. See below for details.
>
> > BTW: I'm using the current version of TortoiseSVN, so I can't give the
> > exact svn commands that were used.
> >
> > Thanks a lot for any help.
> >
> > -Martin
>
> The following instructions work for me with the command line client.
> I'm making some assumptions though, not sure if these apply to your
> particular case:
>
> - The folder A is renamed to B on trunk in a revision I'll call N.
> Ideally, there are no unrelated changes in this revision, just
> the rename (not a strict requirement but it makes resolving
> the tree conflict much simpler).
>
That's what I did during my tests. Revision N only renamed the folder.
>
>
- The branch has merged all desired changes from trunk up to revison N-1.
> It's Ok if you haven't merged *all* revisions up to N-1 from trunk to
> the branch. But any changes up to N-1 you desire should have been merged
> to avoid conflicts if revisions older than N-1 are merged in the future.
> So if there are any such revisions which haven't been merged yet, merge
> them now.
>
That's also fulfilled. All desired changes were already merged to the
branch.
>
> Given these assumptions, here's one way of merging the rename
> on the branch (there are others, but there is no need to talk
> about them if the below works for you):
>
> Get a working copy of the branch at HEAD.
> In this working copy, rename folder A to B. Don't commit!
> Instead of committing, merge just rN from trunk, using TortoiseSVN's
> "Merge a range of revisions" merge option, using just N for the
> revision range parameter.
>
> Two tree conflicts will be flagged.
>
> Here's what the above looks like in the command line client, with N=4:
>
> $ svn merge -c4 ^/trunk
> --- Merging r4 into '.':
> C B
> C A
> --- Recording mergeinfo for merge of r4 into '.':
> G .
> Summary of conflicts:
> Tree conflicts: 2
> $ svn status
> M .
> D C A
> > local delete, incoming delete upon merge
> A + C B
> > local add, incoming add upon merge
> Summary of conflicts:
> Tree conflicts: 2
>
> The first line showing M is a mergeinfo change.
>
> The incoming delete of A conflicts with the local delete of A.
> This happened because both sides (trunk, and branch) decided to
> rename A to B, and Subversion cannot yet tell the difference
> between a normal deletion and a deletion that happens as part
> of a move (which sucks, and we're trying to fix this, but that's
> a separate discussion). In this particular case, deleting A is the
>
Will the (hopefully soon-to-be-released) version 1.8 already contain some
improvements in that area?
> desired conflict resolution outcome. Since the working copy is
> already set up to delete A during the next commit, we can just
> mark the tree conflict on A as resolved:
>
> $ svn resolved A
> Resolved conflicted state of 'A'
> $
>
> Now, what about B?
>
> Check the URL of B in the 'Subversion' tab of the directory's
> properties dialog in Windows. On the command line you can use
> the 'svn info' command for this purpose. In my case this is:
>
> $ svn info B | grep Copied\ From\ URL
> Copied From URL: file:///tmp/svn-sandbox/repos/branch/A
>
> So clearly it's a copy from the branch, not from trunk!
> This happened because we renamed the folder before running
> the merge, forcing a tree conflict, so that Subversion won't
> add 'B' as a copy from trunk.
>
> You might also want to verify that the content in files with B
> still matches what you expect, just to make sure (and this is where
> things get more complicated if you also have other changes in rN...)
>
> Since the directory B is precisely in the state we want it to
> be in, we can also just mark the conflict resolved:
>
> $ svn resolved B
> Resolved conflicted state of 'B'
> $
>
Instead of merging revision N and resolving the conflicts, would a
record-only merge of revision N give the same result?
>
Now commit the entire working copy. This commit will mark revision N
> as merged from trunk and rename A to B on the branch. Future merges
> from trunk will expect a path B instead of A, and work as expected.
>
> For instance, merging r6 from trunk which changed a file B/zeta just
> works:
>
> $ svn merge -c6 ^/trunk
> --- Merging r5 through r6 into '.':
> G B/zeta
> --- Recording mergeinfo for merge of r5 through r6 into '.':
> G .
> $
>
> I hope this helps. If you have further questions feel free to ask.
>
Is the same procedure required when renaming files instead of folders, or
does this issue only happen when renaming folders?
Thanks.
-Martin
Re: How to merge a rename of a folder
Posted by Stefan Sperling <st...@elego.de>.
On Tue, Oct 09, 2012 at 05:23:30PM +0200, Martin Bischoff wrote:
> I have a project which is being developed on /trunk, and at the same time I
> have a branch (/branches/1.x) for maintenance of version 1.x.
>
> Now I'd like to rename a folder of the project, e.g. /trunk/a to /trunk/b.
> The same folder should also be renamed on the maintenance branch, so that
> future bugfixes (made inside /trunk/b) can be merged to the branch.
>
> If I merge the revision (in which /trunk/a was renamed to /trunk/b) to the
> branch, then it seems that files inside /branches/1.x/b will then be
> identical copies of the files inside /trunk/b at the HEAD revision. This
> means, that for example, any changes made directly on /branches/a/text.txt
> are then lost.
>
> Obviously I'm doing something wrong!
>
> What is the correct procedure to merge a rename of a folder to a branch?
>
> Should I rename the folder independently on both trunk and the branch? Will
> I then still be able to merge changes from /trunk/b to /branches/1.x/b?
Yes. See below for details.
> BTW: I'm using the current version of TortoiseSVN, so I can't give the
> exact svn commands that were used.
>
> Thanks a lot for any help.
>
> -Martin
The following instructions work for me with the command line client.
I'm making some assumptions though, not sure if these apply to your
particular case:
- The folder A is renamed to B on trunk in a revision I'll call N.
Ideally, there are no unrelated changes in this revision, just
the rename (not a strict requirement but it makes resolving
the tree conflict much simpler).
- The branch has merged all desired changes from trunk up to revison N-1.
It's Ok if you haven't merged *all* revisions up to N-1 from trunk to
the branch. But any changes up to N-1 you desire should have been merged
to avoid conflicts if revisions older than N-1 are merged in the future.
So if there are any such revisions which haven't been merged yet, merge
them now.
Given these assumptions, here's one way of merging the rename
on the branch (there are others, but there is no need to talk
about them if the below works for you):
Get a working copy of the branch at HEAD.
In this working copy, rename folder A to B. Don't commit!
Instead of committing, merge just rN from trunk, using TortoiseSVN's
"Merge a range of revisions" merge option, using just N for the
revision range parameter.
Two tree conflicts will be flagged.
Here's what the above looks like in the command line client, with N=4:
$ svn merge -c4 ^/trunk
--- Merging r4 into '.':
C B
C A
--- Recording mergeinfo for merge of r4 into '.':
G .
Summary of conflicts:
Tree conflicts: 2
$ svn status
M .
D C A
> local delete, incoming delete upon merge
A + C B
> local add, incoming add upon merge
Summary of conflicts:
Tree conflicts: 2
The first line showing M is a mergeinfo change.
The incoming delete of A conflicts with the local delete of A.
This happened because both sides (trunk, and branch) decided to
rename A to B, and Subversion cannot yet tell the difference
between a normal deletion and a deletion that happens as part
of a move (which sucks, and we're trying to fix this, but that's
a separate discussion). In this particular case, deleting A is the
desired conflict resolution outcome. Since the working copy is
already set up to delete A during the next commit, we can just
mark the tree conflict on A as resolved:
$ svn resolved A
Resolved conflicted state of 'A'
$
Now, what about B?
Check the URL of B in the 'Subversion' tab of the directory's
properties dialog in Windows. On the command line you can use
the 'svn info' command for this purpose. In my case this is:
$ svn info B | grep Copied\ From\ URL
Copied From URL: file:///tmp/svn-sandbox/repos/branch/A
So clearly it's a copy from the branch, not from trunk!
This happened because we renamed the folder before running
the merge, forcing a tree conflict, so that Subversion won't
add 'B' as a copy from trunk.
You might also want to verify that the content in files with B
still matches what you expect, just to make sure (and this is where
things get more complicated if you also have other changes in rN...)
Since the directory B is precisely in the state we want it to
be in, we can also just mark the conflict resolved:
$ svn resolved B
Resolved conflicted state of 'B'
$
Now commit the entire working copy. This commit will mark revision N
as merged from trunk and rename A to B on the branch. Future merges
from trunk will expect a path B instead of A, and work as expected.
For instance, merging r6 from trunk which changed a file B/zeta just
works:
$ svn merge -c6 ^/trunk
--- Merging r5 through r6 into '.':
G B/zeta
--- Recording mergeinfo for merge of r5 through r6 into '.':
G .
$
I hope this helps. If you have further questions feel free to ask.
Re: How to merge a rename of a folder
Posted by Ryan Schmidt <su...@ryandesign.com>.
On Oct 9, 2012, at 10:23, Martin Bischoff <ti...@gmail.com> wrote:
> What is the correct procedure to merge a rename of a folder to a branch?
Several years ago, the correct procedure was: don't. I don't know if this has changed since then.