AAnn IInnttrroodduuccttiioonn ttoo RRCCSS TThhee RReevviissiioonn CCoonnttrrooll SSyysstteemm _L_a_s_t _E_d_i_t _M_a_r_c_h _2_3_, _1_9_9_2 Reg Quinton Computing and Communications Services The University of Western Ontario London, Ontario N6A 5B7 Canada 11.. AAuutthhoorr Walter F. Tichy, Purdue University, West Lafayette, Copy- right (C) 1982, 1988, 1989 by Walter F. Tichy. These notes are from _r_c_s_i_n_t_r_o(1) by Tichy. Within CCS we're currently running Revision Number: 5.6 ; Release Date: 1991/11/03; from cs.purdue.edu. RCS is in the public domain and distributed by the GNU pro- ject (GNU is not Unix). Available by anonymous ftp from prep.ai.mit.edu (and uunet, julian, etc.). Available on most Unix systems, or install the public domain version. _B_e_w_a_r_e there are incompatiblity problems between versions, eg. we installed the GNU version on our systems (Sun and Mips) to get compatibility. The principle contender is SCCS (Source Code Control Sys- tem). This is ATT proprietary code; that's why we don't use it. 11 UUWWOO//RRCCSS 22.. WWhhaatt iiss iitt?? The Revision Control System (RCS) manages multiple revisions of text files. RCS automates the storing, retrieval, log- ging, identification, and merging of revisions. RCS is useful for text that is revised frequently, for example programs, documentation, graphics, papers, form let- ters, etc. The basic user interface is extremely simple. The novice only needs to learn two commands: _c_i(1L) and _c_o(1L). Ci, short for "check in", deposits the contents of a text file into an archival file called an RCS file. An RCS file contains all revisions of a particular text file. Co, short for "check out", retrieves revisions from an RCS file. The remaining commands are _r_l_o_g (to examine revision his- tory), _r_c_s (to manage RCS), _i_d_e_n_t (to check identifiers), and _r_c_s_d_i_f_f (to check differences). However, ci and co are enough to get your started. UUWWOO//RRCCSS 22 33.. FFuunnccttiioonnss ooff RRCCSS Storage and retrieval of multiple revisions of text. RCS saves all old revisions in a space efficient way. Changes no longer destroy the original, because the previous revisions remain accessible. Revisions can be retrieved according to ranges of revision numbers, symbolic names, dates, authors, and states. Maintenance of a complete history of changes. RCS logs all changes automatically. Besides the text of each revision, RCS stores the author, the date and time of check-in, and a log message summarizing the change. The logging makes it easy to find out what happened to a module, without having to compare source listings or having to track down colleagues. Resolution of access conflicts. When two or more program- mers wish to modify the same revision, RCS alerts the pro- grammers and prevents one modification from corrupting the other. Maintenance of a tree of Revisions. RCS can maintain sepa- rate lines of development for each module. It stores a tree structure that represents the ancestral relationships among revisions. 33 UUWWOO//RRCCSS Merging of revisions and resolution of conflicts. Two sepa- rate lines of development of a module can be coalesced by merging. If the revisions to be merged affect the same sec- tions of code, RCS alerts the user about the overlapping changes. Release and configuration control. Revisions can be assigned symbolic names and marked as released, stable, experimental, etc. With these facilities, configurations of modules can be described simply and directly. Automatic identification of each revision with name, revi- sion number, creation time, author, etc. The identification is like a stamp that can be embedded at an appropriate place in the text of a revision. The identification makes it sim- ple to determine which revisions of which modules make up a given configuration. Minimization of secondary storage. RCS needs little extra space for the revisions (only the differences). If interme- diate revisions are deleted, the corresponding deltas are compressed accordingly. _M_o_r_a_l it's an important tool for making, documenting, and coordinating changes to the system. UUWWOO//RRCCSS 44 44.. GGeettttiinngg SSttaarrtteedd Suppose you have a file f.c that you wish to put under con- trol of RCS. (1) Make an RCS subdirectory (this isn't required but will make life simpler). % mkdir RCS (2) Add this text, as a comment, to your file (this isn't required but will make life simpler). $Author$ $Date$ $Id$ $Source$ (3) Invoke the check-in command % ci f.c (4) Invoke the check-out command % co f.c 55 UUWWOO//RRCCSS The check in command command creates the file f.c,v in the RCS subdirectory, stores f.c into it as revision 1.1, and deletes f.c. It also asks you for a description. The description should be a synopsis of the contents of the file. All later check-in commands will ask you for a log entry, which should summarize the changes that you made. Files ending in ,v are called RCS files (`v' stands for `versions'), the others are called working files. To get back the working file f.c in the previous example, use the check-out command % co f.c This command extracts the latest revision from f.c,v and writes it into f.c. Note the comments ($Author$, $Date$, etc.) have been expanded by RCS: % page f.c ... $Author: reggers $ $Date: 1992/03/23 20:00:07 $ $Id: slides,v 1.2 1992/03/23 20:00:07 reggers Exp $ $Source: /usr/src/usr.local/doc/courses/rcs/RCS/slides,v $ ... UUWWOO//RRCCSS 66 55.. LLoocckkss You can co, edit f.c, and check it back in by invoking % co -l f.c % edit f.c ....testing % ci f.c _C_o _-_l creates a writable version and marks the file as locked: % page f.c ... $Author: reggers $ $Date: 1992/03/23 20:00:07 $ $Id: slides,v 1.2 1992/03/23 20:00:07 reggers Exp $ ... Locking a file prevents others from trying to do the same. It keeps people from tripping over one another. The file locking is a good communications tool -- it indi- cates that someone is working on the problem. 77 UUWWOO//RRCCSS 55..11.. SSkkiippppiinngg tthhee lloocckk If _c_i complains with the message ci error: no lock set by then you've editted a file that hasn't been marked as locked. This would have required some effort -- to get write access you have to _c_o _-_l or have done a _c_h_m_o_d. It is too late now to do the check-out with locking, because you probably modified f.c already, and a second check-out would overwrite your modifications. Instead, invoke % rcs -l f.c This command will lock the latest revision for you, unless somebody else got ahead of you already. In this case, you'll have to negotiate with that person. _M_o_r_a_l if you're working on a file lock it first! UUWWOO//RRCCSS 88 55..22.. LLoocckk SSuummmmaarryy Locking assures that you, and only you, can check in the next update, and avoids nasty problems if several people work on the same file. Even if a revision is locked, it can still be checked out for reading, compiling, etc. All that locking prevents is a CHECK-IN by anybody but the locker. If your RCS file is private, i.e., if you are the only per- son who is going to deposit revisions into it, strict lock- ing is not needed and you can turn it off. If strict lock- ing is turned off, the owner of the RCS file need not have a lock for check-in; all others still do. Turning strict lock- ing off and on is done with the commands % rcs -U f.c % rcs -L f.c To get rid of a lock (say you've done _r_c_s _-_l or _c_o _-_l but decided against doing any changes): % rcs -u f.c 99 UUWWOO//RRCCSS 66.. CCii [[--ll --uu]] To avoid the deletion of the working file during check-in (in case you want to continue editing), invoke % ci -l f.c % ci -u f.c These commands check in f.c as usual, but perform an implicit check-out. The first form also locks the checked in revision, the second one doesn't. Thus, these options save you one check-out operation. The first form is useful if locking is strict, the second one if not strict. Both update the identification markers in your working file (see below). It's a bad idea to ci a revision and leave your working copy around -- its RCS headers will say it's locked and this will confuse people. _M_o_r_a_l alias ci 'ci -u' UUWWOO//RRCCSS 1100 77.. RReevviissiioonn NNuummbbeerrss You can give _c_i the number you want assigned to a checked in revision. Assume all your revisions were numbered 1.1, 1.2, 1.3, etc., and you would like to start release 2. The com- mand % ci -r2 f.c % ci -r2.1 f.c assigns the number 2.1 to the new revision. From then on, _c_i will number the subsequent revisions with 2.2, 2.3, etc. The corresponding _c_o commands % co -r2 f.c % co -r2.1 f.c retrieve the latest revision numbered 2.x and the revision 2.1, respectively. _C_o without a revision number selects the latest revision on the "trunk", i.e., the highest revision with a number consisting of 2 fields. 1111 UUWWOO//RRCCSS 77..11.. BBrraanncchheess Usually revision numbers are a simple sequence of changes to a body of text numbered 1.1, 1.2, ..., 2.1, 2.2, ..., etc. Numbers with more than 2 fields are needed for branches. For example, to start a branch at revision 1.3, invoke % ci -r1.3.1 f.c This command starts a branch numbered 1 at revision 1.3, and assigns the number 1.3.1.1 to the new revision. For more information about branches, see _r_c_s_f_i_l_e(5L). Branching usually isn't necessary (I've never used it). UUWWOO//RRCCSS 1122 88.. RReevviissiioonn HHiissttoorryy RCS maintains a revision history. Every time you check in a version you're asked for explanatory text. Why did you make these changes? [11:33am zebra] ci Makefile RCS/Makefile,v <-- Makefile new revision: 1.6; previous revision: 1.5 enter log message: (terminate with ^D or single '.') >> clean target should ignore error condition >> . done _M_o_r_a_l document what you've done and why you did it. Leave some foot prints for those who follow. 1133 UUWWOO//RRCCSS You examine the revision history (and RCS options you've set) by saying _r_l_o_g _M_a_k_e_f_i_l_e: UUWWOO//RRCCSS 1144 99.. AAuuttoommaattiicc IIddeennttiiffiiccaattiioonn RCS can put special strings for identification into your source and object code. To obtain such identification, place the marker $Id$ into your text, for instance inside a comment. RCS will replace this marker with a string of the form $Id: slides,v 1.2 1992/03/23 20:00:07 reggers Exp $ With such a marker on the first page of each module, you can always see with which revision you are working. RCS keeps the markers up to date automatically. To propagate the markers into your object code, simply put them into literal character strings. In C, this is done as follows: static char *rcsid=\ "$Id: slides,v 1.2 1992/03/23 20:00:07 reggers Exp $"; 1155 UUWWOO//RRCCSS The command _i_d_e_n_t extracts such markers from any file, even object code and dumps. Thus, _i_d_e_n_t lets you find out which revisions of which modules were used in a given program. For example: % ident /usr/lib/sendmail /usr/lib/sendmail: $Header: /usr/src/usr.local/rsendmail .../RCS/rsendmail.c,v 1.4 90/11/13 ....13:36:21 reggers Exp $ You may also find it useful to put the marker $Log$ into your text, inside a comment. This marker accumulates the log messages that are requested during check-in. Thus, you can maintain the complete history of your file directly inside it. UUWWOO//RRCCSS 1166 99..11.. KKeeyywwoorrdd lliisstt The complete set of keywords and their corresponding values is: $Author$ The login name of the user who checked in the revision. _R_e_c_o_m_m_e_n_d_e_d -- who did this? $Date$ The date and time the revision was checked in. _R_e_c_o_m_- _m_e_n_d_e_d -- when did they do this? $Header$ A standard header containing the full pathname of the RCS file, the revision number, the date, the author, the state, and the locker (if locked). _R_e_c_o_m_m_e_n_d_e_d -- everything you need to know! $Id$ Same as $Header$, except that the RCS file name is without a path. $Locker$ The login name of the user who locked the revision (empty if not locked). _R_e_c_o_m_m_e_n_d_e_d -- who is working on this file? $Log$ The log message supplied during checkin, preceded by a header containing the RCS file name, the revision num- ber, the author, and the date. Existing log messages are NOT replaced. Instead, the new log message is inserted after _$_L_o_g_$. This is useful for accumulating a complete change log in a source file. $RCSfile$ The name of the RCS file without path. $Revision$ The revision number assigned to the revision. 1177 UUWWOO//RRCCSS $Source$ The full pathname of the RCS file. _R_e_c_o_m_m_e_n_d_e_d -- where are the sources? $State$ The state assigned to the revision with the option of or Any identifier is acceptable for _s_t_a_t_e. A useful set of states is _E_x_p (for experimental), _S_t_a_b (for sta- ble), and _R_e_l (for released). By default, sets the state of a revision to _E_x_p. _R_e_c_o_m_m_e_n_d_e_d -- what's the status? UUWWOO//RRCCSS 1188 1100.. GGrroouupp PPrroojjeeccttss To create an access control list: % rcs -areggers,peter,purple,mcote f.c This gives the listed users the right to lock the file (ie. they can ci and co). Note that you have to list yourself. _B_e_w_a_r_e This requires that the listed users have read/write priviledges for the directories (eg. can't co f.c if you can't write the file f.c). This is usually done with a common group: % chmod 775 . % chmod 775 RCS _B_e_w_a_r_e This requires that the listed users create files that one another can read (eg. you can't co f.c if you can't read f.c,v). This is usually done with a common group and a default file mask: % umask 027 1199 UUWWOO//RRCCSS 1111.. SSeeee AAllssoo ci(1L), co(1L), ident(1L), merge(1L), rcs(1L), rcsdiff(1L), rcsmerge(1L), rlog(1L), rcsfile(5L), Walter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control System," in _P_r_o_c_e_e_d_i_n_g_s _o_f _t_h_e _6_t_h _I_n_t_e_r_- _n_a_t_i_o_n_a_l _C_o_n_f_e_r_e_n_c_e _o_n _S_o_f_t_w_a_r_e _E_n_g_i_n_e_e_r_i_n_g, IEEE, Tokyo, Sept. 1982. By anonymous ftp to julian.uwo.ca, the article _r_c_s_._h_o_w_t_o in the directory ~ftp/doc (also as /usr/doc). By anonymous ftp to julian.uwo.ca, these slides in the directory ~ftp/doc/courses/rcs.ps (also as /usr/doc). UUWWOO//RRCCSS 2200