Posts from  April 2010


How I do VCS

After years of dabbling with different version control systems and techniques, I wanted to share some of what I like and dislike in a few blog posts. To start this out, I want to talk about how I use VCS in a team environment. These come in a series of tips or best practices that I try to follow.

Note: This list is subject to change in the future.

Note: I edited this to make it more friendly, I was too opinionated when I first wrote this.

  1. Always use some form of version control for all aspects of software development.
    1. Development is an evolution. Looking back at where we were is an invaluable asset in that process. This includes data schemas and documentation.
    2. Reverting / reapplying changes is absolutely critical for efficient development.
    3. The tools I use:
      1. Code: Hg (preferred), SVN
      2. Database: TSqlMigrations
      3. Documents: Sometimes in code repository, also SharePoint with versioning
  2. Always tag a commit (changeset) with comments
    1. This is a quick way to describe to someone else (or your future self) what the changeset entails.
    2. Be brief but courteous.
    3. One or two sentences about the task, not the actual changes.
    4. Use precommit hooks or setup the central repository to reject changes without comments.
  3. Link changesets to documentation
    1. If your project management system integrates with version control, or has a way to externally reference stories, tasks etc then leave a reference in the commit. This helps locate more information about the commit and/or related changesets.
    2. It’s best to have a precommit hook or system that requires this information, otherwise it’s easy to forget.
  4. Ability to work offline is required, including commits and history
    1. Yes this requires a DVCS locally but doesn’t require the central repository to be a DVCS. I prefer to use either Git or Hg but if it isn’t possible to migrate the central repository, it’s still possible for a developer to push / pull changes to that repository from a local Hg or Git repository.
  5. Never lock resources (files) in a central repository!
    1. We have great merge tools now, merging sucked a long time ago, it doesn’t anymore!
  6. Always review everything in your commit.

    1. Avoid committing without reviewing the changes in each file.
    2. If you leave to make changes during a review, start the review over when you come back. Never assume you didn’t touch a file, double check.
      1. This is another reason why you want to avoid large, infrequent commits.
    3. Requirements for tools
      1. Quickly show pending changes for the entire repository.
      2. Default action for a resource with pending changes is a diff.
      3. Pluggable diff & merge tool
      4. Produce a unified diff or a diff of all changes. This is helpful to bulk review changes instead of opening each file.
    4. The central repository is not your own personal dump yard.
    5. If you turn on Visual Studio’s commit on closing studio option, I will be very sad :(.
  7. Commit (integrate) to the central repository / branch frequently
    1. I try to do this before leaving each day, especially without a DVCS. One never knows when they might need to work from remote the following day.
  8. Never commit commented out code
    1. If it isn’t needed anymore, delete it!
    2. If you aren’t sure if it might be useful in the future, delete it!

      This is why we have history.

    3. If you don’t know why it’s commented out, figure it out and then either uncomment it or delete it.
  9. Don’t commit build artifacts, user preferences and temporary files.
    1. Build artifacts do not belong in VCS, everything in them is present in the code. (ie: bin*, obj*, .dll, .exe)
    2. User preferences are your settings, don't override other team member preference files! (ie: .suo and .user files)
    3. Most tools allow you to ignore certain files and Hg/Git allow you to version this as an ignore file. Set this up as a first step when creating a new repository!
  10. Be polite when merging unresolved conflicts.
    1. Count to 10, grab a stress ball and realize it’s not a big deal. Actually, it’s an opportunity to let you know that someone else is working in the same area and you might want to communicate with them.
    2. Following the other rules, especially committing frequently, will reduce the likelihood of this.
    3. Don’t blindly merge and commit your changes. Make sure you understand why the conflict occurred and which parts of the code you want to keep.
    4. Apply scrutiny when you commit a manual merge: review the diff!
    5. Make sure you test the changes (build and run automated tests)
  11. Become intimate with your version control system and the tools you use with it.
    1. Avoid trial and error as much as is possible, sit down and test the tool out, read some tutorials etc. Create test repositories and walk through common scenarios.
    2. Find the most efficient way to do your work. These tools will be used repetitively, so inefficiencies will add up. Sometimes this involves a mix of tools, both GUI and CLI.
      1. I like a combination of both Tortoise Hg and hg cli to get the job efficiently.
  12. Always tag releases
    1. Create a way to find a given release, whether this be in comments or an explicit tag / branch. This should be readily discoverable.
    2. Create release branches to patch bugs and then merge the changes back to other development branch(es).
  13. If using feature branches, strive for periodic integrations.
    1. Feature branches often cause forked code that becomes irreconcilable. Strive to re-integrate somewhat frequently with the branch this code will ultimately be merged into. This will avoid merge conflicts in the future.
    2. Feature branches are best when they are mutually exclusive of active development in other branches.
  14. Use and abuse local commits

    at least one per task in a story.
    1. This builds a trail of changes in your local repository that can be pushed to a central repository when the story is complete.
  15. Never commit a broken build or failing tests to the central repository.
    1. It’s ok for a local commit to break the build and/or tests. In fact, I encourage this if it helps group the changes more logically. This is one of the main reasons I got excited about DVCS, when I wanted more than one changeset for a set of pending changes but some files could be grouped into both changesets (like solution file / project file changes).
  16. Avoid committing sensitive information
    1. Especially usernames / passwords

There is one area I haven’t found a solution I like yet: versioning 3rd party libraries and/or code. I really dislike keeping any assemblies in the repository, but seems to be a common practice for external libraries. Please feel free to share your ideas about this below.