| Title: File versioning with rcs | |
| Author: Solène | |
| Date: 31 October 2018 | |
| Tags: openbsd highlight unix versioning | |
| Description: | |
| In this article I will present you the | |
| [**rcs**](https://man.openbsd.org/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](https://man.openbsd.org/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](https://man.openbsd.org/ci) and [co](https://man.openbsd.org/co): | |
| 1. 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) | |
| 2. edit the file | |
| 3. 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](https://man.openbsd.org/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. | |
| # rcsdiff -u -r1.1 fstab | |
| --- fstab 2018/10/29 14:45:18 1.1 | |
| +++ fstab 2018/10/29 14:45:34 | |
| @@ -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 |