In this article I will present you the rcs tools and we will use it for versioning files in /etc to track changes between editions. These tools are part of the OpenBSD base install.

Prerequisites

You need to create a RCS folder where your files are, so the files versions will be saved in it. I will use /etc in the examples, you can adapt to your needs.

# cd /etc # mkdir RCS

The following examples use the command ci -u . This will be explained later why so.

Tracking a file

We need to add a file to the RCS directory so we can track its revisions. Each time we will proceed, we will create a new revision of the file which contain the whole file at that point of time. This will allow us to see changes between revisions, and the date of each revision (and some others informations).

I really recommend to track the files you edit in your system, or even configuration file in your user directory.

In next example, we will create the first revision of our file with ci, and we will have to write some message about it, like what is doing that file. Once we write the message, we need to validate with a single dot on the line.

# cd /etc # ci -u fstab fstab,v <-- fstab enter description, terminated with single '.' or end of file: NOTE: This is NOT the log message! >> this is the /etc/fstab file >> . initial revision: 1.1 done

Editing a file

The process of edition has multiples steps, using ci and co:

checkout the file and lock it, this will make the file available for writing and will prevent using co on it again (due to lock) edit the file commit the new file + checkout

When using ci to store the new revision, we need to write a small message, try to use something clear and short. The log messages can be seen in the file history, that should help you to know which change has been made and why. The full process is done in the following example.

# co -l fstab RCS/fstab,v --> fstab revision 1.1 (locked) done # echo "something wrong" >> fstab # ci -u fstab RCS/fstab,v <-- fstab new revision: 1.4; previous revision: 1.3 enter log message, terminated with a single '.' or end of file: >> I added a mistake on purpose! >> . revision 1.4 (unlocked) done

View changes since last version

Using previous example, we will use rcsdiff to check the changes since the last version.

# co -l fstab RCS/fstab,v --> fstab revision 1.1 (locked) done # echo "something wrong" >> fstab # rcsdiff -u fstab --- fstab 2018/10/28 14:28:29 1.1 +++ fstab 2018/10/28 14:30:41 @@ -9,3 +9,4 @@ 52fdd1ce48744600.j /usr/src ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.e /var ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.m /data ffs rw,dev,wxallowed,nosuid 1 2 +something wrong

The -u flag is so to produce an unified diff, which I find easier to read. Lines with + shows additions, and lines with - show deletions (there are none in the example).

Use of ci -u

The examples were using ci -u this is because, if you use ci some_file , the file will be saved in the RCS folder but will be missing in its place. You should use co some_file to get it back (in read-only).

# co -l fstab RCS/fstab,v --> fstab revision 1.1 (locked) done # echo "something wrong" >> fstab # ci -u fstab RCS/fstab,v <-- fstab new revision: 1.4; previous revision: 1.3 enter log message, terminated with a single '.' or end of file: >> I added a mistake on purpose! >> . done # ls fstab ls: fstab: No such file or directory # co fstab RCS/fstab,v --> fstab revision 1.5 done # ls fstab fstab

Using ci -u is very convenient because it prevent the user to forget to checkout the file after commiting the changes.

Show existing revisions of a file

# rlog fstab RCS file: RCS/fstab,v Working file: fstab head: 1.2 branch: locks: strict access list: symbolic names: keyword substitution: kv total revisions: 2; selected revisions: 2 description: new file ---------------------------- revision 1.2 date: 2018/10/28 14:45:34; author: solene; state: Exp; lines: +1 -0; Adding a disk ---------------------------- revision 1.1 date: 2018/10/28 14:45:18; author: solene; state: Exp; Initial revision =============================================================================

We have revisions 1.1 and 1.2, if we want to display the file in its 1.1 revision, we can use the following command:

# co -p1.1 fstab RCS/fstab,v --> standard output revision 1.1 52fdd1ce48744600.b none swap sw 52fdd1ce48744600.a / ffs rw 1 1 52fdd1ce48744600.l /home ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.d /tmp ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.f /usr ffs rw,nodev 1 2 52fdd1ce48744600.g /usr/X11R6 ffs rw,nodev 1 2 52fdd1ce48744600.h /usr/local ffs rw,wxallowed,nodev 1 2 52fdd1ce48744600.k /usr/obj ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.j /usr/src ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.e /var ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.m /data ffs rw,dev,wxallowed,nosuid 1 2 done

Note that there is no space between the flag and the revision! This is required.

We can see that the command did output some extra informations about the file and “done” at the end of the file. Thoses extra informations are sent to stderr while the actual file content is sent to stdout. That mean if we redirect stdout to a file, we will get the file content.

# co -p1.1 fstab > a_file RCS/fstab,v --> standard output revision 1.1 done # cat a_file 52fdd1ce48744600.b none swap sw 52fdd1ce48744600.a / ffs rw 1 1 52fdd1ce48744600.l /home ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.d /tmp ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.f /usr ffs rw,nodev 1 2 52fdd1ce48744600.g /usr/X11R6 ffs rw,nodev 1 2 52fdd1ce48744600.h /usr/local ffs rw,wxallowed,nodev 1 2 52fdd1ce48744600.k /usr/obj ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.j /usr/src ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.e /var ffs rw,nodev,nosuid 1 2 52fdd1ce48744600.m /data ffs rw,dev,wxallowed,nosuid 1 2

Show a diff of a file since a revision

We can use rcsdiff using -r flag to tell it to show the changes between last and one specific revision.