For most of our projects we use what would most closely resemble a “branch for feature” strategy in source control. This means that we are developing new features in Dev branches which are then merged into the Main branch when development and unit testing have been completed.
One of the problems we’ve had several times was when a new project was added to the solution in one of the Dev branches. This is problematic at merging time because TFS does not know which branch to merge this project to since it’s never been branched to start with.
Our source control tree would look something like this (simplified here):
As you can see, Project2 does not exist in the Main branch
The solution is to use the baseless merge feature of TFS. This allows us to tell TFS to merge our code with a branch that was not the base for the code initially. There is no function within Visual Studio to do a baseless merge so we have to use the tf.exe command-line utility located in <drive>:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE for VS2008. More information can be found on this command-line utility and everything it can do at http://msdn.microsoft.com/en-us/library/z51z7zy0.aspx
Note: this article applies to VS2005 and VS2008 but since I use VS2008 more frequently, all the paths and naming are based on this version. You just have to replace the path with the correct one if you are using VS2005.
As for any merge action, you have to make sure you have both the source and destination branches mapped to your local drive.
- The first thing you need to do it create a new folder for the Project2 files in the Main branch. You do this from the Source Control Explorer in VS.
- Check-in the new folder into source control.
- Open the Visual Studio 2008 Command Prompt (to make sure that tf.exe has been added to the path)
- Type the following command:
tf.exe merge “<drive>:\<path_to_dev1_branch>\Project2″ “<drive>:\<path_to_main_branch>\Project2″ /baseless -r
Make sure you don’t forget the -r option or you will only merge the folder and not its content. the “r” means recursive.
- You only need to check-in the merged code as you would from any other merge action and that can be done from the Source Control Explorer.
The baseless merge creates a link between the source and target branches so sub-sequent merges will not have to be baseless. However, you have to be aware that the link gets established for files and folders below the starting point of your merge. So, for example, looking at the sample above, if you do a baseless merge between the 2 Project1 branches with Dev1 as source and Main as target, Project1 of the Main branch will not become the base for Project1 of the Dev1 branch. Files and folders underneath Project1 will be linked. If you want to have the Project1 folder of the Main branch become the base for Project1 of the Dev1 branch, you will have to do the baseless merge one level higher. This means that you need to do something like this:
tf.exe merge “<drive>:\<path_to_dev1_branch>” “<drive>:\<path_to_main_branch>” /baseless -r
Update (12/02/08): updated the Notes section where I was wrongly reporting that the baseless merge didn’t create a link between the 2 branches