What you need to know about your version control system
Here's the picture: you have introduced a version control system such as Subversion or Git in your organization, and your programmers store their code in it and integrate the changesets of other in their work, using commands like svn add, svn up and svn commit. This is really a no-brainer: the Joel Test requires a version control system to be in place, and most of us would never work without.
After having taught the benefits of source control to the growing programmers in your workplace, the next question to ask yourself is: are we sure we're taking full advantage of the power of our shiny new system?
For example, yesterday a colleague of mine attached a patch to an email in our private mailing list. Events like this happen, but since we are recently switched to Git over Subversion, an upgrade which is not common in enterprises, this made me wonder if there was a better way to manage this hanging code.
It turns out there is: Git has very cheap branching and a private feature branch would solve the problem, even if the changeset sent initially via email break the build. It's perfectly acceptable to break a branch during development: the issue is that with Subversion we were discouraged from creating a branch, due to the slowness of the operation and the pain of subsequent merging.
Thus, here are a set of questions that should make you think about your version control policies and standards, a sort of version control subsection of the Joel Test. Feel free to add your rethorical questions and answers with your Subversion or Git gotchas: by no means this is a complete list (I'm always open to learn), but if you already know all the described practices, you're definitely in the upper segment of the programmers population.
Do you tag?
Tags are read-only copies of your trunk, placed in the /tags folder of the repository. Creating tags for each release is mandatory: the alternative is writing down the revision number of the trunk at the time of the release. Tag have nice names instead, and everyone looking for your releases will instantly open /tags.
Do you ever branch for a major or minor release?
Subversion branches are whole lazy-copied duplicates of your trunk placed under the /branches directory of the repository. These branches are somewhat heavier to create than in the case of distributed VCS, but you really have no excuse for not managing a release branch.
Branches named 1.2 or 1.6 remain available for further bugfixing, or can be referred to by svn:externals properties. They're not normally merged back into trunk, which removes the pain of svn merge. I suggest having one branch for each line of development you support - for example the Doctrine ORM, when managed via Subversion, had the 1.0, 1.1 and 1.2 and 2.0 branches, with the first two slowly moving to an halt.
Do you ever send code via email?
All the non-illustrative code should be kept in the system for it to work. If you can't (it breaks the build for example), at least trac or some wiki can be used for temporary storage.
Does your repository include everything you need for your application to be built and deployed?
Libraries, frameworks, tools, and everything the application depends on must be included in the repository, either via svn:externals or via a periodical import. A frssh checkout on a new machine shouldn't take you more than a minute of configuration before you are able to run the test suite.
Do you use svn revert?
When you make a mistake, or insert print statements, don't waste time removing them one by one: svn diff and svn revert [-R] are at your service for resetting the working copy changeset.
Do you setup svn:externals?
Dependencies towards a component stored in a public Subversion repository (typically an open source project) can be pulled in via the svn:externals property. You'll remove a lot of code from your repository and you'll be sure that the vendore code is never modified, even slightly.
Do you write meaningful commit messages?
Needless to say, commit messages are a mean to tell information that is not already included in the commit log: there is no need to link the interested files, but surely the methods you have added or modified are a good target.
Most of the questions (And answers) are still valid if you have transitioned to Git. But given the versatility of Git, even more questions come to mind.
Do you branch before developing a feature?
Branching is very cheap in Git, taking only seconds and a handful of bytes on disk. There is no reason to avoid using git branch (of if you prefer git checkout -b) for every single feature that takes more than one day to complete.
Do you commit very often?
One of the advantages of Git over Subversion is that commits are local, and until git push is run, they do not affect the origin repository. You can commit every time you want.
Do you favor atomic and short commits?
Small and cohesive commits are easily revertable, and can be harnessed to generate a change log. Read git diff and git status and never forget to commit a green bar if it contains an advancement over HEAD.
Do you use the index?
One of Git's most enviable features is its index, which allows you to select the single filed and directories you want to include in a commit. Basically, unless you execute git add, a created or modified file won't be committed. This leaves open the possibility of atomic commits even if you have already modified too much files. You can reset the index (but not your modifications) by running git reset (which by defaults is --mixed.)
Do you send patches via email?
The whole point of version control systems is to maintain all the code in one place, and provide a management system over it. While with centralized VCS code is sometimes kept out of the loop, you have no excuses while using Git (or Mercurial): creating a simple branch with your modifications and push it is a matter of seconds.
In the open source world, Github has substituted the need for uploading patches into a bug tracker, leaving it available only for discussions between humans. You can post code in the repository too, for ease of merging.
Do you use Git for local folders or projects or just when you need to publish code?
There is no need for an external repository, only of an hidden .git folder inside your main code directory: versioning /etc is becoming a common practice. You can version your personal projects with an overhead of two commands and be covered for httpd.conf simplifications that surprisingly break the web server.
Do you use reset --hard and checkout?
git reset --hard will take you to the situation, throwing away all the modifications (like svn revert -R .). git checkout $file will extract the single $file overwriting the current working copy one with its original content from HEAD.
Do you run commands from wherever in the repository?
The majority of git commands, such as git status, git reset and git commit, act by default on the whole working copy, even if you run it from an obscure tests/Zend/Filter subfolder. This prevents incomplete commits: for instance, the ones where you commit only tests/ without the relative production code. It's also faster than relocating to the main directory if you don't need it.
Do you use git log to filter commits or only HEAD^^ or HEAD~5?
git log executed on a file or folder shows the commits that have affected it. You can then generate a diff by using the first 4-6 characters of the commit hash, as long as they are unique (for example, git diff 39446 3ad42 to generate the diff between 394469d4b7b9d9442ab15fdd0e4e81c186cd2fc5 and 3ad429a5aac5a5090e0c9e6e316e0225e0edb9b0).
Do you use colors?
git config --global color.ui auto will set all the options for colorizing git's output, with red and green colors included in diff generation and index visualization (git status). It's quite helpful, like xUnit colored bars.
I hope you're already learning as much as possible on your version control system, which is one of the best friends a developer has, beside his pairing partners. Mastering the single commands leads to an improved workflow, and a facility of usage that will give you the confidence to do the right thing even when the command seems a little scary at first.