CVS reference guide for module maintainers

Last modified: September 7, 2009 - 23:24

This document contains a series of CVS command examples that project maintainers can use to maintain their projects. Note that this document covers modules, but themes, theme engines, and translations are essentially the same. If you have problems or questions, please review the CVS FAQ to see if your question is answered there.

NOTE: if you are new to CVS and how Drupal.org uses it, you should follow more detailed instructions for Starting a new project and to Manage a project. This document provides very little context and assumes you know what you are doing.

There is a video about creating a new release that shows some of the steps on this page, specifically it applies a patch, commits the change, tags the release and then makes a new release node.

Before you start

Before you get started, you really should understand some basic concepts about Revision Control Systems, of which CVS is one. Please read the CVS Introduction and make sure you have a basic understanding before proceeding, particularly pay attention to the concepts of branches and tags.

Take some time to figure out the directory structure for your module. Renaming files in CVS is hard, and moving around directories is really hard (without the help of the extremely busy CVS admins.) If you have your directories structured and files named how you want them before your first CVS commit, you will save yourself (and those busy admins) a ton of grief.

When your module is ready for release, you'll need to apply for a CVS account. Also, note that you will need to create your project page on drupal.org before you start working with CVS. Check the step-by-step guide to creating new projects for more information.

Basics

Logging in to CVS

if you have not already done so, make the contributions repository your CVSROOT. At the command line:

export CVSROOT=:pserver:cvs_username@cvs.drupal.org:/cvs/drupal-contrib

cvs_username will correspond to the username you requested when you applied for a Drupal CVS account.

Next, log into CVS:

cvs login

This will prompt you for your CVS password. Note that this is not necessarily the same as your drupal.org password!

Adding a new module to CVS

First, check out the modules directory from the HEAD version of the contributions repository:

cvs checkout -l contributions/modules

The -l parameter (for "local") tells CVS to only check out the given directory, not all of the directories underneath it.

Next, copy your module files into the contributions/modules directory.

cd contributions/modules
cp -r ~/drupal/modules/example example

Finally, add your files to CVS.

cvs add example
cvs add example/*
cvs commit -m "Initial commit of example module. Here is a brief description of what this module does."

NOTE: The cvs add command tells CVS that you want to add files to the repository, and it does not add directories recursively. If you have subdirectories then you will need to add each directory as above e.g cvs add example/subdir/*. The cvs commit command is used to commit your changes (in this case, the files you told CVS you wanted to add) to the repository, and the -m parameter is the "commit message", which tells people what changes you made to the repository and why. There is documentation on the commit messages handbook page on how to format CVS commit messages.

Saving changes to your module

Bugs and features are tracked in your project's issue queue. It is customary in the commit message to reference the node ID of the issue where the bug/feature request was raised, and mention any contributors who helped with the code. After making the changes in your local repository, you need to commit them to the CVS repository:

cvs commit -m "#12345 by username: Brief description of changes."

Obtaining latest changes

Both before you begin editing and before you save your changes, it's a good idea to grab the latest changes from CVS with the update command:

cvs update -dP

The cvs update command updates your local copy to the current state of the repository, and you can run it from the top level of your local copy, or any sub-directory to update only that sub-directory. The -d option ensures that you get new sub-directories that might have appeared, and the -P option "prunes" (removes) empty directories.

Removing files from CVS

While you cannot remove existing releases or actually remove files from CVS, it is possible to remove files from a branch. Sometimes a newer version of a module doesn't require a certain file anymore. If this file is foo.bar.inc, you need the following command to remove it:

cvs remove foo.bar.inc
cvs commit -m "some sort of a message as to why you removed the file"

Like cvs add, cvs remove tells CVS you want to remove the file, and it isn't actually removed until the cvs commit.

Branching and tagging

CVS allows you to keep different versions of your code active on different branches, and to tag different versions of your code. Drupal modules use CVS branches and tags in very specific ways, which are described fully on other pages:

The sections below cover the CVS commands used for branching and tagging, and assume you have already figured out why you are branching and tagging, and what branch/tag ID you want to use.

Before branching or tagging

If you have just made the initial commit to a new module, you should have created a project on drupal.org before you started. If you didn't, do that now, before before proceeding with creating a branch or tag.

Before you enter the command to create a tag or branch, verify that the directory you're about to tag has the correct version of your code in it, that the code has been committed, and if you are tagging, that you are on the correct branch. In order to create a new branch, first change to the HEAD branch, and create your new branch as a copy of the HEAD branch, as shown in the examples below.

Branching for a specific Drupal core version

Branching indicates the code's compatibility with Drupal core. For more information on when to branch and why, read the overview of contributions branches and tags documentation.

For example, if you want to create a branch called "DRUPAL-6--1", you would use the following commands (after making sure you have the correct starting code committed and checked out):

cd contributions
cvs tag -b DRUPAL-6--1 modules/example

The cvs tag -b command creates a branch, and is followed by the name of the branch you want to create.

Once you have created the branch, assuming you now want to work with that branch (modify code and check code in), you need to switch your local repository to using that branch. To do that:

cd contributions/modules/example
cvs update -dP -r DRUPAL-6--1

Only run that from within your module's directory (example, here), or it will start downloading files for everything with that branch.

The -r option to cvs update tells CVS to update your repository to that particular branch, and to keep using that branch until you tell CVS to update to a different branch.

You can check which branch you are currently using by issuing a status command:

cvs status

Look on each file for "Sticky Tag:" to be, in this example, DRUPAL-6--1 (followed by a CVS internal branch number) rather than "Sticky Tag: (none)" for HEAD.

Status will also tell you if you have changed anything that has not yet been committed to the repository.

You can go back to using the HEAD branch by issuing this command:

cvs update -A

The -A flag tells CVS to reset to using no particular branch (i.e. HEAD), and to update the code to whatever is checked in on the HEAD branch.

Also, you may find it helpful to keep one local directory pointing to the HEAD branch, and other local directories pointing to each of your other branches. That way, you can have copies of each branch available at all times. To create a new local directory on a particular branch, use the CVS checkout (co) command:

cvs co -d new_local_directory_name -r DRUPAL-6--1 contributions/modules/module_name

The -d flag tells CVS to create a new directory with the given name; the -r command tells CVS which branch to check out.

Creating an official release

Once your module is stable, it's time to create an official release for it. Just as Drupal comes out with 5.0, 5.1, and such, you can (and should!) do this with your module. You do that by tagging your code.

Assuming you are already using the correct branch (see above), and that all of your changes have been committed, you can tag your code with DRUPAL-6--1-0 (the correct tag for the 6.x-1.0 release) with the following commands:

cd contributions/modules/example
cvs tag DRUPAL-6--1-0

The cvs tag command tags all of the files in your project as belonging to a particular release. Note that you can tag a release as a "beta" by adding a suffix to the tag. For example:

cvs tag DRUPAL-6--1-2-BETA1

After tagging the module for your release, you also need to create a release node for it, so that it shows up in the list of downloads on your project page on drupal.org.

Note that normally, releases should only be made after major bug fixes or security patches; not for minor bugs like whitespace fixes, small text fixes, and so on.

NOTE: If you find a security bug, please report the vulnerability to the Security team and do not commit fixes for the security vulnerability until told to do so by the security team. This gives the security team time to send an announcement out via the security newsletter and to make sure that the proposed fix for the bug actually fixes the security vulnerability.

Branching for new development versions of your module

Once a stable release of a module is created, you may want to continue to add features, leaving the original release of your module intact.

To create a branch for a new major version of your module (for example, version 2.0 of the Drupal 6.0 compatible version of your module), use the following commands:

cd contributions/modules/example
# Always branch from HEAD to avoid file versions like 1.133.2.14.2.10.
cvs update -A
cvs tag -b DRUPAL-6--2

Eventually, when version 2.0 is ready to be released you would tag the 2.0 version using the following commands:

cd contributions/modules/example
cvs update -dP -r DRUPAL-6--2
cvs tag DRUPAL-6--2-0

You may want to edit your project node and click the 'releases' subtab and bump the major release also.

Creating a development snapshot release of your module

In order to allow people to test your module while it is in development, you may wish to make a development snapshot. This will create a "dev" snapshot which will always point to the newest version of the module in a particular branch.

To do so, make sure that the module is branched for the appropriate Drupal core version, and then create a release node pointing to that branch, rather than a specific release tag.

Note: Developer snapshots are only generated 2 times per day.

Deleting a tag

Note that it's a very bad idea to delete a branch once you have started committing changes to it.

Release nodes on drupal.org are typically never deleted. For more info about this please read the handbook page on Fixing releases. If you believe that it really is necessary to delete a release node, please submit an issue to the drupal.org webmasters queue, and one of the site maintainers will be able to delete the release node from drupal.org, but only if there is a very good reason for it.

In the event that there is a drupal.org release node pointing to the tag or branch you're trying to delete, CVS will display an error when you attempt to run these commands. You will need to first get the release deleted by filing an issue as indicated above, then delete the tag or branch; then create the tag or branch, and then re-create the release.

To delete a tag that was created in error, use the command:

cvs tag -d DRUPAL-5--1-0

If you need to delete a branch that was created in error, use the command:

cvs tag -dB DRUPAL-5

Saving changes to multiple branches

When you commit bug fixes, if they span more than one version, they need to be committed to each affected branch.

So for example, if you have a 4.7.x-1.x and 4.7.x-2.x and 5.x-1.x version of your module, changes that affect both the 4.7.x and 5.x versions need to be committed to the DRUPAL-4-7, DRUPAL-4-7--2, and DRUPAL-5 branches.

Script

konsumer - March 14, 2008 - 19:13

I made a little bash script to create new CVS projects, according to the instructions on this page (using find instead of dir/*, for recursion).

Put it in your path, as some shortname like "dcvs" or something, and you can type dcvs mymodule to create a new module named mymodule in a dir called mymodule.

It works for me on linux:

#!/bin/bash

# this is a quick drupal project CVS importer.

# you can override USER variable here, if it's not the same as the one on drupal.org
# USER="whatever"

# default type of project
TYPE=modules

if [ -z "$1" ];then
  echo "usage: $0 dir [type] [username]"
  echo
  echo "dir: the directory to import"
  echo "type: should be modules, profile, themes, etc : defaults to $TYPE"
  echo "username: defaults to $USER"
  echo
  exit 1
fi

# on ubuntu, I had to run sudo apt-get install realpath
IMPORT_DIR=`realpath $1`

if [ -n "$2" ];then
  TYPE=$2
fi

if [ -n "$3" ];then
  USER=$3
fi

export CVSROOT=":pserver:$USER@cvs.drupal.org:/cvs/drupal-contrib"
cvs login
cvs checkout -l "contributions/$TYPE"

cd "contributions/$TYPE"
cp -r "$IMPORT_DIR" .

NAME=`basename "$IMPORT_DIR"`

cvs add "$NAME"
find "$NAME" -name '*' -exec 'cvs add {}' \;
cvs commit

Also useful to know is how

Liam McDermott - March 19, 2008 - 15:50

Also useful to know is how to get from one branch back to HEAD. I spent hours trying to work this out, it's actually simple, see Derek's comment on cvs update -A.

----
Web Design, GNU/Linux and Drupal.

separate folders for separate branches

davidwhthomas - June 2, 2008 - 01:29

Note, if you're developing module versions for different Drupal versions (e.g D5 and D6), keep each module branch version in a separate cvs checkout folder.

Making a tag point to a different version of a file

alpha2zee - June 13, 2008 - 01:01

To get a tag to point to a different revision (version) of a file, use:

cvs tag -r new_revision_number -F tag_name file_name

New-line/line-break encoding auto-converts depending on OS

alpha2zee - August 4, 2008 - 01:03

I use the native CVS command-line tool on Windows. Any file downloaded from Drupal's CVS repository gets the Windows/DOS-type line-endings. After locally editing and then updating the file on the repository using CVS, the line-endings seem to be back to the original Unix-type. That is, there seems to be no need to manually edit the file on Windows to make the line-endings Unix-type. This might be helpful to new CVS users.

"Show snapshot release"

Frank Ralf - September 16, 2008 - 10:30

If you are creating a snapshot release as described above, you might have to go to "Administer releases" and mark the option "Show snapshot release" for the snapshot to show in the module's release list.

Thank you! I couldn't figure

mattyoung - July 10, 2009 - 17:32

Thank you!

I couldn't figure out why no snapshot release show up on my project page until I see this! I bet a lot of people get confuse by this. Why is the default not "Show snapshot release"? If you are making a snapshot release, you want people to test it.

Let me put this here so hopefully google search finds this page:

Drupal module maintainer how to create snapshot development release:

must go to "Administer releases" and select "Show snapshot release"

Whoever can edit this page, please go to http://drupal.org/handbook/cvs/quickstart#release-dev

and add this important missing info, please!

Bringing back files from the dead

egfrith - November 19, 2008 - 14:54

I've just encountered a situation where some files had been removed from HEAD but were still in the branches. This means that when you check out HEAD, the files are not there, though they are in the branches.

In the world of CVS, their state was "dead" (as evident from the output of cvs log). Dead files are stored in the "Attic", also seen in the output of cvs log. (I really think that skeletons ought to be kept in cupboards, but never mind.)

Anyway, to get them back, the following worked:

1. Find out the latest revision in HEAD of the dead file by looking at the output of cvs log
2. Extract this revision (e.g. 1.1) from the repository:

cvs -Q update -p -r 1.1 example.module > example.module

3. Verify that example.module is there
4. Add it to the repository:
cvs add example.module

5. Commit it:
cvs commit -m "Brought file back from dead" example.module

Please could someone add the

joachim - February 18, 2009 - 10:48

Please could someone add the command for checking out a module from contrib as a non-anon user, getting a given branch? This would be useful for CVS account holders who are invited to maintain other projects.

I've been using:cvs co -d

Liam McDermott - February 18, 2009 - 16:13

I've been using:

cvs co -d module_name -r DRUPAL-6--1 contributions/modules/module_name

-d is the directory to check out to.
-r is the branch/tag to check out.
and the contributions/modules/module_name bit is the location in the Drupal CVS repo.

I use this all the time to maintain sites using CVS. Am not sure this is the right page for it though, or that it isn't in the documentation here (am pretty sure I gleaned it from somewhere).

----
Web Design, GNU/Linux and Drupal.

Conflicting and confusing directions

Chris Johnson - February 19, 2009 - 16:31

This page has conflicting and confusing directions. Immediately beneath the major heading for "Branching and tagging" there are 3 poorly written paragraphs talking about only doing branching from MAIN (first reference I've seen to MAIN -- it seems to be the same as HEAD). Later on, the examples talk about, and show, branching from existing branches, not MAIN.

Which is correct?

Exporting all files except CVS related

Michelle - May 30, 2009 - 03:01

Webchick just helped me with this on IRC and wanted me to add it to the docs but I can't tell where it would go. Putting it in a comment for now. If you need to make one branch match another (like updating HEAD before branching), you can use this command to get a directory with all your project's files except the CVS directories and contents:

cvs -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib export -r DRUPAL-6--1 contributions/modules/MODULE_DIRECTORY

Then you copy the contents of that over the top of the branch you want to sync up, do any cvs adding / deleting, and commit.

Michelle

---
I'm looking for folks to help me out by posting in my Coulee Region forums. You don't need to live in the area; there's plenty of general forums. But please, no Drupal support questions. :)

Guide if using GUI CVS

liquidcms - September 11, 2009 - 16:16

Sure would be nice if someone could post how to do this using TortoiseCVS as most/many developers are likely using Windows and not command line based CVS.

help!!

liquidcms - September 11, 2009 - 16:36

using TortoiseSVN, and trying to follow "branch after intially committing code and adding project page" instructions above, i do this:

- from my local contributions/modules folder i right click my checked out module 'published'
- select to create branch
- enter DRUPAL-5--1 and create new branch

i get following error:

(x86)\CVSNT\cvs.exe" -q tag -c -b DRUPAL-5--1
CVSROOT=:pserver:ptalindstrom@cvs.drupal.org:/cvs/drupal-contrib

** ERROR: invalid branch for this directory:
** contributions/modules/published

any ideas?

a little trial and error

liquidcms - September 11, 2009 - 16:38

but for some reason if i use DRUPAL-5 with above, that works.

doesn't seem to match with these instructions too well.

 
 

Drupal is a registered trademark of Dries Buytaert.