Merging feature branches for QA with TFS (part 1)

or How to merge sibling branches with the least conflicts as possible

In this post series I’ll propose a simple procedure to merge feature branches among them without merging into Main. This is particularly useful when you want to test the features altogether (or by groups of features) without bringing yet all the content onto the Main branch. If you have a large code base, you also want to avoid conflicts as much as possible.


Team Foundation Version Control (TFVC) is a great version control system as long as your respect the branching and merging guide produced by the ALM Rangers. You can handle pretty complex situations and have branching trees such as this:


© Visual Studio ALM Rangers

All is well under control as long as you merge between branches that have parent-child relationship. Should you need to merge between any pair of branches, you can always :

  • Use a TFS “baseless” merge
  • Use a Shelveset (code stored at server side in a separated storage that you merge onto anything)

TFS baseless merges (really baseless?)

To achieve a baseless merge you have to type a command like:

tf merge /baseless $/Project/SourceBranch $/Project/DestBranch /recursive

More on the merge command here. That will create a merge relationship between two branches with no obvious connection (read parent-child). Now the merge relationship is established, subsequent merges are then managed by TFS UI (Visual Studio) and history engine. Good.

But still, this king of merge is not very satisfactory because TFS is not very good at picking the most recent common ancestor “in a clever way”. Don’t laugh too fast, Git is not very clever either at picking up the best base.

Here is the best scenario you can get with TFS when merging sibling branches: the base is the origin of the branch you are merging from. When merging with the command line, you should use the /version parameter to select only wanted changesets, don’t take the changeset that created the branch, or the whole branch will be a conflict. Take only the changesets your are interested in, as explained by Buck Hodges here. In this precise case (schema below), I selected all the changesets but the one that created the branch dev B, in order to merge its contents into dev A.


I’m lying, the UI can do it!

Ok, sorry, but since this feature is new in TFS 2012, don’t blame me too much if put in my article a bit of TFS history!

So with TFS 2012, it is now very easy to perform baseless merges in the UI. You can edit manually the target branch in the merge wizard. Then choose to pick the changesets you want:


Then select the changesets you want to merge (without the branch creation):


Made with Brien Keller VS 2012 VM Smile

Using Shelvesets

The trick is to use the TFS power tools to unshelve your content to a different branch. The command will “translate” server paths to another location (that you must have mapped in your Workspace):

tfpt unshelve /migrate /source:$/Project/SourceBranch /target:$/Project/TargetBranch

They are very handy but don’t expect a top notch merging experience regarding to the conflicts that are generated. Before TFS 2010 SP1 baseless merges improvements, they were kings for moving fixes from branch to branch. Now, that baseless have improved, I’m not so sure, I go “baseless” more and more.


Next post I’ll talk about a solution, there is no magic, we’ll use external tools to achieve our goal. Till then, just think, what base is the best in such a case?

Stay tuned!

Leave a Reply

Your email address will not be published. Required fields are marked *