Hey guys,
In terms of categorizing SCM products, Team Foundation Server fits more into the branch/merge mold than it does the stream mold.
That said, there are some interesting things about using a stream-based approach that we could leverage in Team Foundation Server.
Recall from my first post that there are numerous, numerous ways to do stream-based SCM. To try and narrow our scope a bit, let's just concentrate on the branch-on-task flavor of this a stream-based approach.
With TFS, you typically wouldn't branch-on-task. What you would typically do is make your changes - either in the mainline or a integration branch - and check them in. During the check-in, you would associate a work item with it.
With branch on task, you create a branch for the task you are working on (or the product you are using does this for you) and you make your changes. Once you are satisfied with your work, you merge it into an integration branch, which in turn will eventually merge into a mainline. Some products like AccuRev enable you to cascade your changes into other streams.
There are advantages and disadvantages to both approaches; I don't want to go too far towards a full comparison between these two. There is a very good discussion on the topic at CM Crossroads by folks who are far more qualified than myself :)
What I'd like to do is just explore what a branch-on-task approach might look like in Team Foundation Server. It might not work for everyone - or anyone :) - but I thought it is worth some experimentation.
Looking the Source Control Explorer, suppose that we have a project called Captcha as shown below.
Now let's say that we want to setup a branch-on-task model with this project.
The first thing we could do is set up an integration branch, this is where the changes are collected before they are integrated into our mainline. The Captcha project shown above effectively becomes our mainline.
So, we would create a branch as shown.
Now our structure looks as shown.
Since we are going to branch-on-task, we are going to end up with a lot of branches. Team Foundation Server is going to show us all the branches we have; so we need a bit of organization or things will get very confusing.
Let's setup a folder to hold all of our branches that are associated with tasks.
The toolbar button indicated below enables you to create a new folder manually; we will call our Development Team.
Now, inside of our development team folder, we will create a folder for each developer that we have. This is something we would have to do when a developer joins the team.
So let's just say I'm the lone developer, now we have.
OK, now we're ready to take on tasks. Suppose that we have the following bugs assigned to us (double-click the image to see if full size)
Let's follow branch-on-task strictly; that means we need to create a branch for each bug we are working on. Let's decide to start working on bug #2273 first.
So we create a branch of the Captcha_Integration (or mainline) into our development team work area.
Note the location of the branch - it is under development team\ericlee. We don't have to decorate the branch with _Bug_2273 if we don't want to; we can just associate a work item when we check-in the branch.
Each developer would be responsible for making a branch for the task they are working on. There is no specific branching privilege in Team Foundation Server, so any developer who can check-in changes can make a branch.
Our branch isn't 'real' until we check-in; so let's do that. When we check-in, we will also associate bug #2273 with it. We won't resolve the bug, since we haven't done anything yet to try and fix it, we are just associating the bug with our branch operation so we have a record that tells us why we created this branch in the first place.
Doing this work item association creates a link between the change set that committed our branch and the work item.
Now our structure looks as shown.
In theory, a project manager could query for work items that are still active, with a link to a changset where the operation was a branch and come up with a result that was reasonably close to what tasks were being actively worked on.
Once the actual bug was fixed, the final check-in for that fix would resolve the bug we originally associate the branch operation with. So bug #2273 ends up with 2 links to changesets.
Then, it is just a matter of merging the changeset from the task-branch into the integration stream.
A project manager or integrator would be responsible for merging changes from the integration stream into the mainline.
The branch-on-task approach has its benefits.
- Task-branches allow for interim check-ins. Suppose that a given task requires a fair bit of work, a developer can check-in, revert and even branch within their task-branch. You could do some of these same things with shelvesets, but I think that might become problematic if things got complicated.
- Having an isolated task-branch also makes it easier to transfer work from one developer to another. In our example above, suppose that I want to transfer the work that I've done for bug #2273 to another developer named 'darren'. I could just use the move operation to move my task into his folder as shown below.
- Task-Branches help project managers determine what tasks are actually being worked on, as opposed to just being assigned. You could go as far as seeing what kind of activity (i.e. number of check-ins, etc) that each task-branch was receiving.
This approach, implemented in Team Foundation Server - certainly has its drawbacks well.
- Branches freak some people out; especially if you are coming from a VSS background, you may not feel comfortable having so many branches.
- Branches means merges; the reality is that merging introduces some risk. It's arguably not riskier than coding, but it certainly something where errors can be introduced.
- There is a fair bit of meta data to keep in mind; there is nothing in Team Foundation Server that prevents you from creating a branch where you are not supposed to. That being the case, developers will have to know that they are supposed to create their task-branches in the right place.
I've never used an approach like this with Team Foundation Server in real-life, so I'm not sure how it would hold up. But, I thought it might be a good mental exercise to see what a branch-on-task model might look like in Team Foundation Server. There are still many things that need to be thought out; namely, what do you do with the task-branch after the task is done? Maybe you could delete it? Or maybe you could move it?
I certainly hope I don't stir up a religious debate over branch/merges versus streams; that is not my intention. I think there are some interesting things that you get from using a streams-based approach so I thought I would try and see if I could bring them over to Team Foundation Server. Hope it was at least an interesting read :)
As always, feedback and comments are appreciated. If there is interest shown, I would definitely like to refine this model over time.
Thanks,
Eric.