Posted by Benjamin Close on November 7, 2008 under Programming | Be the First to Comment

This page contains various helpful hints for using CVS.



Importing To a NEW Vendor Branch

This directory contains virgin sources of the original distribution files on a “vendor” branch. Do not, under any circumstances, attempt to upgrade the files in this directory via patches and a cvs commit. New versions or official-patch versions must be imported. Please remember to import with “-ko” to prevent CVS from corrupting any vendor RCS Ids.

To upgrade to a newer version of a project, when it is available:

  1. Unpack the new version into an empty directory.

[Do not make ANY changes to the files.]

  • Remove the any files that don’t apply to this project
  • 3. Use the command:
 cvs import -ko -m 'Virgin import of Project v<version>' www/share/contrib/project VENDOR project_<version>
  • Follow the instructions printed out in step 3 to resolve any conflicts between local changes and the newer version.

Do not, under any circumstances, deviate from this procedure.

To make local changes to cpio, simply patch and commit to the main branch (aka HEAD). Never make local changes on them VENDOR branch.

All local changes should be submitted back to the maintainer of the project for inclusion in the next vendor release.

Importing to an EXISTING Vendor Branch

This text is taken from: Many thanks to the author as it has saved me lots of grief.

It is rare for third-party software to remain unchanged forever; updates are available (even on a regular basis).

An important part of managing third-party software is upgrading to a newer version in a sane way.

The process to import an updated version of a package is similar to importing the original package. However, because changes in the newer version may conflict with any local changes that you may have made to the product, there are a couple of steps that are different.

In this example, we’ll be upgrading dhcp 2.0b1 from pl18 to pl27.

In the directory containing the extracted source import the new version:

 % cvs import -m 'ISC dhcp 2.0b1pl27' net/dhcp ISC dhcp-2-0-b1-pl27
 U net/dhcp/CHANGES
 C net/dhcp/Makefile.conf
 U net/dhcp/server/dhcpd.leases.cat5
 1 conflicts created by this import.

Use the following command to help the merge:

 cvs checkout -jISC:yesterday -jISC net/dhcp

As you can see there was a conflict on the import (Makefile.conf; the file with the status character of “C”). This is CVS’s way of indicating that those files have been modified from the previous release of the vendor code. Checkout the updated source, automatically merging in any changes. Whether or not CVS suggests a checkout command, you should use a checkout of the form:

 cvs checkout -j old-release-tag -j new-release-tag module

old-release-tag is the previous release tag, and new-release-tag is the one just imported.

For this example the cvs command is:

 % cvs checkout -j dhcp-2-0-b1-pl18 -j dhcp-2-0-b1-pl27 net/dhcp
 U net/dhcp/CHANGES
 U net/dhcp/Makefile.conf
 RCS file: /src/cvsroot/net/dhcp/Makefile.conf,v
 retrieving revision
 retrieving revision
 Merging differences between and into Makefile.conf
 U net/dhcp/server/dhcpd.leases.cat5

The advantages of using checkout -j old-release-tag -j new-release-tag include:

  • files added or deleted by the vendor between releases are handled automatically, and
  • merges between changes are cleaner.

Remember; always use cvs checkout -j old-release-tag -j new-release-tag when checking out code for the first time after you have updated a vendor release. It saves a lot of time.

Search for and resolve any conflicts. A couple of CVS commands are useful for this. cvs update will show any files modified, added, or removed by the vendor between releases.

 % cvs update
 M Makefile.conf

Note that even though include/site.h was locally modified in the previous release, it does not show up as modified here. This is because it was not actually modified by the vendor between the two vendor releases.

cvs diff will display any changes between the last release and this code; changes either from local updates or from the new release. The diff output will also display our changes to include/site.h.

It is probably more useful to use cvs diff -r VENDOR to display changes between the most recent vendor release and this code:

 % cvs diff -r ISC
 Index: Makefile.conf
 RCS file: /src/cvsroot/net/dhcp/Makefile.conf,v
 retrieving revision
 diff -r1.1.1.2 Makefile.conf
 > ## RMITCS overrides
 > #BINDIR = /usr/local/sbin
 > #CLIENTBINDIR = /usr/local/sbin
 > #ADMMANDIR = /usr/local/man/cat1m
 > #FFMANDIR = /usr/local/man/cat4
 > #VARRUN = /var/run
 > #VARDB = /var/run/dhcp
 > #SCRIPT=none
 Index: includes/site.h
 RCS file: /src/cvsroot/net/dhcp/includes/site.h,v
 retrieving revision
 retrieving revision 1.2
 diff -r1.1.1.1 -r1.2
 > #define _PATH_DHCPD_PID       "/var/run/"
 > #define _PATH_DHCPD_DB        "/var/run/dhcpd.leases"
 > #define _PATH_DHCPD_CONF      "/usr/local/etc/dhcpd.conf"

Peruse the output of the diffs and determine if things look reasonable. In this case I am fairly happy with the changes. Refer to the CVS info documentation [4] node “Conflicts example” for more information on resolving conflicts.

Ignoring files via cvsignore

There are certain file names that frequently occur inside your working copy, but that you don’t want to put under CVS control. Examples are all the object files that you get while you compile your sources. Normally, when you run ‘cvs update’, it prints a line for each file it encounters that it doesn’t know about (see section A.16.2 update output).

CVS has a list of files (or sh(1) file name patterns) that it should ignore while running update, import and release. This list is constructed in the following way.

  • The list is initialized to include certain file name patterns: names associated with CVS administration, or with other common source control systems; common names for patch files, object files, archive files, and editor backup files; and other names that are usually artifacts of assorted utilities. Currently, the default list of ignored file name patterns is:
   RCS     SCCS    CVS     CVS.adm
   RCSLOG  cvslog.*
   tags    TAGS
   .make.state     .nse_depinfo
   *~      #*      .#*     ,*      _$*     *$
   *.old   *.bak   *.BAK   *.orig  *.rej   .del-*
   *.a     *.olb   *.o     *.obj   *.so    *.exe
   *.Z     *.elc   *.ln
  • The per-repository list in ‘$CVSROOT/CVSROOT/cvsignore’ is appended to the list, if that file exists.
  • The per-user list in ‘.cvsignore’ in your home directory is appended to the list, if it exists.
  • Any entries in the environment variable $CVSIGNORE are appended to the list.
  • Any ‘-I’ options given to CVS is appended.
  • As CVS traverses through your directories, the contents of any ‘.cvsignore’ will be appended to the list. The patterns found in ‘.cvsignore’ are only valid for the directory that contains them, not for any sub-directories.

In any of the 5 places listed above, a single exclamation mark (‘!’) clears the ignore list. This can be used if you want to store any file which normally is ignored by CVS.

Specifying ‘-I !’ to cvs import will import everything, which is generally what you want to do if you are importing files from a pristine distribution or any other source which is known to not contain any extraneous files. However, looking at the rules above you will see there is a fly in the ointment; if the distribution contains any ‘.cvsignore’ files, then the patterns from those files will be processed even if ‘-I !’ is specified. The only workaround is to remove the ‘.cvsignore’ files in order to do the import. Because this is awkward, in the future ‘-I !’ might be modified to override ‘.cvsignore’ files in each directory.

Note that the syntax of the ignore files consists of a series of lines, each of which contains a space separated list of filenames. This offers no clean way to specify filenames which contain spaces, but you can use a workaround like ‘foo?bar’ to match a file named ‘foo bar’ (it also matches ‘fooxbar’ and the like). Also note that there is currently no way to specify comments.

Branches / Merging Branches / Trunk Merging

This example was taken from:


How to check out a branch

  cvs co -r <keyword>-<revision>-branch xc

How to make a branch

You have no checked out trees

If you want to use the main trunk as the anchor for your branch:

  cvs rtag -b <keyword>-<revision>-branch
  cvs co -b <keyword>-<revision>-branch

If you want to use some other tag as the anchor for your branch:

  cvs rtag -b -r <tag> <keyword>-<revision>-branch
  cvs co -b <keyword>-<revision>-branch

You have a checked out trunk, and you want to tag it and start using it as a branch

  cd <root-of-your-checked-out-tree>
  cvs tag -b <keyword>-<revision>-branch
  cvs update -r <keyword>-<revision>-branch

This makes the {{{<keyword>-<revision>-branch}}} tag sticky. You can verify this by using {{{cvs status}}}, for example in `XFree39/xc`, do this:

  cvs status Makefile


  cvs status -v Makefile

How to merge the trunk into your branch

Before you merge your code into the trunk you should first merge the latest trunk code into your branch. After merged code has been tested on your branch, merging into the trunk should be simple.

  • Be sure all the changes on your branch are checked in.
  • Tag your branch with a ‘freeze’ tag:
  cvs tag <keyword>-<revision>-<date>-freeze
  • Merge from the trunk:
  cvs update -d -j HEAD
  • Resolve any conflicts from the merge.
  • Recompile and build your branch. Test it.
  • Check in your changes from the merge.
  • Tag your branch with a merge tag:
  cvs tag <keyword>-<revision>-<date>

How to merge your branch to the main trunk

  • Be sure your <keyword>-<revision>-<date>-merge tag (on the branch) is up

to date (i.e., in case you changed some files from between the time you merged the trunk onto the branch until you merged the branch onto the trunk).

You can make the tag with:

  cvs tag <keyword>-<revision>-<date>
  • Revert your working tree to the main trunk:
  cvs update -A

(Alternatively, you can just check out a new copy of the main trunk.)

  • Merge in the changes from your branch:
  cvs update -j <keyword>-<revision>-branch
  • Test your merged tree
  • Check in your merged tree to the main branch;
  cvs commit -m 'Merged <keyword>-<revision>'
  • Tag your merge so we can find it again:
  cvs tag <keyword>-<revision>-<date>-merge
  • Now you can make diffs to send to XFree86

Say you keep hacking on your branch after the merge to test a few extra things and you want to merge again. You get the main trunk checked out, as in step 1, then you merge only those changes between your last merge and the most recent revision in your branch:

  cvs update -j <keyword>-<revision>-<date> \
             -j <keyword>-<revision>-branch

Donations keep this site alive

Add A Comment