Team Foundation Server and Team Foundation Version Control are brand new products, having just been released in the first quarter of 2006. As such, there is not a lot of best practice information built up around them. This section of the chapter attempts to outline what the authors believe to be some good ways to use Team Foundation Version Control. Some of the points presented here hold true regardless of the version control system you are using. You should take the following information and build off it to develop the best practices that work best for you and your organization.
Regardless of what you are developing, you want to have a copy of your code that will always compile, allowing you to create a product release of your code. This copy is referred to by Vincent Maraia in The Build Masters as the mainline, or trunk. The purpose of the trunk is to make it easy to create a release of your product. As such, no code is merged or added to the trunk until you are sure it compiles and passes any appropriate tests. This ensures the trunk is always in pristine condition.
Always start a top-level folder underneath a new team project to serve as a mainline or trunk. Create a folder called main, and put all the source code for the main branch in this folder. When a new branch needs to be created, you can branch from the main folder directly.
Always use the shared check-out model. This model allows you to make the most efficient use of the source files and your team. You will not have developers waiting to check out files to make changes, allowing more work to be completed in a shorter length of time.
If you have source files checked out for a long period, do not just try to check them back into the repository when you are done. Depending on how long you have had the files checked out into your workspace, there may be many changes that have taken place in the repository. As such, it may be difficult to check your code back in, due to all the conflicts. Instead, while you are working on your code, periodically get the latest code from the repository and merge it into your workspace. This allows you to make sure the changes you are making will play nice with the other changes that have taken place in the repository. That way, when you do finally check your changes back into the repository, you have already resolved most of the conflicts, making the check-in process relatively painless.
This leads to the next point, which is never check code into the repository unless it compiles and is ready for consumption by other members of the team. Remember, you want to have a trunk of code in the repository that you can ensure will always compile.
When you check in your code to the repository, you should always associate it with a work item, so you can track why the change was made and what the changes addresses. However, you should only associate one work item per check-in. Do not associate multiple work items with a check-in, as this makes it difficult to determine what code changes go with what work item.
Finally, even though you can, don't override a check-in policy unless you really have to! Check-in policies exist not to make your life difficult, but to ensure that code changes meet certain requirements, to ensure the reliability of the repository. When you override a check-in policy, you potentially introduce instability into the system, such as causing a build to break. If you need to stop working on a project for a while, or want to make sure your files are backed up on the server nightly, use shelving instead.
The following bullet points are some branching and merging best practices:
You should merge frequently. Whether you are merging the latest changes from the repository into your workspace, or vice versa, you should do this often to ensure compatibility between changes. As well, you should do full merges instead of cherry-pick merges. This will simplify the merge process as a whole.
When you perform a merge, make sure you always check that merge in completely before you perform another merge. Otherwise, things can become confusing.
Always build and run tests after performing a merge, but before you check the merge into the repository. This ensures that you have tested the merges, to make sure nothing is broken. Remember, you never want to perform a check-in of code that will not build or pass its tests. Also, when renames are part of a merge, pay particular attention to the path the tool recommends for the renames, and make changes as appropriate.
Branching and merging tie into a concept called promotion modeling. Promotion modeling is a strategy where you maintain your source code at various levels of readiness. For example, your developers will always be working on the latest version of the source files, which might be relatively unstable, while the testers are looking at the latest version of the stable code. Using promotion modeling, once the developers have stabilized their code and are ready for the testers to look at it, they move it, or promote it, into an area where the testers can take advantage of the new code.
With Team Foundation Version Control, if you are going to use promotion modeling, you need to establish a branch for every promotion level. For example, you might have a development branch, a test branch, and a production branch in your team project. When code is checked into the development branch, and is ready to be promoted to the test branch, you simply merge the development branch changes into the test branch. This promotes the files, allowing the testers to have access to the new code. Then, when the testers are satisfied, they can promote the code to the production branch. The moral of this story is to use branching and merging to establish your promotion model scenario.
Remember, you are always going to have your main trunk, which is your pristine copy of your code. The trunk is always supposed to compile. All changes will ultimately be merged into the trunk.
You should always shelve your code before you quit working. That ensures your latest changes are backed up when the Team Foundation Server is backed up. Moreover, never check in code that does not compile or pass your tests. If you need to put it back on the server for some reason, shelve it.
You should also use shelving to conduct peer code reviews. This provides an easy way for other developers to look at your code from their own workstations.