Annotated RCS Practice Session

## The Working Directory:
## To get started we first need to make a working directory as well as a
## RCS sub-directory.  Note if a ../RCS/ directory is not present RCS puts
## the delta files, ex. 'fubar,v', in the working directory; allowed but
## perhaps not really ideal.
#
$ mkdir -p rcs_test/RCS
$ cd rcs_test
 
## Create a test file:
## RCS supports a handful of keyword tags which can be included in source
## files like so: "$Tag$".  These tags will then be expanded whenever RCS
## acts upon the file.
##
## fubar test file with 'Id' RCS keyword tag:
#
$ printf '$Id$\nThis is fubar line one.\n' >fubar
 
 
## Initial file check-in:
## When a file is first placed under RCS management the user is prompted
## for just the file's description.  This info can be multi-lined and is
## finalized with a "." on a new line.  The ci(1) command will be used for
## subsequent check-ins as well.  The '-u' option tells RCS to check the
## file in unlocked and place a read-only copy of the file in the working
## directory.  Keeping a read-only copy in the working directory is useful,
## especially for configuration files which need to be present.
#
$ ci -u fubar
RCS/fubar,v  <--  fubar
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> The fubar RCS practice file
>> .
initial revision: 1.1
done
 
## The current state of our working directory.  Note the special delta
## file under ../RCS/ which are used to track the changes:
#
$ ls -FR
RCS/       fubar
 
./RCS:
fubar,v
 
## Verifying the read-only status of fubar file:
#
$ ls -l fubar
-r--r--r--  1 sdfer  users  73 Mar  3 21:18 fubar
 
 
## Checking out RCS-managed files for editing:
## The co(1) command is used for check-outs.  Although not mandatory, locking
## the file via the '-l' option is a good idea as it helps prevent accidental
## over-writes or having to do a merge if previously checked out. In addition
## the lock state of a file can be polled via rlog(1) as a proxy to determine
## if it is liked check out.
#
$ co -l fubar
RCS/fubar,v  -->  fubar
revision 1.1 (locked)
done
 
## Verifying the read-write status of working file:
#
$ ls -l fubar
-rw-r--r--  1 sdfer  users  101 Mar  3 21:20 fubar
 
## Committing additional revisions:
## As with the initial check-in, the ci(1) command is used to commit changes made
## to our test file.  Below we add a second line to fubar then check it back in.
## This time RCS prompts for a description of our edit(s) followed by a "." on a
## new line:
#
$ echo 'This is fubar line two.' >> fubar
$ ci -u fubar
RCS/fubar,v  <--  fubar
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> added 2nd line
>> .
done
 
 
## Verifying RCS keyword Tag expansion:
## It's a small file so we'll use cat(1) to show current content of fubar.  Note
## the expansion of the "$Id$" keyword tag; similar tags are commonly used by the
## NetBSD project as can be seen at the top of various /etc/* config files:
#
$ cat fubar
# $Id: fubar,v 1.2 2025/03/04 04:19:48 sdfer Exp $
This is fubar line one.
This is fubar line two.
 
 
## The Art of Reversion:
## It's common for humans to have a change of heart in their endeavors
## and file editing is certainly not exempt.  Fortunately RCS is up to
## dealing with our indecisiveness.  To illustrate we'll check out our
## test file, make some edits to the working copy, then over-write the
## working copy with the latest checked in version, leaving us back at
## our starting point.
#
$ co -l fubar
RCS/fubar,v  -->  fubar
revision 1.2 (locked)
done
 
## add a third line to test file:
#
$ echo 'This is fubar line 3.' >> fubar
 
## We've changed our mind => revert back to latest checked-in version.
## We'll use the '-u' option with the co(1) command which will remove
## the lock on the latest checked-in version and over-write our edited
## working file with a read-only copy if we confirm the action:
#
$ co -u fubar
RCS/fubar,v  -->  fubar
revision 1.2 (unlocked)
writable fubar exists; remove it? [ny](n): y  # << type "y" to confirm
done
 
## Verifying file state is read-only:
#
$ ls -l fubar
-r--r--r--  1 sdfer  users  73 Mar  3 21:18 fubar
 
 
## Comparing revisions with rcsdiff(1):
## The rcsdiff(1) command is similar to the standard Unix diff(1) and is
## used to compute the differences between two revisions. For ease of use
## The default reference point is the latest checked in revision and if 
## run without specifying an alternate revision the comparison is with
## the working copy.  Since our file is identical to the latest checked
## in version the rcsdiff(1) command reports just that:
#
$ rcsdiff fubar
===================================================================
RCS file: RCS/fubar,v
retrieving revision 1.2
diff -r1.2 fubar
 
## Providing specific versions to rcsdiff(1) shows the differences; below
## r1.1 and r1.2 are compared.  Note that the same result is obtained if
## just '-r1.1' is given as the latest version is the default reference:
#
$ rcsdiff -r1.1 -r1.2 fubar
===================================================================
RCS file: RCS/fubar,v
retrieving revision 1.1
retrieving revision 1.2
diff -r1.1 -r1.2
1c1
< # $Id: fubar,v 1.1 2025/03/04 04:18:22 sdfer Exp $
---
> # $Id: fubar,v 1.2 2025/03/04 04:19:48 sdfer Exp $
2a3
> This is fubar line two.
 
 
## Similarly, if we do another check out, make some edits and run the
## rcsdiff(1) command again we can see how our working copy compares
## to the latest checked in revision:
#
$ co -l fubar
RCS/fubar,v  -->  fubar
revision 1.2 (locked)
done
 
 
## Re-add a third line to test file:
#
$ echo 'This is fubar line 3, again.' >> fubar
 
## Compute diff between working file and r1.2:
#
$ rcsdiff fubar
RCS file: RCS/fubar,v
retrieving revision 1.2
diff -r1.2
3a4
> This is fubar line 3, again.
 
## Toss line 3 again and revert back to RO r1.2:
#
$ co -u fubar
RCS/fubar,v  -->  fubar
revision 1.2 (unlocked)
writable fubar exists; remove it? [ny](n): y  # << type "y" to confirm
done
 
 
## Deleting versions:
## Oops -- we've changed our mind AGAIN and want to revert to r1.1 and
## DELETE r1.2 from the RCS record.  This requires the rcs(1) command
## with the '-o<ver_range>' option along with 'co -u' as before.  Note
## the order doesn't matter: 'co -r1.1 -u' + 'rcs -o1.2' works too.
#
$ rcs -o1.2 fubar
RCS file: RCS/fubar,v
deleting revision 1.2
done
 
## rcs(1) left the RO copy which was still at r1.2..
#
$ ls -l fubar
#
-r--r--r--  1 sdfer  users  97 Mar  3 21:22 fubar
 
## Just for fun, instead of using cat(1) lets use the ident(1) command
## to display the current state of our RCS keyword tag "$Id$":
#
$ ident fubar
fubar:
     $Id: fubar,v 1.2 2025/03/04 04:19:48 sdfer Exp $
 
## As we can see above the RO copy in the working directory still shows
## the r1.2 edits; to fix this we'll need to check out latest checked in
## version (now 1.1) and UNLOCK it:
#
$ co -u fubar
RCS/fubar,v  -->  fubar
revision 1.1 (unlocked)
done
 
## Re-running ident(1) shows our read-only copy now matches the latest
## checked revision which is now r1.1:
#
$ ident fubar
fubar:
     $Id: fubar,v 1.1 2025/03/04 04:18:22 sdfer Exp $
 
 
## Checking the logs:
## The rlog(1) command can show us the change comments for any checked in
## revision using '-r<ver>'.  Be default rlog(1) simply shows ALL changes:
#
$ rlog fubar
RCS file: RCS/fubar,v
Working file: fubar
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1;     selected revisions: 1
description:
The fubar RCS practice file
----------------------------
revision 1.1
date: 2025/03/04 04:18:22;  author: sdfer;  state: Exp;
Initial revision
=============================================================================
 
 
## Checking lock states with rlog(1):
## As long as locking hasn't been disabled the rlog(1) command can be used
## to determine whether a file is currently locked and thus is a proxy for
## discerning whether a file is likely checked out. When the '-L' option is
## used rlog(1) will print the file name(s) of any files with active locks;
## files without locks are omitted, i.e. no output.  A simple lock checker
## can be made utilizing this behavior like so:
#
$ [ -z "$(rlog -L fubar)" ] && echo 'Unlocked' || echo 'Locked'
=> Unlocked
 
## If we check out and lock our test file and re-run the above we can see
## change in lock status:
#
$ co -l fubar
RCS/fubar,v  -->  fubar
revision 1.1 (locked)
done
 
$ [ -z "$(rlog -L fubar)" ] && echo 'Unlocked' || echo 'Locked'
=> Locked

This concludes our whirlwind tour of RCS – you are now an expert! 8-)