We use SVN merging in the Open MPI project, particularly with a /tmp
tree that we created at the same level as /trunk. If a developer needs
to de-stabilize the trunk for a while, they usually copy the /trunk
into a private branch in /tmp (e.g., /tmp/jeff-stuff). Then the
developer can go develop there for a while, and merge over updates from
the trunk as necessary to start current with the trunk HEAD. Then,
when done, /tmp/jeff-stuff can be merged back into the /trunk.
Hence, we do merges in 2 directions -- from the trunk to a branch, and
then from that branch back to the trunk. The process is actually
identical -- it's just a question of swapping the *from* and *to*
arguments on the command line, so to speak.
Merging is *significantly* better than patching when you're
adding/removing files, and it helps eliminate potential for human error
if trying to replay actions in multiple SVN trees (e.g., commit on the
trunk, and then try to replay the same actions on a different tree).
Plus, SVN tracks the history accurately (the fact that it was a merge,
etc.). Repeat after me: accurate version control history is good.
So how to do this w.r.t. OSCAR?
As with anything, there's a dozen ways to do this. Here's one way...
Let's take a concrete example -- Dave's recent commits to the trunk
that need to be ported over to the branch-4-2. There are three general
forms of "svn merge":
1. merge [EMAIL PROTECTED] [EMAIL PROTECTED] [WCPATH]
2. merge [EMAIL PROTECTED] [EMAIL PROTECTED] [WCPATH]
3. merge -r N:M [EMAIL PROTECTED] [WCPATH]
I normally use the 3rd form. Keep in mind that you can *only* merge
things that have previously been committed. Put differently: if you
want to merge, it must be committed somewhere in the repository
already.
Dave's stuff had previously been committed on the trunk, so it meets
the criteria.
The first step is to determine exactly what changeset (or changesets)
you want to merge. "svn log -v" is your friend here. Dave's stuff is
on the trunk, so get a log of the trunk. I have a trunk checkout, so:
$ cd svn/oscar-trunk
$ svn log -v > log.txt
Now examine log.txt and determine which r number(s) that you want to
snarf. I'm thinking that we want to grab the following commits:
r3490
r3483-3486
The next step is to get into the *target* tree. So in the OSCAR case,
get a checkout of the branch-4-2 tree. If you don't already have one:
$ svn co
https://svn.oscar.openclustergroup.org/svn/oscar/branches/branch-4-2
oscar-4.2
$ cd oscar 4.2
So now we're in the branch checkout. The first thing you want to do is
ensure that you're not going to try to merge an r number from the trunk
that was from before the branch was created. Again, "svn log" is your
friend:
$ svn log -v --stop-on-copy
This will show the log on the branch, but it will stop when the branch
was created (--stop-on-copy is a cool feature). In this example, the
last entry it will show is r3482 -- when John created the branch.
So we can see that all the r numbers above (r3490, r3483-3486) are all
after the branch was created, so we're good.
Now we want to apply the revisions. You can either apply them en-masse
(only works for contiguous revisions), or you can apply them one at a
time -- but only if the commits are non-overlapping (more on this
below). We'll do 2 commits here in this example: first we'll merge
3483-3486 and then commit that, and then we'll merge 3490 and commit
that.
So let's look at the 3rd form of the merge command and apply it here.
It's easiest to show the command and then explain it:
$ svn merge -r3482:3486
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
What this does is pull down the changes from r3482 through 3486 from
the trunk URL into the current working directory. NOTICE that I used
384***2***, which is one less than the first r number that we wanted to
grab (384***3****). This is because we're dealing with deltas. So to
get 3483, we have to ask for the difference between 3842 and 3483.
Make sense?
If you run "svn status", you'll see that you have a lot of changes in
your working copy:
$ svn st
M scripts/generic-setup
M lib/OSCAR/MAC.pm
D
packages/sis/distro/common-rpms/systeminstaller-1.04-10oscar.noarch.rpm
A +
packages/sis/distro/common-rpms/systeminstaller-1.04-11oscar.noarch.rpm
D
packages/sis/distro/common-rpms/systeminstaller-x11-1.04
-10oscar.noarch.rpm
A +
packages/sis/distro/common-rpms/systeminstaller-x11-1.04
-11oscar.noarch.rpm
D packages/sis/SRPMS/systeminstaller-1.04-10oscar.src.rpm
A + packages/sis/SRPMS/systeminstaller-1.04-11oscar.src.rpm
So this pulled over all the changes from r3482 through r3486 and put
them as local changes in your tree. Now you have to commit them:
$ svn ci
...editor comes up...
I typically put in a message indicating that this is a merge, and I
include the specific "svn" command that I used to pull them down, and
then all the log messages for the r numbers that I committed. For
example:
-----
This commit is a merge of several commits from the trunk:
svn merge -r3482:3486
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
Commit message for r3486:
Type on help
Commit message for r3485:
Bug: 1258729; 'Assign All' doesn't enable properly
Commit message for r3484:
Fix systeminstaller BuildRequires and Requires
Commit message for r3483:
Fix generic-setup
------
So the first merge is committed and done. But we still have one more
commit that we want to pull from the trunk -- r3490. So we do another
"svn merge" command:
$ svn merge -r3489:3490
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
Again, notice that we have to give a *delta* specification here, so
we're grabbing the difference between 3489 and 3490 from the trunk.
Now commit it:
$ svn ci
...editor comes up...
-----
This commit is a merge of several commits from the trunk:
svn merge -r3489:3490
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
--
{+} Jeff Squyres
{+} [EMAIL PROTECTED]
{+} http://www.lam-mpi.org/Commit message for r3490:
RFE 1052496; file choosers in Build Image only show appropriate files
------
Let's have a quiz to see if you were really paying attention. Would
the following have worked?
$ svn co
https://svn.oscar.openclustergroup.org/svn/oscar/branches/branch-4-2
oscar-4.2
$ cd oscar 4.2
$ svn merge -r3482:3486
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
$ svn merge -r3489:3490
https://svn.oscar.openclustergroup.org/svn/oscar/trunk
$ svn ci
What do you think? All we did here was do both merges before
committing (as opposed to merge/commit/merge/commit).
The answer is *no* -- it would not have worked.
But why?
It's because there were overlapping, conflicting changes between the
two merges. Specifically, in the first merge, we added file A. Then,
in the second merge, we removed file A. This is Bad -- don't do this
without an intervening commit. SVN will give you warnings during the
merge if this kind of situation arises (actually, SVN may have the
wherewithal to make this all Just Work, but in general, it's bad
practice -- don't do it). In fact, the only reason we could apply
3482-3486 together is because there were no overlapping adds/removes
(multiple, non-exclusive patches to a single file are fine, of course
-- by definition, you wouldn't really run into this kind of problem by
pulling a contiguous series of commits from a single tree, of course,
but if you try to do complex merges by pulling in non-contiguous
revisions or from multiple sources, you can run into conflicting
patches to a single file).
For those looking at the fine print, file A was
/trunk/packages/sis/distro/common-rpms/systeminstaller-x11-1.04
-11oscar.noarch.rpm.
There you go. SVN merging in simplicity. :-)
--
{+} Jeff Squyres
{+} The Open MPI Project
{+} http://www.open-mpi.org/
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
Oscar-devel mailing list
Oscar-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oscar-devel