CVS Techniques

This information is for historical reference only; the R source repository is now maintained using Subversion. Please see Subversion tips instead.


There are two main development branches for R. For reference, we call r-devel, and r-patched.

After the release of R-x.y.z the two versions work towards

Version      Name            Tag
R-x.(y+1).0  r-devel         [none]
R-x.y.(z+1)  r-patched       R-x-y-patches
The "Tag" column refers to CVS branch tags. The logic is that patch releases (R-x.y.z, z!=0) are made from the branch tagged "R-x-y-patches", whereas normal releases (R-x.y.0) are made from the from the "trunk" i.e. the untagged files.

In what follows, I use the reference names also as directory names. All developers are encouraged to use the same names, to provide us with a common reference.

Checking out a development branch

(By a development branch, I mean either the trunk or a version marked by a CVS branch tag)

First set the CVSROOT environment variable and make sure it is exported:
For sh variants, use
export CVSROOT

For csh and derivatives, use

setenv CVSROOT

If your username on franz aka is not the same as your local user name you need to add it to CVSROOT, eg setenv CVSROOT

Also make sure that you have CVS_RSH set to ssh. I shall assume the bash shell in the following, for simplicity, and create the three development directories under $RTOP.

export RTOP=~/R-devel #adjust as necessary

The head revision

(aka "r-devel")

mkdir -p $RTOP/r-devel
cd $RTOP/r-devel
cvs co -P R

The -P option prunes empty directories. The checked out directory will be called "R". Use the -d option to call it something else.

Current patch branch

(aka "r-patched")

mkdir -p $RTOP/r-patched
cd $RTOP/r-patched
cvs co -P -r R-1-9-patches R

Checking out a specific release version

Release versions are labeled with a tag of the form R-1-2-3. (For obscure reasons, non-patch versions up to R-1.3.0 were labeled R-1-3 and not R-1-3-0. This was changed starting with R-1.4.0.). You can check out an old version simply with

cvs co -P -r R-1-2-3 R

Notice however, that these tags are not branch tags, you cannot change a released version and commit the changes back.


To update a source tree with the latest changes, just go to the relevant top-level directory (e.g. $RTOP/r-patches/R) and say

cvs up -Pd

If you want to make completely sure that the files come from a given branch, add (say) -r R-1-9-patches . I am unsure whether (and when) this is actually needed; there seems have been a case where a new directory got added from the wrong branch.

If you are on a slow connection, it generally works to take one revision and convert it to another tagged revision by using e.g.

cvs up -Pd -r R-1-9-patches

To create the trunk revision from a branch revision, use

cvs up -PdA

Notice, however, that CVS is capable of getting things wrong, notably if interrupted in the middle of an update. This can lead to an infinite loop condition when updating. If that happens, I know no remedy other that doing a fresh checkout instead.


To put your modified versions back in the repository, just say cvs commit -m'describe change' FILE1 FILE2 ...

or just

cvs commit

in which case you'll be asked for a change comment.

Notice that commits only works on the trunk and on branch revisions. Non-branch tags represent the status of the files at a given instance in the past which is unchangeable by definition.

Updating from r-patched to r-devel, entire tree

	# assumes that 	"last-patch-update" is set correctly

export RTOP=~/R-devel #adjust as necessary
export TAG=R-1-9-patches

cd $RTOP/r-devel/R
cvs rtag -F -r $TAG  patch-update R

cvs update -Pd
cvs update -Pd -j last-patch-update  -j patch-update
find -type f | xargs grep '>>>>>>>'
	# fix conflicts...
cvs commit -m 'branch update'

	# better do this right away...
cvs rtag -F -r patch-update last-patch-update R

Updating from r-patched to r-devel, specific files

FILES="src/main/unique.c NEWS" #change to your liking
PATCH=~/R-devel/r-patched/R         #ditto
DEVEL=~/R-devel/r-devel/R     #ditto

# fix and commit to r-patched  as usual, e.g.
cvs up
cvs commit $FILES

# Note: Use cvs tag (not rtag) just in case someone commited a change
# in the meantime
cvs tag -F patch-update $FILES


cvs update -j last-patch-update  -j patch-update $FILES
grep '>>>>>>>' $FILES
# FIX CONFLICTS (if any)
# This technique is often helpful, although you need to be aware that
# ediff occasionally makes conflicts more complicated rather than
# less...
#   emacs  -f vc-resolve-conflicts
cvs commit -m 'branch update' $FILES
cvs tag -F -r patch-update last-patch-update $FILES

Making releases

Dot-release (x.y.0)

echo -e "TAG=$TAG\nREL=$REL\nOREL=$OREL"

export CVSROOT=/home/rdevel/CVS-ARCHIVE
cd ~/r-devel
rm -rf R BUILD
cvs checkout -P R
	#-- set/check version number and release status:
cd R

mkdir ../BUILD
cd ../BUILD
        # FIXME: this'll build against Tcl 8.0 on Franz and so might
	# break future versions
../R/configure --enable-maintainer-mode --prefix ~/$REL
make && make check && make check-devel && make check-all

cd ~/r-devel/R
cvs update -Pd # watch out for merges!
cvs commit -m 'preparing for release'

#---- at specified time:
cd ~/r-devel/R
cvs update -Pd # watch out for last minute merges -
               # make check again if necessary!
cvs rtag $TAG R
cvs rtag -b -r $TAG $BRANCHTAG R

cd ~
rm -rf r-patched
mkdir r-patched
cd r-patched
cvs checkout -P -r $BRANCHTAG R

cd ~/r-devel/BUILD
make dist
cp $REL.tar.gz $FTPDIR/$REL.tgz
cd ../R

split -b 1400k $REL.tgz $REL.tgz-split.
ln -sf $REL.tgz R-latest.tgz

#	-- set release numbers on release and devel. versions

cd ~/r-devel/R
echo $NEWMAJOR.$NEWMINOR.0 "Under development (unstable)" > VERSION
cvs commit -m 'prepare for next version' VERSION

cd ~/r-patched/R
echo $MAJOR.$MINOR.0 "Patched" > VERSION
cvs commit -m 'prepare for next version' VERSION
# Don't forget this or branch updates run amok!
cvs rtag -F -r $BRANCHTAG last-patch-update R

# Finally, update the developer homepage with new version info
# Make announcement on R-announce
# ------------ All done --------------

Dot-dot release (x.y.z)

	# Exec the following and check carefully:

echo -e "TAG=$TAG\nREL=$REL\nDIFF=$DIFF"

	# go to the patched directory
cd ~/r-patched
rm -rf BUILD R
cvs -d ~rdevel/CVS-ARCHIVE checkout -Pr R-$MAJOR-$MINOR-patches R
cd R
	#-- set/check version number and release status

mkdir ~/r-patched/BUILD
cd ~/r-patched/BUILD

(../R/configure --enable-maintainer-mode --prefix ~/$REL \
  --with-tcl-config=/usr/lib/tcl8.4/ \
make &&  make check-all) | tee make.log

cd ~/r-patched/R
cvs update -Pd
cvs commit -m "prepare for release $REL"

#---- at specified time:

cvs update -Pd # watch out for last minute merges - make check if necessary!
cd ~/r-patched/R
cvs tag $TAG

cd ~/r-patched/BUILD
make dist
cp $REL.tar.gz $FTPDIR/$REL.tgz
cd ../R

split -b 1400k $REL.tgz $REL.tgz-split.
ln -sf $REL.tgz R-latest.tgz

#---- Setup for patch tree

cd ~/r-patched/R
echo $MAJOR.$MINOR.$PL Patched  > VERSION
cvs commit -m "setup for patched versions"

# Finally,
#    Update the developer homepage with new version info
#    Make announcement on R-announce
# ------------ All done --------------

Handling experimental branches

Suppose you want to have a branch to hold your volatile changes, let's
say R-Tk.

(A) Creating the branch
export CVSROOT cvs rtag -b R-Tk R mkdir r-experimental cd r-experimental cvs checkout -P -r R-Tk R cvs rtag -r R-Tk R-Tk-update-last R (B) Hacking on the branch ===================== Just like on the release branch: cvs update -Pd -r R-Tk #..hack, hack, hack.... cvs commit -m'hacked blah' (C) Updating from r-devel (aka "main trunk") ======================================== cvs rtag -F R-Tk-update R cvs update -Pd -j R-Tk-update-last -j R-Tk-update # resolve conflicts if any cvs commit -m 'merged from main' cvs rtag -F -r R-Tk-update R-Tk-update-last R (D) Merging the hack back into r-devel ================================== cd ~/r-devel/R cvs update -Pd -j R-Tk # resolve conflicts if any cvs commit -m'merged with Tk branch'