it easier to take code changes from one fork and apply those changes to the other. We call this operation "merging branches," a term which highlights why the physical tree metaphor fails. The two forks of a nature path can merge back into one, but two branches of an oak tree just don't do that. I'll talk a lot more about merging branches in the next chapter.
At this point I should take a step back and admit that my example of doing 1.0 maintenance and 2.0 features is very simplistic. Real life examples are sometimes far more complicated, involving multiple branches, active development in each branch, and the need to easily migrate changes between and two of them. Branching and merging is perhaps the most complex operation offered by a source control tool, and there is much to say about it. I'll begin with how branching works "under the hood."
Two Branching Models
Best Practice: Organize your branches
The "folder" model of branching usually requires you to have one extra level of hierarchy in your repository tree. Keep your main development in a folder named $/trunk. Then create another folder called $/branches. Each time you create a branch off of the trunk, put it in $/branches.
First of all, let's acknowledge that there are [at least] two popular models for branching. In the first approach, a branch is like a parallel universe.
- The hierarchy of files and folders in the repository is sort of like the regular universe.
- For each branch, there is another universe which contains the same hierarchy of files and folders, but with different contents.
In order to retrieve a file, you specify not just a path but the name of the universe, er, branch, from which you want the file retrieved. If you don't specify a branch, then the file will be retrieved from the "default branch." This is the approach used by CVS and PVCS.
In the other branching model, a branch is just another folder, located in the same repository hierarchy as everything else. When you create a branch of a folder, it shows up as another folder. With this approach, a repository path is sufficient to describe a location.
Personally, I prefer the "folder" style of branching over the "parallel universe" style of branching, so my writing will generally come from this perspective. This is the approach used by most modern source control tools, including Vault, Subversion (they call it " copy"), Perforce (they call it " Inter-File Branching ") and Visual Studio Team System (looks like they call it branching in " path space ").
Under the Hood
Good source control tools are clever about how they manage the underlying storage issues of branching. For example, let us suppose that the source code tree for UltraHello is stored in $/projects/Hello/trunk. This folder contains everything necessary to do a complete build of the shipping product, so there are quite a few subfolders and several hundred files in there.
Now that you need to go forward with 1.0 maintenance and 2.0 development simultaneously, it is time to create a branch. So you create a folder called $/projects/Hello/branches. Inside there, you create a branch called 1.0.
At the moment right after the branch, the following two folders are exactly the same:
It appears that the source control tool has made an exact copy of everything in your source tree, but actually it hasn't. The repository database on disk has barely increased in size. Instead of duplicating the contents of every file, it has merely pointed the branch at the same contents as the