Overview of Branching, Merging, and Shelving
I'm Buck Hodges, a software developer on Team Foundation working on Source Control. I work on the client portion of Source Control, focusing primarily on the client object model and command line. With this post, I'll provide an overview of what we offer for branching, merging, and shelving, which is a feature unique to Team Foundation Source Control.
Branching
Branching plays a key role in software configuration management (SCM) for producing builds and releases that can be maintained in an orderly manner. In Team Foundation Source Control, we branch in "path space," which means that it is very much like copying items in that it creates new copies of the items. However, branching, unlike copying, maintains the history relating the source to the target to allow merging future changes.
By having branching create new copies, branches are easy to navigate. They appear in the Source Control Explorer just like the source items. It also makes it very easy to simultaneously work on as many branches of the same code base as you need -- just get it as you would any other folder.
When it comes to maintaining permissions for branches, it's as easy as setting permissions on any folder in the server, because branches are regular paths and use the same path-based permission access control. Open Source Control Explorer, navigate to the folder, right click on it, choose Properties from the popup menu, and click on the Security tab. From the command line, you can use the permissions command.
Creating branches uses very little additional storage space. The server minimizes the storage required by only keeping one copy of content no matter how many different files contain it. So, if you have 100 copies of a 1 MB file and all of the files are identical, the server will only store only 1 MB, not 100 MB. So, when you create a new branch and commit, all of the files in the new branch that are identical to the files in the branch source reference the same content. The result is that a branch consumes very little additional storage space, and that storage space expands only when the branched file becomes different than the source.
To create a branch, you can choose to branch by date, label, workspace version (i.e., the versions you last retrieved into your workspace), or latest server version. Furthermore, you can mix and match as you need. For example, you can branch based one folder based on a date and another folder based on the latest version of its items.
As with all changes in Team Foundation Source Control, changes exist only within the local workspace until they are committed to the server. This means that after branching if you need to edit files before checking them in, you can. You can also build and test the code in the branch to make sure it works properly. Once you are satisfied with it, you commit the entire set of changes to the server as a single changeset.
| Creating a Branch of the Latest Version of the Code |
 |
Merging
Once you have created a branch, moving changes from the branch source to the branch target or from the branch target back to the branch source is very easy. Team Foundation Source Control maintains the relationships of branched items and the merge history.
Merging across branches is more than just three-way file content merge. All the changes that have been made are merged, including additions, deletions, undeletions, and moves (renames). For example, if an item has been renamed from A to B, merging that change to another branch will also rename the corresponding item, using the branch and merge history, in the other branch.
For files where you have made changes to both the source and the target, merging the changes will result in conflicts. These conflicts are maintained by the server, and the client provides a dialog, both from the command line and Visual Studio, that shows the conflicts and leads you through resolving them. For each conflict, you choose whether to accept the source or target changes or a combination of them. If there are edits to the file, you can choose to have the changes merged for you automatically. If the edit changes cannot be merged automatically or you would like to manually merge the files, the conflict resolution dialog will launch a graphical three-way merge tool.
As I mentioned with branching, your merge becomes a set of pending changes that are contained within your workspace. You can make additional changes to the result of the merge, such as changing or moving files or fixing build issues, before committing the merged changes. The entire set of merged changes is committed atomically as a single changeset.
Once a merge has been committed to the server, it becomes part of the merge history of the items involved. The next time you need to merge a set of changes, Source Control will tell you what changes have not yet been merged. You don't have to keep track of the merges -- the system takes care of this for you. At any time, you can get this information from either the command line or from the Source Control Explorer in Visual Studio.
You can choose what changes you want to merge. You can choose to merge only a subset of the changes, so that, for example, you can merge a single bug fix without merging all of the changes that occurred before it. Knowing what change fixed a particular bug becomes simple with the integrated Work Item Tracking. When a developer checks in changes, he or she can associate or resolve work items. When the changes are checked in, a link is created between the work items and the changeset. So finding what changes need to be merged to propagate a bug fix simply requires clicking on the Links tab of the work item to find the changeset to merge.
We've made merging a painless process. Within Visual Studio, the Merge Wizard leads you through choosing what changes to merge, allowing you to merge every change since the last merge or to pick only particular changes. In the Source Control Explorer, simply go to the folder from which you want to merge changes (the source of a branch) and right click. Clicking the Merge item on the popup menu will bring up the merge wizard. The Merge Wizard knows what the possible targets are, so you simply select the target from a list (there's only one entry if you've only branched the folder once). Choose either to merge all changes or selected changes. If you choose selected changes, you will get a list of changes that haven't been merged. After selecting the changes to merge, click finish, and you will have merges pending for each file involved. Check in the merge when you are satisfied that it builds correctly. That's all it takes to merge changes.
| Merging Specific Changes | Selecting Changes not yet Merged | Finishing the Merge |
 |  |  |
Shelving
Shelving is a really useful feature that was included for the first time with the Dec. CTP. Shelving allows you to bundle your pending changes and store them on the server without checking them in, resulting in what we call a shelveset. The shelveset consists of the same kind of information that a changeset does. Shelving creates a space, the shelveset, on the server that is your own, containing your pending changes, comment, and associated work items. Creating shelvesets is fast and efficient.
When you shelve, you can choose to move your changes out of your workspace or you can keep your pending changes. Moving your changes to the server is great when you need to stop working on your current changes, make a targeted fix, check in that fix, and then unshelve what you were working on before being interrupted. Keeping your changes in your workspace is very useful when you want share a change (perhaps a fix for another developer prior to checkin) or have another person review your code changes. Finally, it's a great way to back up or checkpoint your changes.
Each developer can have as many shelvesets as needed. Other developers can see what shelvesets exist in the system. However, permissions for shelved changes are enforced according to the permissions for the items involved, so developers only have access to see the changes to the items to which they have permission.
To shelve your changes from Visual Studio, click on the Shelve button beside the Checkin button in the Pending Checkin tool window. To Unshelve, click on the Unshelve button beside the Shelve button in the same window. Clicking on Unshelve brings up a dialog that lists the available changesets and also allows you to specify a different user to his or her shelvesets. Double-clicking on a shelveset brings up a dialog that shows each change and allows you to compare the changes by right-clicking on a change (unfortunately, there is a bug in the Dec. CTP release that prevents this from working properly).
| Shelving and Unshelving in the Pending Checkin Tool Window | Shelving Changes |
 |  |
| Unshelving a Shelveset | Viewing the Contents of a Shelveset |
 |  |
Going Further
With the upcoming release of Beta 2, there will be more documentation and presentations on these features.
For examples and more discussion on branching and merging, see Branching and Merging in the Dec. CTP on my blog and Some More Merge Examples by Chris Rathjen.
For examples of using shelving from the command line, see How to use shelving from the command line.
Command line documentation is available online at http://blogs.msdn.com/buckh/category/9194.aspx. There you find the Command Line Reference and Command Line Summary documents.
Buck Hodges, software developer, Team Foundation