Welcome to MSDN Blogs Sign in | Join | Help

A Branching and Merging Primer

Hmm, OK I guess I jumped too quickly into using unfamiliar terminology.  Let me step back and define some of the concepts/terms a little more and then hopefully that last post will make more sense.

The Source Tree

Let’s start with what the source tree in the Developer Division looks like.  It has the following top level folders (not a complete list but a relevant subset).  Each of these folders has its own subtree of subfolders and files.

CSharp
DDSuites
Public
Tools
VB
VC
VSCommon
VSET

CSharp - is a tree that contains all of the code for the CSharp compiler, project system and related components.
DDSuites - is a very large tree of tests for all of the components in the system.  Any developer can get this folder and run the tests.  This is where we put our unit tests.
Public - This is all of the .h files, import libraries, .NET Framework assemblies, etc. that are needed to build.  For example we check in the .NET Framework assemblies, Windows SDK, etc.  Source code elsewhere in the tree references standard assemblies and header files from this directory.
Tools - A big tree that contains all of our compilers, linkers, source control tools, build configuration files, etc.  Basically everything needed to build the system.  It does not include the IDE – just command line tools.
VB - All the source code that the VB team has written.
VC - All of the source code that the VC team has written.
VSCommon - A set of shared utility library source code, midl files and the like that are shared across many components in VS.
VSET - The source code for the Team System tools.

And of course there’s more – probably 30 or 40 top level folders in our tree but this is a good representative sample.

Why do we check in all of our tools and includes?  Developers already have VS installed on their machine, right?  Well, yes but there are several advantages.  First by versioning them with the source code we can ensure that we always have a consistent set.  If we need to go back and reconstruct a build from 6 months ago we also have the tools we used to build it at that time.  One thing to keep in mind is that we are building the tools too so every few months we check in a new version of the compilers and libraries, etc.  Using the version control system is a great way to distribute the tools to everyone.  Another benefit of doing it this way is that the system is self contained.  You can walk up to a newly installed machine (just the OS), create a Team Foundation workspace, do a get, build and everything works.


How a Developer Uses the Tree

I create a workspace on my machine (workspace is a mapping construct that describes what folders to get and where to put them).  Very few developers put the entire tree in their workspace because it is so big.  Pretty much everyone includes VSCommon, Public and Tools.  Beyond that developers include the folders they need.

To give an example (from Team Foundation – which I enlist in), my workspace looks something like this.

$/Main/tools -> d:\dd\tools
$/Main/public -> d:\dd\public.
$/Main/vscommon -> d:\dd\vscommon
$/Main/ddsuites -> d:\dd\ddsuites
$/Main/vset -> d:\dd\vset

One of the nice things about our build system is that it allows me to build at any level in the tree.  I can build everything in my workspace by going to d:\dd and typing "build".  Or I can build just the Team System components by going to d:\dd\vset and typing build – or just Version control from d:\dd\vset\scm\SourceControl, etc.

After I build, all my built binaries end up in d:\binaries.<cpu><build type>.  For example if I build x86 debug then they end up in d:\binaries.x86dbg.  If I build retail they end up in d:\binaries.x86fre (don’t ask me why retail is called fre :)).


On to Branching and Merging

OK, hopefully with a little background on what the "tree" is, the branching part will be a little easier to understand.  What I’ve described above is how it would all work if all of the developers worked together on the same source at the same time.  As I described in my last blog post, this is impractical – too many developers changing things.

So we created branches off of Main and, in fact, no developer actually works in Main – they all work in some branch.  So start at the beginning.  We checked all of our source into the tree under $/Main.  We then created branches of main.  Using the Source Control Explorer in Team Foundation you can do this by selecting $/Main and choosing File -> Source Control -> Branch.  When the dialog comes up we’d choose $/Lab21.

This would create a whole new copy of the source tree that would look something like:

$/Main
      CSharp
      DDSuites
      Public
      Tools
      VB
      VC
      VSCommon
      VSET
$/Lab21
      CSharp
      DDSuites
      Public
      Tools
      VB
      VC
      VSCommon
      VSET


Right after the branch, $/Main and $/Lab21 are basically exact copies.  Fortunately, however, it doesn’t double your disk space usage.  The new branch ($/Lab21) references the same copies of the files that the original, or Parent branch ($/Main) contains.  Only when you actually modify (checkin) a file in one of the branches is another copy of the modified file made.

Let’s talk for a second about Branch lineage or Parenting.  It’s very complicated and takes a while to internalize.  Let’s take a file in the system as an example.

There is a file (you can probably guess what it is :))

$/Main/VSET/SCM/SourceControl/CommandLine/CommandCheckin.cs

When we branched the $/Main folder above a whole copy of the tree was created.  So there is now another "copy" (remember we don’t actually duplicate the contents until you change it but looking at the tree you can’t tell the difference) of CommandCheckin.cs at:

$/Lab21/VSET/SCM/SourceControl/CommandLine/CommandCheckin.cs

From the perspective of the “folder hierarchy” the two files are in very different parts of the tree – one is deep down under $/Main and the other is deep down under $/Lab21.

However when speaking from a "branch hierarchy" perspective rather than a "folder hierarchy" perspective $/Main/VSET/SCM/SourceControl/CommandLine/CommandCheckin.cs is the parent of $/Lab21/VSET/SCM/SourceControl/CommandLine/CommandCheckin.cs.  When the Lab21 tree was created each file was branched from the corresponding file in the Main tree and this relationship is maintained.  Having this relationship allows changes in CommandCheckin.cs to be easily merged back and forth between the two branches.  So, imagine I had a change to $/Lab21/VSET/SCM/SourceControl/CommandLine/CommandCheckin.cs that I want to move to the main branch.  I can do this by (again using the Source Control Explorer) selecting CommandCheckin.cs under $/Lab21 and choosing File -> Source Control -> Merge.  This will give me a choice of files to merge with and one of them will be the CommandCheckin.cs under $/Main.  After you hit OK, the changes to CommandCheckin.cs under $/Lab21 will be incorporated into the CommandCheckin.cs under $/Main.

To make managing branches easier, you can do this merging at a higher level too.  For example, using the Source Control Explorer as above, I can select the $/Lab21 folder itself rather than the CommandCheckin.cs file way down below it.  When picking the merge target, I pick the $/Main folder.  Because it tracks all of the relationships, it looks down the tree and finds that CommandCheckin.cs has been changed in the $/Lab21 tree and merges it with the corresponding CommandCheckin.cs in the $/Main tree.  Being able to do this makes managing merging changes between branches dramatically easier.

Because changes can be merged in either direction and it’s confusing which one you mean.  If I say I’m merging Lab21 and Main, what do I mean?  In order to do this we coined some terminology to indicate the direction of the merge.  A "Reverse Integration" (abbreviated RI) is a merge from the "Branch child" to the "Branch parent". And a "Forward Integration" (abbreviated FI) is a merge from the "Branch parent" into a "Branch child".  So using the example from above, if I said I’m going to RI Lab21.  We know that means we are going to merge changes that have been made to files under $/Lab21 into the corresponding files under $/Main.

Hopefully that helps understand the difference between the folder hierarchy and the branch hierarchy.  We can talk meaningfully about both.  When we do this I represent them as follows:

Repeating the folder hierarchy from above:

$/Main
      CSharp
      DDSuites
      Public
      Tools
      VB
      VC
      VSCommon
      VSET
$/Lab21
      CSharp
      DDSuites
      Public
      Tools
      VB
      VC
      VSCommon
      VSET

However, I’d represent the Branch Hierarchy as follows:

Main
      Lab21

What this means is that Lab21 was created by branching from Main.  Even though in the folder hierarchy they are peers, in the branch hierarchy Lab21 is a "child" of Main.  All of the files in Lab21 were branched from the corresponding files in Main.  So looking at a more complex example from my incomprehensible blog post:

Main
      Lab21
            Lab21dev
                  Clr
                  …
      Lab22
            Lab22dev
                  VB
                  …
      Lab23
            Lab23dev
                  TeamFoundation
                  …
      RTM
            Servicing
                  VSTFRTM
      …

This says that Lab21, Lab22, Lab23 and RTM were created by branching from Main.  Lab21dev was created by branching from Lab21.  Clr was created by branching from Lab21dev and so forth.  When it gets this complicated it becomes even more useful to be able to talk about RI’s and FI’s.  For example, I RI changes from Clr into main (done by merging Clr into Lab21dev, then merging Lab21dev into Lab21, then merging Lab21 into Main).  An I FI Main into TeamFoundation (done by merging Main into Lab23, then Lab23 into Lab23dev and finally Lab23dev into TeamFoundation).


Closing

I hope that’s enough background to understand the previous blog post.  That post is more about the end result and the rationale behind it than the mechanics and concepts behind it.  I hope this has enough of those to make the former comprehensible.  If not, let me know and I’ll try again 

Brian

Published Sunday, November 13, 2005 10:54 AM by bharry

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: A Branching and Merging Primer

Wow really helpfull :)

Thanks for explaining!
Sunday, November 13, 2005 11:27 AM by Stephan

# re: A Branching and Merging Primer

Excellent couple of post Brian, this is not only very informative, but also gives us some nice ideas as to how to use the product. Thanks!
Sunday, November 13, 2005 2:09 PM by Tomas Restrepo

# re: A Branching and Merging Primer

Thanks for the great post. Very useful and clearly explains the concept.
Sunday, November 13, 2005 2:17 PM by Vineeth Raja

# re: A Branching and Merging Primer

Great stuff! Can you elaborate a bit more on how each developer is able to just build from any dir? The thing I struggle with when thinking about building using path space branching is how to get a single nightly build script to work for multiple developers when they are likely to be building off of different branches. In SCM products like TFS these different branches manifest themselves as different directories. With our current SCM system which uses version space branching this isn't a problem because everybody's directory structure is the same even if they are using different branches.
Monday, November 14, 2005 6:56 PM by Keith Hill

# re: A Branching and Merging Primer

I'm not sure I thoroughly understand your scenario - but a few comments and you can re-ask the question if I missed it.

I don't know the details of what we put into the project files to enable the tree to be built at any level. The TFS build guys did it and I'm sure they'd be happy to blog about it. I'll send them mail and ask them to post something.

We don't have a "single nightly build". We have one nightly build for each VBL. Individual developer branches don't get built by the build lab but rather are built as needed by the developers who use them. Some set up rolling build machines (continuous integration), others just do it manually when they need a build.

Code only makes it into an "official" build when the code has been RI'd into one of the build lab supported VBLs.
Tuesday, November 15, 2005 8:21 AM by bharry

# re: A Branching and Merging Primer

Our development teams are small enough usually where we have a single KornShell script checked into $/ProjectName/Build/Scripts called DevNightlyBuild.ksh that rebuilds on a developer's PC every night. Each dev sets it up in the task scheduler passing in their email address as the one and only parameter (to mail failure messages). This works great when everyone's directory structure (relative to the project root) is identical. I'm just trying to wrap my mind around how to make this work when folks start using private branches in a path spaced branching SCM tool. All of a sudden each developer may not want to build $/proj/Trunk/Src/Foo but instead build $/proj/Branches/Dev/Joe/Foo. I don't think this is insurmountable or anything. I just need to ponder on this some more. :-)
Tuesday, November 15, 2005 11:27 AM by Keith Hill

# re: A Branching and Merging Primer

Ahh, I think I understand the heart of your question. Our build environment is a command shell that is initialized by running a script called razzle.cmd that sits in:

<vbl root>\tools

It knows where it is relative to the root of the VBL (it's always in the tools subdirectory) and sets an environment variable to the root of the workspace on the user's local machine. Then all of our build scripts are parameterized by that environment variable.

So, using an example. I may want to enlist in $/VisualStudio/lab23. It contains all of the tools, publics, source, etc. I map the directories I need into my workspace:

$/VisualStudio/lab23/tools -> d:\dd\tools
$/VisualStudio/lab23/vset -> d:\dd\vset
and so forth for all of the folders I need.

I then open a command prompt and run d:\dd\tools\razzle (optionally passing a parameter indicating whether I want debug or retail). It sets up environment variables, including one calls NTROOT (Don't ask why it's called this. It's legacy because this system started in Windows). It will set

NTROOT = d:\dd

Because it knows it's always right below the root. Now I can cd to any folder in the tree and build it and it knows where the root is (and can therefore find tools, public, etc) because of the environment variable.

As a side note, I'll mention that not every private branch includes a whole VBL. It's too much stuff to branch for small projects - something like 500,000 files. It's not uncommon to branch $/VisualStudio/private/FeatureX from $/VisualStudio/lab23dev (or one of the other full VBLs) by only branching the subset of subfolders that you need and then have clients create a workspace that maps from both branches. For example:

$/VisualStudio/lab23dev/tools -> d:\dd\tools
$/VisualStudio/private/FeatureX/vset -> d:\dd\vset

I hope this helps.

Brian
Tuesday, November 15, 2005 10:13 PM by bharry

# re: A Branching and Merging Primer

Hey, this is cool, learning from people with such experience has to be a winner; thanks.

A question though. You say the Public folder contains all libs and assemblies the projects reference, including Framework and SDKs. I'm sure the answer is yes, but does this mean that say one of your projects needs the mobile 2005 SDK, rather then referencing something from the GAC (which is why the SDK installs its assemblies), you would copy that assembly from the default installed folder to the Public folder (or a subfolder in here) and reference that instead.

I can see that advantage for doing this with most SDK's, but the Framework? Surely this is required on the build machine anyway?

Wait, hang on, you also copy the compilers to the tools folder don't you, then I bet you reference these from the build script.
Thursday, November 17, 2005 7:27 AM by Graham Allwood

# re: A Branching and Merging Primer

Right, we copy everything. The .NET Framework, all SDKs, compilers and everything to the version controlled tree. This way the tree is pretty much entirely stand alone and makes almost no assumptions about the machine's environment. You pretty much just need a properly installed copy of Windows and the version control tools (so you get get all the rest) and you are good to go.

It makes the tree kind of big but gives us a lot of flexibility to be building things against different versions of the Framework, update the tools and distribute them to the team in a controlled fashion, etc.

Brian
Thursday, November 17, 2005 4:19 PM by bharry

# re: A Branching and Merging Primer

Another question for you Brian...

Do you think that would could ever use Team Build to run your nightly builds are is the Razzle script a little too complicated? Sorry, this is a little off topic (i.e. not branching or merging).
Friday, November 18, 2005 3:24 AM by Graham Allwood

# re: A Branching and Merging Primer

We've actually already integrated some of TFS Build into our nightly build process. We don't use the TFS build launching capability (we really don't want random people around the division starting builds anyway).

Over the next 6 months or so we will be integrating more of it. Our build is big enough and complicated enough that I don't forsee us using any TFS Build "out of the box" configuration in the near term.

We designed TFS Build to be more of a set of building blocks than a turn key solution. We recognize that build processes can be very complex and customized to the needs of each organization. As a result we tried to deliver discrete components for things like labeling the source, generating a build number, running tests, updating work items, etc. This way people can integrate these tasks into what ever custom build process they have.

The "out of the box" TFS build configuration will work for smaller projects and will save a lot of time putting together a build process. In future versions, we will continue to expand the scope of what the out of the box solution can handle (for example adding support for parallelization of the build process, tasks for code signing, etc).
Friday, November 18, 2005 9:17 AM by bharry

# Quickie: bharry on VBLs and branching

A couple of posts by Brian Harry (bharry) from November 2005 about virtual build labs and branching on the TFS project...
Saturday, April 22, 2006 9:36 AM by Stuart Celarier

# Pozo T??cnico &raquo; Blog Archive &raquo; Branching en VSS

Thursday, August 24, 2006 10:54 AM by Pozo T??cnico » Blog Archive » Branching en VSS

# Branching strategies for TFS

There has been a few discussions (Eg. Brian Harry , Martin Woodward , MSDN Forums ) and even a session
Tuesday, September 12, 2006 5:52 PM by My VSTS Blog

# re: A Branching and Merging Primer

Hi!

A bit late, but...
I would like to see a clarification of how you handle the potentially large number of branch folders below "branches" (or the root). Do you create a nested structure from the beginning and use the leaf nodes or do you keep all branch folder below a common parent (the root or "branches")?

I tried to ask the same question in another forum but tries to rephrase it here to make it easier to understand and to connect to your example.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=773007&SiteID=1
Thursday, September 28, 2006 5:44 PM by Johan Bergens

# re: A Branching and Merging Primer

This has been evolving some as our number of branches grows.  The current organization of branches for Orcas (our next version) looks something like this:

$/Orcas - The Team Project

$/Orcas/Main - The main branch from which the final product is built.

$/Orcas/PU - Contains a flat list of branches - one for each product unit.  Under here each product unit has a branch (e.g. $/Orcas/PU//VB and $/Orcas/PU/VSTS, etc) where work from each of their feature teams is merged and tested before being merged into $/Orcas/Main.

$/Orcas/Feature - For Orcas, each "feature" is being developed in its own branch for isolation from the churn induced by other feature teams.  This folder contains a branch for each feature team to work in (e.g. $/Orcas/Feature/LoadTest or $/Orcas/Feature/VCClient01, etc) before merging their changes into their PU branch.  Today this is a flat list under $/Orcas/Feature but you could imagine creating some hierarchy to manage it.

$/Orcas/private - This is a container for random "personal" branches that anyone wants to create and use for a period of time.

Hope this helps,

Brian
Friday, September 29, 2006 9:59 AM by bharry

# Microsoft SCM 的策略 -- from BHarry

bharry's WebLog : A Branching and Merging Primer Branch structure in Developer Division at Microsoft

Saturday, January 20, 2007 10:52 AM by Refines.Info["Polo Lee"]

# Please help: Merge options are disabled

I am using TFS.

I have created a brunch for project proj1 which is called proj1B.

After modifing one of the files in proj1B, chek-in and merge to proj1, the modification was automatically merged into proj1.

If I modify (adding a method) on of the files in proj1, then modifying it also in proj1B (also adding a method), both check-in ---> When I come to merge proj1B to proj1 i get the conflicts dialog (which is fine) with the "Auto Merge All" button DISABLED. When I click on the "Resolve" button, I get the resolve options dialog with the first two merge options also DISABLED ("Merge changes for me" and "Merge changes in merge tool").

I have full permissions.

Thursday, February 08, 2007 8:01 AM by guyRonen

# Resources for Today's TFS Live Meeting

TEAM FOUNDATION SERVER Team System Overview http://msdn2.microsoft.com/en-gb/teamsystem/aa718836.aspx

Wednesday, February 28, 2007 3:39 AM by Microsoft UK Developer Tools Team

# re: A Branching and Merging Primer

Hi,

What if I want to branch only a few items from Parent into the Child and not everything that's there under Parent. How to accomplish that?

I tried two ways of branching:-

1. Create a New Team Project and folow the wizard. It will prompt you to branch from an existing TeamProject. You may choose that or skip. If you choose it, it will branch everything from Parent to Child.

2. Just create an empty TeamProject. Right click the Parent and select Branch. Enter the appropriate paths.

Option 1 maintains the links b/w the Parent and Branch but Option 2 doesn't. Do you know a way to branch just a few files from Parent to Child but with ability to keep the links?

thanks!

Monday, April 14, 2008 2:33 PM by Neha

# bharry's WebLog : A Branching and Merging Primer

Hmm, OK I guess I jumped too quickly into using unfamiliar terminology. Let me step back and define some of the concepts/terms a little more and then hopefully that last post will make more sense. The Source Tree Let’s start with what the source tree

Saturday, May 31, 2008 10:57 AM by Dating

# bharry's WebLog : A Branching and Merging Primer

Hmm, OK I guess I jumped too quickly into using unfamiliar terminology. Let me step back and define some of the concepts/terms a little more and then hopefully that last post will make more sense. The Source Tree Let’s start with what the source tree

Thursday, June 05, 2008 5:37 PM by Weddings

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker