��� RCS - Wikidocs

RCS

From Wikidocs

Table of contents

RCS Overview

RCS is the Revision Control System, a venerable (i.e. ancient) software solution for tracking modification of source files. Revision Control provides a log of changes to a file along with comments added when the file was modified. Tools are provided which will show specific changes between particular revisions or the entire history of a changes to a file.

Until we have time to properly implement CVS or Subversion with a nice distribution mechanism across all servers RCS will serve as a stop-gap for change control over our config files.

Using RCS

RCS: Managing System Config Files (http://www.linuxgazette.com/node/8416 )

Here we'll run through using RCS on a sample config file, but essentially it's pretty much what's described in the Linux Gazette article.

Check-In

First you need to "check-in" your file. For neatness we should create an RCS sub-directory anywhere we want to have files under RCS's control. RCS will store the "vector" files in here, this reduces clutter in directories where lots of files will be checked-in. The vector files are ASCII stores containing diffs of changes made, timestamps and their associated comments. Lets see RCS in action. The stuff typed in is in bold everything else is output:

[wmcdonald@willspc ~]$ pwd
/home/wmcdonald
[wmcdonald@willspc ~]$ mkdir conf
[wmcdonald@willspc ~]$ cd conf/
[wmcdonald@willspc conf]$ mkdir RCS
[wmcdonald@willspc conf]$ touch sample.conf
[wmcdonald@willspc conf]$ ls -l
total 4
drwxrwxr-x  2 wmcdonald wmcdonald 4096 Jun 27 12:07 RCS
-rw-rw-r--  1 wmcdonald wmcdonald    0 Jun 27 12:07 sample.conf
[wmcdonald@willspc conf]$ ci -u sample.conf
RCS/sample.conf,v  <--  sample.conf
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> initial check-in - WMCD
>> .
initial revision: 1.1
done
[wmcdonald@willspc conf]$ ls -l
total 4
drwxrwxr-x  2 wmcdonald wmcdonald 4096 Jun 27 11:59 RCS
-r--r--r--  1 wmcdonald wmcdonald    0 Jun 27 11:59 sample.conf
[wmcdonald@willspc conf]$ ls -l RCS
total 4
-r--r--r--  1 wmcdonald wmcdonald 206 Jun 27 11:59 sample.conf,v
[wmcdonald@willspc conf]$

Here I've created an empty file "sample.conf" and checked it in to RCS, this created an associated vector, "sample.conf,v". If you don't provide the -u option RCS checks the working file in without leaving a readable copy. For source code this is acceptable, for config files it's very bad. So we alway use -u when checking in config files.

Always try to give sensible input when prompted for comments/log detail. A brief description of the change and any reason for it which may be useful later.

Check-Out

Notice that the checking-in process has changed the permissions for the file to read-only, this is a simplistic mechanism to prevent inadvertant edits to the file without it first being checked out.

Should we need to edit our config we need to "check-out" the file from RCS.

[wmcdonald@willspc conf]$ co -l sample.conf
RCS/sample.conf,v  -->  sample.conf
revision 1.1 (locked)
done
[wmcdonald@willspc conf]$ vi sample.conf

Here the file's been checked-out for editing, I've edited it and added the following sample text.

# sample config file

option1=defalt
option2=default

Now the file needs to be checked back in

[wmcdonald@willspc conf]$ ci -u ./sample.conf
./RCS/sample.conf,v  <--  ./sample.conf
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> Initial edit. Added a comment and set some default options.
>> WMCD
>> .
done
[wmcdonald@willspc conf]$

Notice the revision has incremented. Now the process which reads this file is restarted and complains it can't read option1, simple typo, easily fixed.

[wmcdonald@willspc conf]$ co -l sample.conf
RCS/sample.conf,v  -->  sample.conf
revision 1.2 (locked)
done
[wmcdonald@willspc conf]$ vi sample.conf
[wmcdonald@willspc conf]$ cat sample.conf
# sample config file
#
# $Id$
 
option1=default
option2=default

[wmcdonald@willspc conf]$

I've fixed the typo and added a comment including the $Id$ string. This is a special string that RCS expands when the file is checked back in which provides some useful information on last edit time, file version and so on. So let's check it back in after the changes.

[wmcdonald@willspc conf]$ ci -u sample.conf
RCS/sample.conf,v  <--  sample.conf
new revision: 1.3; previous revision: 1.2
enter log message, terminated with single '.' or end of file:
>> Fixed option1 typo. Added $Id$ for RCS.
>> WMCD
>> .
done
[wmcdonald@willspc conf]$ cat sample.conf
# sample config file
#
# $Id: sample.conf,v 1.3 2005/06/27 11:18:38 wmcdonald Exp $

option1=default
option2=default

[wmcdonald@willspc conf]$


So, to summarise, for a new config file use ci -u to check in, co -l to check-out before editing and ci -u again to check back in once complete.

Useful RCS Tools & Features

rlog and rcsdiff and the remaining commands we need to be aware of. rlog provides a potted history of the file's modifications.


[wmcdonald@willspc conf]$ rlog ./sample.conf

RCS file: ./RCS/sample.conf,v
Working file: ./sample.conf
head: 1.3
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 3;     selected revisions: 3
description:
initial check-in - WMCD
----------------------------
revision 1.3
date: 2005/06/27 11:18:38;  author: wmcdonald;  state: Exp;  lines: +3 -1
Fixed option1 typo. Added $Id$ for RCS.
WMCD
----------------------------
revision 1.2
date: 2005/06/27 11:16:05;  author: wmcdonald;  state: Exp;  lines: +5 -0
Initial edit. Added a comment and set some default options.
WMCD
----------------------------
revision 1.1
date: 2005/06/27 11:10:19;  author: wmcdonald;  state: Exp;
Initial revision
=============================================================================
[wmcdonald@willspc conf]$

rcsdiff provides us with a detailed breakdown of the changes (i.e. a diff) between revisions of a file.

[wmcdonald@willspc conf]$ rcsdiff -r1.2 -r1.3 ./sample.conf
===================================================================
RCS file: ./RCS/sample.conf,v
retrieving revision 1.2
retrieving revision 1.3
diff -r1.2 -r1.3
1a2,3
> #
> # $Id: sample.conf,v 1.3 2005/06/27 11:18:38 wmcdonald Exp $
3c5
< option1=defalt
---
> option1=default

Working With RCS and Source Files in Bulk

RCS allows us to check-in and check-out entire directories (think whole projects) worth of files. As an example lets say that static content on webdev1 for Managed $Project isn't under RCS control and we'd like it to be.

Initial Bulk Check-in

We want to check in all the HTML source, to save having to add individual descriptive text for each file (remember, the descriptive text tells us the file's purpose) we can assign a global description to all the files being checked-in in one fell swoop using the "-t-" option to ci.

Check which files we'll be checking-in and create the RCS subdirectory for the "vector" files:

[root@webdev1 public_html]# cd /home/project.net/public_html/
[root@webdev1 public_html]# ls -l *.html
-rw-r--r--  1 root root  121 Dec  1  2004 atmail.html
-rw-r--r--  1 root root 2251 Oct 17 11:04 cookie2test.html
-rw-r--r--  1 root root  730 Sep 25  2003 cookietest.html
-rw-r--r--  1 root root  660 Sep 25  2003 em_export.html
-rw-r--r--  1 root root  406 Sep 30 13:05 index1024.html
-rw-r--r--  1 root root  405 Sep 25  2003 index1152.html
-rw-r--r--  1 root root  406 Sep 25  2003 index640.html
-rw-r--r--  1 root root  406 Sep 30 13:07 index800.html
-rw-r--r--  1 root root 2727 Sep 25  2003 index.html
-rw-r--r--  1 root root 3619 Oct 10 15:32 logon.html
-rw-r--r--  1 root root 3574 Sep 25  2003 logontest.html
-rw-r--r--  1 root root 5451 Sep 25  2003 nmslogoff.html
-rw-r--r--  1 root root  310 Sep 25  2003 project.html
-rw-r--r--  1 root root  454 Dec 20  2004 ttrac_msg.html
[root@webdev1 public_html]# mkdir RCS

Now we check-in all the HTML files. "-i" tells ci this is the initial check-in, files already checked in will be ignored. "-u" tells ci to leave a read-only working copy of the file in place. "-t-" tells ci to use the message which follows in quotes as the descriptive text.

[root@webdev1 public_html]# ci -i -u -t-"Managed $Project (project.net) static pages" *.html
RCS/atmail.html,v  <--  atmail.html
initial revision: 1.1
done
RCS/cookie2test.html,v  <--  cookie2test.html
initial revision: 1.1
done
RCS/cookietest.html,v  <--  cookietest.html
initial revision: 1.1
done
RCS/em_export.html,v  <--  em_export.html
initial revision: 1.1
done
RCS/index1024.html,v  <--  index1024.html
initial revision: 1.1
done
RCS/index1152.html,v  <--  index1152.html
initial revision: 1.1
done
RCS/index640.html,v  <--  index640.html
initial revision: 1.1
done
RCS/index800.html,v  <--  index800.html
initial revision: 1.1
done
RCS/index.html,v  <--  index.html
initial revision: 1.1
done
RCS/logon.html,v  <--  logon.html
initial revision: 1.1
done
RCS/logontest.html,v  <--  logontest.html
initial revision: 1.1
done
RCS/nmslogoff.html,v  <--  nmslogoff.html
initial revision: 1.1
done
RCS/project.html,v  <--  project.html
initial revision: 1.1
done
RCS/ttrac_msg.html,v  <--  ttrac_msg.html
initial revision: 1.1
done

We can check the state of one of the newly checked in files using rlog.

[root@webdev1 public_html]# rlog ./index.html

RCS file: ./RCS/index.html,v
Working file: ./index.html
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1;     selected revisions: 1
description:
Managed $Project (project.net) static pages
----------------------------
revision 1.1
date: 2005/10/19 14:49:45;  author: root;  state: Exp;
Initial revision
=============================================================================

Bulk Check-out

If we want to make changes across a few files at the same time we can check-out all HTML files, edit the ones we need then do a bulk check-in and only the files which have changed will have their "vector" files updated.

[root@webdev1 public_html]# co -l *.html
RCS/atmail.html,v  -->  atmail.html
revision 1.1 (locked)
done
RCS/cookie2test.html,v  -->  cookie2test.html
revision 1.1 (locked)
done
RCS/cookietest.html,v  -->  cookietest.html
revision 1.1 (locked)
done
RCS/em_export.html,v  -->  em_export.html
revision 1.1 (locked)
done
RCS/index1024.html,v  -->  index1024.html
revision 1.1 (locked)
done
RCS/index1152.html,v  -->  index1152.html
revision 1.1 (locked)
done
RCS/index640.html,v  -->  index640.html
revision 1.1 (locked)
done
RCS/index800.html,v  -->  index800.html
revision 1.1 (locked)
done
RCS/index.html,v  -->  index.html
revision 1.1 (locked)
done
RCS/logon.html,v  -->  logon.html
revision 1.1 (locked)
done
RCS/logontest.html,v  -->  logontest.html
revision 1.1 (locked)
done
RCS/nmslogoff.html,v  -->  nmslogoff.html
revision 1.1 (locked)
done
RCS/project.html,v  -->  project.html
revision 1.1 (locked)
done
RCS/ttrac_msg.html,v  -->  ttrac_msg.html
revision 1.1 (locked)
done
[root@webdev1 public_html]#

Bulk Check-in

Now I can add the RCS "$Id$" macro into a few of the files and perform a bulk check-in. I only need to enter the log message for the first edited file. Once entered and terminated with the '.' dot, holding down ENTER will simply re-use the previous log for all changed files.

[root@webdev1 public_html]# vi index*
5 files to edit
[root@webdev1 public_html]# ci -u *.html
RCS/atmail.html,v  <--  atmail.html
file is unchanged; reverting to previous revision 1.1
done
RCS/cookie2test.html,v  <--  cookie2test.html
file is unchanged; reverting to previous revision 1.1
done
RCS/cookietest.html,v  <--  cookietest.html
file is unchanged; reverting to previous revision 1.1
done
RCS/em_export.html,v  <--  em_export.html
file is unchanged; reverting to previous revision 1.1
done
RCS/index1024.html,v  <--  index1024.html
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> Added $Id$ in comment for the index files by way of an
>> example for RCS docs.
>> wmcd
>> .
done
RCS/index1152.html,v  <--  index1152.html
new revision: 1.2; previous revision: 1.1
reuse log message of previous file? [yn](y):
done
RCS/index640.html,v  <--  index640.html
new revision: 1.2; previous revision: 1.1
reuse log message of previous file? [yn](y):
done
RCS/index800.html,v  <--  index800.html
new revision: 1.2; previous revision: 1.1
reuse log message of previous file? [yn](y):
done
RCS/index.html,v  <--  index.html
new revision: 1.2; previous revision: 1.1
reuse log message of previous file? [yn](y):
done
RCS/logon.html,v  <--  logon.html
file is unchanged; reverting to previous revision 1.1
done
RCS/logontest.html,v  <--  logontest.html
file is unchanged; reverting to previous revision 1.1
done
RCS/nmslogoff.html,v  <--  nmslogoff.html
file is unchanged; reverting to previous revision 1.1
done
RCS/project.html,v  <--  project.html
file is unchanged; reverting to previous revision 1.1
done
RCS/ttrac_msg.html,v  <--  ttrac_msg.html
file is unchanged; reverting to previous revision 1.1
done
[root@webdev1 public_html]#