Lullabot Ideas
We know stuff. We empower you to know stuff too.
CVS Annotate, or "What the heck were they thinking?"
Article by Angie ByronJune 13, 2007 - 2:15am
CVS Annotate? What's this, then?
Ever wanted to get into a developer's head, to figure out why they made a certain change to the code? Ever tracked down a particularly pesky bug, and want to know where point that look of scorn? If so, the cvs annotate command is just what you've been looking for!
The cvs annotate command (and its sister, svn blame) is the "tattle-tale" of the development world. For every single line of code in a file, it will tell you:
- Who was the last person who touched it?
- What date was it last changed?
- In what precise version of the file was it last changed?
Like so:
1.85 (dries 22-Jun-05): require_once './includes/bootstrap.inc'; 1.86 (dries 23-Jul-05): drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); 1.67 (dries 28-Sep-03): 1.83 (dries 24-Apr-05): $return = menu_execute_active_handler(); 1.91 (unconed 12-Dec-06):
Sound handy? It sure is! And you don't even need to be a command-line geek to benefit!
For example...
Right now, Drupal 6.x-dev spits out a fatal error if the database connection fails:
Fatal error: Call to undefined function file_directory_path() in /Applications/MAMP/htdocs/head/includes/common.inc on line 1769Darn you, line 1769! Why must you mock me so?!
So I know this had to be introduced at some point relatively recently, since in 5.x, this would give me a nice "Could not connect to database" message, themed with the lovely, smiling Druplicon. Let's take a closer look.
CVS annotate - command-line version
Bring up a command prompt and punch in the following:
$ cvs annotate includes/common.inc > blame.txt
$ vim blame.txt # or pico, if you're like a total wuss. ;)I redirect this to a file because this sucker is loonnng.
If I head down to line 1769, I see:
1.649 (unconed 01-Jun-07): $directory = file_directory_path();
Ah-HA! So now I can blame Steven. ;) Let's see what was actually done during that commit:
$ cvs log -r1.649 -N includes/common.inc (-r1.649 limits the list of log messages to only that revision, and -N stops it from printing a huge list of tags. See the manual for additional cvs log options.)
The output of this command is:
(snip a bunch of unrelated stuff)
#119441: JavaScript aggregator/compressor by m3avrck and others.Since the #number corresponds to a node ID on drupal.org, I now know that this bug originated from the JS aggregation patch, and I also know that I should harras Ted next time I see him, and not Steven. ;)
CVS annotate - web version
It's also possible to use the power of this command without using CVS at all! Drupal.org provides a handy web-based CVS browser and you can use the same technique with it.
- Browse to includes/common.inc to view a list of log messages for that file. (incidentally, you can use the "Sticky tag" drop-down at the bottom to view previous versions of the files [DRUPAL-5 = Drupal 5, DRUPAL-4-7 = Drupal 4.7...])
- Click the annotate link next to the first revision in the list.
- Hit Ctrl/Cmd+F to use your browser's search to find the line in question (1769). This will show you output like the following:

As you can see, this still has the same information as the command-line version, just is laid out a bit differently.
- Take note of the revision number (1.649). Incidentally, you can click that number to get a "diff" of the changes that were made during that commit.
- Go back to the top and click Revision log to go back to the initial screen showing all the commit messages.
- You should be automatically skipped down to the place where that change was introduced. And here you go, the same result as we discovered in the command-line version:
- Head over to the referenced issue and read up on why the change happened for hints on how to fix it.
So there you have it!
Two ways to get at some really useful information for whatever ails you!
About this 'bot
Angela Byron is the Drupal 7 core maintainer, recipient of the Google-O'Reilly Open 2008 Source Award for Best Contributor, and an Open Source evangelist who lives and breathes Drupal. She got her start as a Google Summer of Code student in 2005 and since then...

Comments
Nano!
It's nano, not pico... and yes, I'm a total wuss. :-)
Darn you, line 1769! Why
Too funny, now I won't be able to see an error message without cursing the line number for a week.
Why not ask
Looks a little bit like a workaround for asking to me. Why not just ask Steven what he had in mind when changing the code? But anyway, good demo of the annotate feature!
Lots of reasons, really.
There's lots of reasons for taking a different approach than just asking:
Also, figuring out things for yourself can be fun – sometimes, at any rate :)