Keyword Substitution - Just say No!

2006-08-02, , Comments

Subversion supports keyword substitution — and has to, really, since it claims to be “a compelling replacement for CVS”.

Now, by default, when you import a text file into CVS, keyword substitution is enabled. And by default, when you use cvs2svn to convert your CVS repository into a Subversion repository these particular CVS settings are honoured, and keyword substitution properties are enabled. Out of the box, however, Subversion does not apply keyword substitution to text files. Yes, you can configure it to automatically turn keyword substitution on for certain file types, but by default, the file you check out is the same as the file you checked in.

Let’s repeat that: the file you check out is the same as the file you checked in. Surely this is the behaviour we really want from a version control system?

So, while Subversion does maintain backwards compatability with CVS, moving forwards, we should leave keyword substitution disabled. If you are migrating from CVS to Subversion, take the opportunity to use cvs2svn’s --keywords-off switch.

What Keyword Substitution Does

If a file has keyword substitution enabled, then tags within that file of the form $Id: $ will be expanded when the file is checked in. That is to say, they end up reading something like:

$Id: calc.c 148 2002-07-28 21:30:43Z sally $

which is interpreted to mean that the file calc.c was last changed in revision 148 on the evening of July 28, 2002 by the user sally.

Why Keyword Substitution is a Bad Idea

  1. Clearly, the substituted text duplicates information which properly belongs within the source control system. By enabling it, we introduce unnecessary differences in file comparisons.

  2. Keyword substitution modifies the file during check in, leading to a subsequent re-rebuild. Not good if lots of files depend on the file you’ve modified.

  3. When performing a diff/patch between source trees, it often happens that a patch will result in dozens of conflicts over the $Id:$ field alone, because the patch tool is not intelligent enough to ignore it.