You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Duncan Murdoch <su...@murdoch-sutherland.com> on 2004/07/23 13:40:38 UTC

Standard setup for multiple branch merges?

I'm working in the R project, and we've just switched from CVS to
Subversion.  Our practice is to create a branch (currently
R-1-9-patches) at the time of a release for bug fixes; the trunk is
for the main development.

At fairly regular intervals we merge the changes on R-1-9-patches into
the trunk.  Our CVS script to do this looked like this:

>	# assumes that 	"last-patch-update" is set correctly
>
>export RTOP=~/R-devel #adjust as necessary
>export TAG=R-1-9-patches
>
>cd $RTOP/r-devel/R
>cvs rtag -F -r $TAG  patch-update R
>
>cvs update -Pd
>cvs update -Pd -j last-patch-update  -j patch-update
>find -type f | xargs grep '>>>>>>>'
>	# fix conflicts...
>cvs commit -m 'branch update'
>
>	# better do this right away...
>cvs rtag -F -r patch-update last-patch-update R

I think I can do a fairly literal translation of this to Subversion;
it looks like this (but is untested, so might have dumb errors):

>export REPOS=https://svn.r-project.org/R
>export RTOP=~/R-devel #adjust as necessary
>export TAG=R-1-9-patches
>
>svn rm -m'branch update' $REPOS/tags/patch-update
>svn cp -m'branch update' $REPOS/branches/$TAG $REPOS/tags/patch-update
>
>cd $RTOP/r-devel/R
>svn update
>svn merge $REPOS/tags/last-patch-update $REPOS/tags/patch-update
>
>find -type f | xargs grep '>>>>>>>'
>	# fix conflicts... (remember to use svn resolved for each)
>svn commit -m 'branch update'
>
>	# better do this right away so we don't forget...
>svn rm -m'branch update' $REPOS/tags/last-patch-update
>svn cp -m'branch update' $REPOS/tags/patch-update $REPOS/tags/last-patch-update

However, I have the feeling that this isn't the right way to do it.
(For one thing, it results in 5 commits; I'd like just one.) The
Subverison book talks about doing this without tags, just using the
comments in the log to figure out which revision numbers need to be
merged in.  I'd like to avoid having to search through the log, so it
seems to me that storing the revision numbers corresponding to
last-patch-update and patch-update in properties somewhere would be a
better approach.

Can an experienced Subversion user comment on this?  This must be a
problem that others have solved; is there some standard solution
around on the net somewhere?

Duncan Murdoch

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Duncan Murdoch <su...@murdoch-sutherland.com>.
No answers on the question below yet, so let me ask a simpler one.

In CVS it was possible to use a tag as a placeholder, and then move it
to a new position.  What's the best way to do this in Subversion?
Below I was doing it using 

> svn rm -m'branch update' $REPOS/tags/last-patch-update
> svn cp -m'branch update' $REPOS/tags/patch-update $REPOS/tags/last-patch-update

but this causes two commits.  I could do it with only one commit with
something like

cd $RTOP/R/r-patched
svn switch $REPOS/tags/last-patch-update
svn merge $REPOS/tags/last-patch-update $REPOS/branches/$TAG
svn commit -m'branch update' 
svn switch $REPOS/branches/$TAG

but this looks ugly.  Is there a standard way to do this?

Duncan Murdoch

On Fri, 23 Jul 2004 09:40:38 -0400, Duncan Murdoch
<su...@murdoch-sutherland.com> wrote :

>I'm working in the R project, and we've just switched from CVS to
>Subversion.  Our practice is to create a branch (currently
>R-1-9-patches) at the time of a release for bug fixes; the trunk is
>for the main development.
>
>At fairly regular intervals we merge the changes on R-1-9-patches into
>the trunk.  Our CVS script to do this looked like this:
>
>>	# assumes that 	"last-patch-update" is set correctly
>>
>>export RTOP=~/R-devel #adjust as necessary
>>export TAG=R-1-9-patches
>>
>>cd $RTOP/r-devel/R
>>cvs rtag -F -r $TAG  patch-update R
>>
>>cvs update -Pd
>>cvs update -Pd -j last-patch-update  -j patch-update
>>find -type f | xargs grep '>>>>>>>'
>>	# fix conflicts...
>>cvs commit -m 'branch update'
>>
>>	# better do this right away...
>>cvs rtag -F -r patch-update last-patch-update R
>
>I think I can do a fairly literal translation of this to Subversion;
>it looks like this (but is untested, so might have dumb errors):
>
>>export REPOS=https://svn.r-project.org/R
>>export RTOP=~/R-devel #adjust as necessary
>>export TAG=R-1-9-patches
>>
>>svn rm -m'branch update' $REPOS/tags/patch-update
>>svn cp -m'branch update' $REPOS/branches/$TAG $REPOS/tags/patch-update
>>
>>cd $RTOP/r-devel/R
>>svn update
>>svn merge $REPOS/tags/last-patch-update $REPOS/tags/patch-update
>>
>>find -type f | xargs grep '>>>>>>>'
>>	# fix conflicts... (remember to use svn resolved for each)
>>svn commit -m 'branch update'
>>
>>	# better do this right away so we don't forget...
>>svn rm -m'branch update' $REPOS/tags/last-patch-update
>>svn cp -m'branch update' $REPOS/tags/patch-update $REPOS/tags/last-patch-update
>
>However, I have the feeling that this isn't the right way to do it.
>(For one thing, it results in 5 commits; I'd like just one.) The
>Subverison book talks about doing this without tags, just using the
>comments in the log to figure out which revision numbers need to be
>merged in.  I'd like to avoid having to search through the log, so it
>seems to me that storing the revision numbers corresponding to
>last-patch-update and patch-update in properties somewhere would be a
>better approach.
>
>Can an experienced Subversion user comment on this?  This must be a
>problem that others have solved; is there some standard solution
>around on the net somewhere?
>
>Duncan Murdoch
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
>For additional commands, e-mail: users-help@subversion.tigris.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Duncan Murdoch <su...@murdoch-sutherland.com>.
On Fri, 23 Jul 2004 15:24:04 -0500, Ben Collins-Sussman
<su...@collab.net> wrote:

>
>Let me phrase it another way:  the reason your current CVS process is so
>obsessed with tag creation is because CVS has no ability to name/capture
>changesets.  Incessant tagging is the *only* way to approximate that
>sort of thing:  "let's see, to port this bugfix, I need to tag the tree
>before committing, and tag it after committing, and then use those tags
>to merge the change to a different branch."  
>
>In Subversion, the tagging isn't necessary.  You just "port change r3981
>from branchA to branchB".  All the correct files are part of the
>changeset already.

Thanks again.  This sort of advice is very helpful.

The reason I'm asking this is that I'm revising the document 

 <http://developer.r-project.org/CVStips.html>

to apply to Subversion instead of CVS.  This page tells how to check
out working copies, commit changes, etc. You don't happen to know of
similar project-specific advice for some other project that I could
steal^H^H^H^H^Hconsult, do you?

Duncan Murdoch

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Ben Collins-Sussman <su...@collab.net>.
On Fri, 2004-07-23 at 15:17, Duncan Murdoch wrote:

> Turns out that pretty frequently we do merges for only a few files, or
> for a subtree, and sometimes do backports to the stable branch.  So we
> can't just save the revision of the last merge in a file, we need a
> more complicated scheme, more closely equivalent to a CVS tag.

Ah, so your team *is* normal, then.  :-)

I don't think any amount of scripting and automation is going to help,
then.  Or rather, the complexity will become so immense, it's just
easier to port stuff as needed by hand.

You need to get out of the mindset of 'merging particular files' and
think about porting 'changesets' back and forth.  You need to do what
the rest of us do:  merge specific changesets by naming them via global
revnums.  The book talks all about it, as you already know.  It's much
easier to have a human being do this stuff, rather than creating
zillions of temporary tags.

Let me phrase it another way:  the reason your current CVS process is so
obsessed with tag creation is because CVS has no ability to name/capture
changesets.  Incessant tagging is the *only* way to approximate that
sort of thing:  "let's see, to port this bugfix, I need to tag the tree
before committing, and tag it after committing, and then use those tags
to merge the change to a different branch."  

In Subversion, the tagging isn't necessary.  You just "port change r3981
from branchA to branchB".  All the correct files are part of the
changeset already.



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Duncan Murdoch <mu...@stats.uwo.ca>.
Thanks very much for your comments.  They're just the sort of thing I
was looking for.  Unfortunately, I asked the wrong question....

Turns out that pretty frequently we do merges for only a few files, or
for a subtree, and sometimes do backports to the stable branch.  So we
can't just save the revision of the last merge in a file, we need a
more complicated scheme, more closely equivalent to a CVS tag.

I think I can simplify the original script, but I don't think I'm
going to get it as clean as what you suggested :-(.

Duncan Murdoch

On Fri, 23 Jul 2004 14:56:43 -0500, Ben Collins-Sussman
<su...@collab.net> wrote :

>On Fri, 2004-07-23 at 08:40, Duncan Murdoch wrote:
>
>> >export REPOS=https://svn.r-project.org/R
>> >export RTOP=~/R-devel #adjust as necessary
>> >export TAG=R-1-9-patches
>> >
>> >svn rm -m'branch update' $REPOS/tags/patch-update
>> >svn cp -m'branch update' $REPOS/branches/$TAG $REPOS/tags/patch-update
>> >
>> >cd $RTOP/r-devel/R
>> >svn update
>> >svn merge $REPOS/tags/last-patch-update $REPOS/tags/patch-update
>> >
>> >find -type f | xargs grep '>>>>>>>'
>> >	# fix conflicts... (remember to use svn resolved for each)
>> >svn commit -m 'branch update'
>> >
>> >	# better do this right away so we don't forget...
>> >svn rm -m'branch update' $REPOS/tags/last-patch-update
>> >svn cp -m'branch update' $REPOS/tags/patch-update $REPOS/tags/last-patch-update
>
>This definitely works, it's just very "involved", as you said.  It's not
>so pretty to look at.  You're constantly destroying and creating tags as
>a way of remembering merge-points.
>
>It's funny that you do bug fixes first on the 'stable' branch, then port
>them to the unstable trunk.  My impression is that most projects (like
>the subversion project) fix bugs on trunk and 'backport' them to the
>stable branch.  But I digress.  :-)
>
>In any case, the scenario is that you want to regularly merge one branch
>to another, in an automated way.  I can offer a different way of
>automating this which doesn't use tags as 'markers' for merge points at
>all... it uses revnums instead.
>
>0. cd trunk-working-copy
>
>1. Run 'svn st -u' or 'svn up' and parse the last line, so you have a
>value for the HEAD revision (or something very close to HEAD, since
>there's always a race condition against new commits.  :-) )
>
>2. Read OLDREV from a file.
>
>3. svn merge -r OLDREV:HEAD branchURL
>
>4. resolve conflicts; svn commit -m "Merge revisions OLDREV:HEAD from
>branch to trunk"
>
>5. Save HEAD into the file for next time.
>
>Voila, only one revision committed.
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Ben Collins-Sussman <su...@collab.net>.
On Fri, 2004-07-23 at 14:56, Ben Collins-Sussman wrote:

> > >find -type f | xargs grep '>>>>>>>'
> > >	# fix conflicts... (remember to use svn resolved for each)

By the way, this is not the way to find conflicts in Subversion.  Just
run 'svn status' and look for (C)onflicted files.

And I sure hope you're not depending on a script to fix the conflict
markers.  :-)



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Standard setup for multiple branch merges?

Posted by Ben Collins-Sussman <su...@collab.net>.
On Fri, 2004-07-23 at 08:40, Duncan Murdoch wrote:

> >export REPOS=https://svn.r-project.org/R
> >export RTOP=~/R-devel #adjust as necessary
> >export TAG=R-1-9-patches
> >
> >svn rm -m'branch update' $REPOS/tags/patch-update
> >svn cp -m'branch update' $REPOS/branches/$TAG $REPOS/tags/patch-update
> >
> >cd $RTOP/r-devel/R
> >svn update
> >svn merge $REPOS/tags/last-patch-update $REPOS/tags/patch-update
> >
> >find -type f | xargs grep '>>>>>>>'
> >	# fix conflicts... (remember to use svn resolved for each)
> >svn commit -m 'branch update'
> >
> >	# better do this right away so we don't forget...
> >svn rm -m'branch update' $REPOS/tags/last-patch-update
> >svn cp -m'branch update' $REPOS/tags/patch-update $REPOS/tags/last-patch-update

This definitely works, it's just very "involved", as you said.  It's not
so pretty to look at.  You're constantly destroying and creating tags as
a way of remembering merge-points.

It's funny that you do bug fixes first on the 'stable' branch, then port
them to the unstable trunk.  My impression is that most projects (like
the subversion project) fix bugs on trunk and 'backport' them to the
stable branch.  But I digress.  :-)

In any case, the scenario is that you want to regularly merge one branch
to another, in an automated way.  I can offer a different way of
automating this which doesn't use tags as 'markers' for merge points at
all... it uses revnums instead.

0. cd trunk-working-copy

1. Run 'svn st -u' or 'svn up' and parse the last line, so you have a
value for the HEAD revision (or something very close to HEAD, since
there's always a race condition against new commits.  :-) )

2. Read OLDREV from a file.

3. svn merge -r OLDREV:HEAD branchURL

4. resolve conflicts; svn commit -m "Merge revisions OLDREV:HEAD from
branch to trunk"

5. Save HEAD into the file for next time.

Voila, only one revision committed.



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org