Branching and Merging with Subversion
I always have to re-read the documentation for merging in subversion, and it's not really that confusing. So I am writing this document as a reference for myself, and anyone else that is having trouble. If any of these commands seem confusing or you're unsure about the meaning, check the help messages of the subversion client ( svn help <command> ).Scenario
I have a project called myProject, in a subversion repository and I wanted to add some features to it, but I didn't want to tamper with the main version of the project. That way I could make small bug fixes to the main line of development with out worrying about all my new features breaking it.My folder structure is as follows:
/myProject/trunk/srcThe src directory contains the source files for the project, and that is what I need to make a copy of so I can add my features with out messing up the main line of development. So in order to make copy of the trunk directory, I do need to do a few things; First, I need to add a branches folder under the myProject directory, that will contain this branch and all future branches. Second, I have to copy the trunk into the branches folder.
Creating branches folder
First get the trunk all up to date and add the new branches directory:cd myProject svn update . mkdir branches svn add branches svn commit -m Created branches directory branches
Copying the trunk into the branches folder
Next, I have to copy the trunk into the branches directory, which is really simple:cd myProject svn update . svn copy trunk branches/myBranch svn commit -m Added my branch. branches
Merging the changes
So, a week or so later I added some really sick features and I am pretty sure that everything is going to work out ok. The way I usually handle this, is make a temp directory that will be used for this merge process.mkdir /some/path/tempDir cd /some/path/tempDir svn co svn://foo/myProject . svn merge dry-run svn://host/myProject/trunk svn://host/myProject/branches/myBranch trunkThat last command will NOT merge anything, because of the dry-run flag. The command is pretty straight forward, except for the trunk at the end. What I am doing is merging the trunk and myBranch INTO a working copy of the trunk. The repositories trunk and myBranch are specified by the URLs and the working copy of trunk is going to receive the changes from the merge. So don't worry if you mess something up, it has no effect on the repository, just the working copy of trunk. Now everything looks like it worked out ok, so I re-run the command with out the dry-run option:
svn merge svn://host/myProject/trunk svn://foo/myProject/branches/myBranch trunkNow, I can build and test the trunk of myProject and make sure there are no bugs or conflicts. Once I can verify that everything is all set, I will commit the trunk back into the repository, and now my changes are a part of the main line of development. Sometimes when working on a large project with a group of people, I find it easier to merge my branch with the revision number of the trunk at the time I branched ( not the current HEAD revision ). Then, once I verify everything is working, I will update that trunk to the head revision, test again, and commit.
There are plenty of tools that can help do this like TortoiseSVN, but I often find the extra options to be confusing when doing a simple merge. Plus, it's not a bad idea to learn to do this from the command line, as it's the same syntax across the UNIX, Windows, and Mac svn clients ( as far as I know ).
If you take a look at the svn help merge message, you should see the usage:
usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH] 2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH] 3. merge -r N:M SOURCE[@REV] [WCPATH]It looks pretty intimidating, but it's really not. Compare the command I used with usage example 1 and it might seem a bit easier to understand. It's also a lot easier to understand if you know the basic usage of the svn diff command. In it's simplest form svn diff would look something like this:
svn diff old_file new_fileIt will print the differences between the 2 versions of the file. Instead of printing the differences, the merge command will attempt to make the changes between the 2 files. In my case it wasn't files, it happened to be directories, and the files contained in those directories.


