Merging
Contents |
Merging
From Brad Stiles
A merge using Subversion happens in a working copy, not in the repository. The general steps to follow are:
- Check out the directory, or update an existing working copy, to which you want to merge changes. For instance, if you are merging changes from the 5.10 branch to the trunk, you would check out the trunk.
- Using the 'svn merge' command, apply the *set* of changes between two revisions in the source, e.g. the branch, to the working copy.
- Resolve any conflicts that arise. TortoiseSVN makes this absurdly easy, but it's not difficult with the command line interface either.
- Commit the working copy.
For instance, if your branch is at https://svn.sourceforge.net/svnroot/pcgen/Branches/5.10.x and your trunk is at https://svn.sourceforge.net/svnroot/pcgen/Trunk, you would start by checking out https://svn.sourceforge.net/svnroot/pcgen/Trunk to a local working copy. For this example, I'll assume that directory is "c:\pcgen\merge"; substitute your own as necessary.
Next, determine the set of changes you want to merge. For instance, if you want to merge from the start of the branch, which was cut in rev 865 I believe, to the current revision, you want 866 (that's not a typo, since the first change to the branch was committed in rev 866) to HEAD. You can also use a specific revision number instead of just HEAD, if for instance, some changes on the branch aren't working yet, but you still want to merge what was commited before that.
Now merge from the branch to your working copy. Using TSVN is pretty simple, and if you need help with that, let me know (I'll have to make pictures and upload them). For now, I'll illustrate using the CLI.
Using the Command Line Interface, execute the following:
svn merge -r 866:HEAD https://svn.sourceforge.net/svnroot/pcgen/Branches/5.10.x c:\pcgen\merge
This takes the set of changes that happened in the given repository directory between those two revisions and applies them to the working copy in c:\pcgen\merge.
Now comes the "interesting" part. There will likely be a number of changes that Subversion sees as conflicts that it can't resolve automatically. The person doing the merge will have to examine each one of those and resolve it.
Subversion places conflict markers, I think the same ones used by CVS, in the file around all the conflicts. 'svn stat' will show you which files are conflicted with a "C" in one of the first two columns (column 1 is for the file itself, and column 2 is for properties). Edit each of the conflicted files, removing the conflict markers. As each file is resolved, execute 'svn resolved <filename>' to tell Subversion you've dealt with it, and that it may treat it as a normal change.
TSVN also makes this pretty simple. Right-click on the conflicted file and choose TortoiseSVN->Edit Conflicts. The two files will show up next to each other, with a third pane on the bottom that will show the final state of the file when conflicts are resolved. Note the names at the top of each pane; one has "mine" and one has "theirs". The "mine" file is the one that was originally in the working copy, in this case the trunk, before the merge. The "theirs" file is the one that came brom the branch.
There are two red buttons at the top that will help you find the next conflict in the file. As you get to each conflict, choose which side is correct, right click on the conflicted block and select which side you want to use. You can also choose to use both, or neither.
Note that the "mine" and "theirs" files are actual files in the directory, created by Subversion, along with the file containing the markers. If you decide that you want to use the file from the branch in toto, without caring what was in the trunk, you can just delete the marked up file, and rename the "theirs" file to the original name. You can then delete the "mine" file as well.
Thre will also no doubt be many files that were automatically merged by Subversion. Note that THIS DOES NOT MEAN THAT THE MERGED CHANGES MAKE SENSE in the context of the file, only that Subversion did not find any line based conflicts. You still have to test the code before committing it.
You also need to update your working copy before committing, as others may have checked something in while you were merging and resolving conflicts. This may produce more changes and/or conflicts that have to be resolved and tested.
When you do commit, make sure the message lists the starting and end revision numbers. This is so that the *next* merge can be started at the revision after the one this one used as the end. Subversion doesn't have any automatic merge tracking, so you need to make sure that log messages are clear about what was merged and from where.
The size of this job is an argument for merging only pieces of the branch at one time. Perhaps only one directory of /Trunk at a time is appropriate.
Hope this helps. Ask any questions that come to mind.
Viewing changes
A couple of things for those that are interested and don't already know:
To view the set of files that changed in the merge, using TortoiseSVN.
- Right-click your desktop, select TortoiseSVN->Repo Browser. For the URL, enter https://svn.sourceforge.net/svnroot/pcgen/Trunk
- After a few moments, the repository browser will appear with the "Trunk" node already highlighted. Right click on "Trunk" and select "Show Log"; the Log Messages dialog will appear.
- Click on revision 1280 (for the 5.10.1 merge) and the commit message for that revision will be shown in the middle pane, while the set of files that was changed in that revision will be displayed in the bottom pane of the dialog. Right click on any of those files and select "Show Differences" to see the actual diff. Note that if the only difference in a file is the presence or absence of a line end at the *end* of the file, Tortoise Diff won't show that to you in any graphical way, even though it's still seen as a change. I haven't found where it will display the changes in properties, either.
- To see the set of changed files using the command line interface, type the following at your command prompt. svn log https://svn.sourceforge.net/svnroot/pcgen/Trunk -r 1280 --verbose
- To see the difference in one file for this revision type:
svn diff https://svn.sourceforge.net/svnroot/pcgen/Trunk/full/path/to/file.name -r 1279:1280
The command line tool *will* explicitly report a difference if the only difference is the presence or absence of a line-ending. It will also show that properties changed.
I hope this helps, but if nobody needs this kind of explanation, let me know and I'll knock it off.