Go to the first, previous, next, last section, table of contents.


An RCS Interface for GNU Emacs Sebastian Kremer sk@thp.uni-koeln.de

$Date: 1992/02/10 10:30:35 $

$Revision: 1.18 $

Copyright (C) 1991, 1992 Sebastian Kremer

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled "GNU General Public License" is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled "GNU General Public License" may be included in a translation approved by the author instead of in the original English.

Rcs, a GNU Emacs RCS interface

`rcs.el' provides a convenient, automated, often nearly transparent way to use the Revision Control System (RCS) source-code management utilities.

When the library is loaded and the variable rcs-active is non-nil, Emacs will notice and respond appropriately to RCS files associated with the files you visit. These RCS files will be found either in the same directory as the files you are working with, or (preferentially, for organization's sake) in an `RCS' subdirectory of that directory.

See the manual pages of rcs(1) for information about how RCS itself works. `rcs.el' assumes that you are using strict locking in RCS, which is necessary to derive the full benefits of its protection. `rcs.el' is known to work with RCS 5.5 and 5.6, and should also work with earlier versions of RCS.

Overview of Rcs

Editing RCS controlled files in Emacs works like this:

The minor mode part of the modeline displays the head revision number `rev' if a file is RCS controlled, but currently unlocked, or a list of lockers (in the format `locker:rev') if it is currently locked. Usually you just use C-x C-q to start editing an RCS controlled file (making it writable by checking out a locked revision) and C-c I to check in a new (or initial) revision.

These two commands suffice for most day-to-day usage, but additional commands exist to give info about RCS files (C-c D to `rcsdiff', C-c L to show the RCS log), to unlock a file you have begun to edit (C-c U), and to show all locked files in a directory (C-c W).

If a working file you want to visit does not exist but can be created by checking out an RCS file, Emacs automatically does that. You are asked if you want to lock the file for editing, i.e., if you intend to modify that file. If you answer y or SPC, the file will be RCS-locked and thus writable for editing. If you answer n or DEL an unlocked read-only copy will be checked out. If you abort from the prompt by typing C-g, no file will be checked out from RCS. You should probably kill the empty buffer that results from aborting find-file in this case.

If any RCS operation initiated by rcs-mode fails or generates unexpected output, an error is signalled, and the RCS output is displayed in a buffer.

This is nearly everything you need to know to start using `rcs.el'. The remaining sections give more detailed information about each command, how `rcs.el' hooks itself into Emacs and the user options.

Rcs Commands

Most commands accept a prefix argument C-u to mean that the switches passed to the underlying RCS program (`rcsdiff', `ci' etc.) are to be edited. You are prompted for the switches in the minibuffer. Multiple switches can be entered on the same line, separated by whitespace. The arguments are not passed to a shell: the string is split on whitespace and each component is one argument.

With this method, there is no way to include space in an argument. Usually this is not important, but sometimes you want to be able to include spaces, e.g., for the `rlog -t' command. Therefore, there is an escape to "line mode": if you enter a single space instead of a switch, you are prompted for each switch separately, until you just enter a RET by itself.

However, be warned that adding arbitrary switches to commands is a very powerful, but also potentially dangerous feature. You should always know what your are doing when adding switches of your own, especially for the `rcs', `ci' or `co' commands, which (unlike the `rcsdiff' or `rlog' commands) can affect your files.

Unless you set the variable rcs-bind-keys to nil before loading `rcs.el', the following keys will be bound:

C-x C-q
(rcs-toggle-read-only) If the buffer being changed is under RCS control, prompt if you want to perform the corresponding RCS action, namely, checking out a locked version of the file to make it writable. Once a file is locked, you can toggle its read-only status without affecting its RCS status. In non-RCS buffers this behaves like the usual C-x C-q (toggle-read-only) command.
C-c I
(rcs-check-in) lets you check in a file. The file is unlocked unless a prefix argument is given, see below. It prompts you for the name of the file, defaulting to the current buffer's file. But you can also check in any other file. The log message is prompted for in the minibuffer. Since the string is passed directly to the `ci' program, no shell quoting is necessary and multiline messages are possible. You can use C-x ^ to enlarge the minibuffer, or yank (C-y) previously edited text into the minibuffer, e.g., from a `ChangeLog' buffer. It is also possible to use a separate buffer to edit the log by setting rcs-read-log-function to rcs-read-log-string-with-recursive-edit, See section Rcs Customization Variables. If you have just created a file, and it has not yet been put under RCS control, this command is the only way you can do so. If rcs-check-in is given a prefix argument, it will first let you edit the switches used, with `-l' as default to retain your lock. Use this to check in a version but continue editing the file. You can also specify the revision number here to create a new major revision level, e.g., use `-u3.0' to check in as revision 3.0, unlocked. If you want to force a checkin even if the file did not change, add `-f' to the switches. You could also do
(setq rcs-default-ci-switches '("-f"))
in your `~/.emacs' if you always wanted this behaviour.
C-c O
(rcs-check-out) retrieves the current version of a file from RCS. With a prefix argument you can specify the `co' switches, defaulting to `-l' to lock it for edit. Mostly C-x C-q is used to check out a file, but C-c O is useful if you have an older version of the file present in your directory, since find-file will just load that. The prefix argument can also be used to specify a version to check out, using the `-r' switch of the `co' program, e.g., use `-r2.5' to check out revision 2.5.
C-c D
(rcs-diff) creates a buffer showing the differences between the version of a file you are editing and the last version that was checked in to RCS. With a prefix argument you can specify the diff switches used, see also variable rcsdiff-switches, See section Rcs Customization Variables. Useful if you do not remember what you changed, and want to provide a descriptive log entry when you check it back in.
C-c U
(rcs-unlock) releases your RCS write lock on a given file; this is different from checking the file in because no new version of the file is created, and any changes that you have made will be discarded. If you have not actually made any changes, this operation is completed silently. However, if you have made changes, `rcs.el' will present you with a buffer showing you the changes that you have made (much as does rcs-diff) and ask you to confirm that you want to discard the changes. Currently it is not possible to break someone else's lock with `rcs.el' since `rcs -u' requires you to interactively compose a mail message for this. RCS 5.7 may offer a possibility to suppress the mail or take it from a file or from the commandline.
C-c L
(rcs-log) presents you with a buffer showing the log information for all versions of a given RCS file. You may use a prefix argument to give additional switches to the `rlog' program (e.g. `-h' to just show the head revision).
C-c S
(rcs-status) displays a brief message in the mode-line showing the lock status of a given file. If the file is not under RCS supervision (i.e., no RCS control `,v' file for it exists) or the file is not locked, this is stated. If the file has been locked by someone, their username and the version they have locked are displayed. As a side effect, the file has its modeline updated if it is currently visited in Emacs. Usually you just look at the modeline to find out the RCS status, but this command can also be used to describe files not currently visited in Emacs. With a prefix argument, this command changes instead of queries the RCS status. It prompts for arguments to be passed to the `rcs' program. Multiple switches can be entered separated by whitespace. See section Overview of Rcs, for how to include whitespace in a switch. For example, if you want to start using a different branch for a file, you would enter `-bbranch' to the prompt. The command executed will be `rcs -bbranch -q filename'. If `rcs' makes output in spite of the `-q' flag this means an error has occurred, which is reported in the usual way. The modeline is not automatically updated, thus you might want to do a status query right afterwards, depending on the sort of status change you requested. If you want to give a description to a file , type C-u C-c S, enter the filename and RET, and enter a single SPC to the prompt for the switches. This puts you into "line mode", allowing you to enter `-t-Descriptive Text', where there may be spaces in the descriptive text (something not possible if you had not escaped to line mode). You can even enter multiline text by using C-q C-j to do a quoted insert of a newline, since RET would finish your input.
C-c W
(rcs-who) presents a buffer showing the status of each locked file in a directory, showing who the locker is, and what version is locked. If no files are locked or there are no RCS controlled files at all, this is stated.

ChangeLog and RCS log

Accompanying `rcs.el', an enhanced version of `add-log.el' is shipped. It was modified from the Emacs 18.55 version to endorse the GNU coding standards and work together with `rcs.el'. (It will also work without `rcs.el'.) The advantage over the old version is that it automatically adds the filename, the current defun and the RCS level to the entry, like this:

	* rcs.el,v 1.52
	(rcs-unlock): 

You just have to enter the descriptive text, everything else is already there. If the guessed defun is not appropriate, C-w (kill-region) will wipe it out, since the mark was dropped at the beginning of the inserted defun.

The ChangeLog is set up so that

You can use either C-x a or C-x 4 a to add a ChangeLog for the current file and defun:

C-x a
(add-change-log-entry) Find change log file and add an entry for current day, file and defun. First argument (interactive prefix) non-nil means prompt for user, site and log file. If there is an empty entry (just a `*') it is used and filled in with the current filename and defun. Else, if there is an entry of today for the same file, it is used and a new line for the current defun is added at the beginning. Else, a new entry is created. Thus you can force using a new entry by first creating an empty entry with C-x a (add-change-log-entry) from the ChangeLog buffer itself, even if there is already an entry from today for the current file. This is useful if you check in two RCS revisions on the same day. When called from a lisp, second arg is file name of change log. Optional third arg other-window non-nil means visit in other window.
C-x 4 a
(add-change-log-entry-other-window) Like add-change-log-entry, but in other window.

This variable determines RCS revision level formatting in ChangeLogs:

add-change-log-entry-rcs-format
Default: ",v %s" Format used by add-change-log-entry to insert RCS revision levels. Besides a format string, it can also be a function of zero arguments to return the formatted revision level of the current buffer's file or nil. This can be used to hook in arbitrary RCS packages. If it is a string, it is assumed you are using sk's `rcs.el' (but it does not hurt if you do not, you just do not get any revision levels inserted).

`add-log.el' tries to guess the name of the "defun" (or more generally speaking, the section of a document) the cursor was in before you made the ChangeLog entry:

add-log-current-defun-header-regexp
Default: "^\\([A-Z][A-Z_ ]+\\|[a-z_--A-Z]+\\)[ ]*[:=]" Heuristic regexp used by add-log-current-defun for unknown major modes.
add-log-current-defun
Return name of function definition point is in, or nil. Understands Lisp, LaTeX ("defuns" are chapters, sections, ...), texinfo (@node titles), and C. Other modes are handled by a heuristic that looks in the 10K before point for uppercase headings starting in the first column or identifiers followed by `:' or =. Has a preference of looking backwards.

Here is one way of combining ChangeLogs and RCS logs: After doing changes to an RCS locked file, while it is still locked, use C-x 4 a to insert an entry. Compose the log message describing your changes. You might want to do C-c D to look at the diffs to the last checked-in version for this. Update the inserted revision level. Usually this just means incrementing it by one, but you might want to check it in with a new major revision number. For example, the log might look like


	* rcs.texi,v 1.16
	(ChangeLog and RCS log): 

and you would change it to


	* rcs.texi,v 1.17
	(ChangeLog and RCS log): 

Since `add-log.el' cannot know whether you are going to check in with a new major revision number (or whether you do ChangeLogs after or before RCS check in), this is not done automatically. When you are finished with composing your log message, put it into the kill ring using M-w (copy-region-as-kill), do the check-in using C-c I and yank the log message into the minibuffer.

That way, by doing the ChangeLog before the RCS log, you can compose your log message in the ChangeLog buffer without having to worry about recursive edits or having to cope with multiline minibuffer editing.

Rcs Customization Variables

The following variables can be used to customize `rcs.el':

rcs-bind-keys
Default: t If nil, `rcs.el' will not bind any keys. This variable has to be set before rcs.el is loaded, See section Installation of Rcs, for an example.
rcs-active
Default: t If non-nil, RCS controlled files are treated specially by Emacs. You can set this to nil to disable `rcs.el' completely, even after it has already been loaded.
rcs-ange-ftp-ignore
Default: t If non-nil, remote ange-ftp files are never considered RCS controlled. This saves a lot of time for slow connections. Ange-ftp is package for transparent FTP access within GNU Emacs. The latest version of ange-ftp can always be obtained via anonymous ftp from
ftp.gnu.ai.mit.edu:ange-ftp/ange-ftp.el.Z
or by email from its author, ange@hplb.hpl.hp.com (Andy Norman).
rcsdiff-switches
Default: nil If non-nil, a string specifying switches to be be passed to `rcsdiff'. A list of strings (or nil) means that the commandline can be edited after inserting those strings.
rcs-default-co-switches
Default: nil List of switches (strings) for co(1) to use on every rcs-check-out.
rcs-default-ci-switches
Default: nil List of switches (strings) for ci(1) to use on every rcs-check-in.
rcs-default-rlog-switches
Default: nil List of switches (strings) for rlog(1) to use on every rcs-log.
rcs-read-log-function
Default: nil If non-nil, function of zero args to read an RCS log message. If nil, log messages are read from the minibuffer. To be able to enter and edit log strings in a separate buffer, put
(setq rcs-read-log-function
      'rcs-read-log-string-with-recursive-edit)
in your `~/.emacs'. The function rcs-read-log-string-with-recursive-edit is predefined for this purpose.

Hooks Used by Rcs

This section explains how RCS hooks itself into Emacs. It is not necessary to read it to be able to use `rcs.el'.

`rcs.el' installs itself in two hooks that customize Emacs' file-manipulation behavior: find-file-not-found-hooks and find-file-hooks.

Automatic Checkout of Working Files

The first hook (rcs-file-not-found, installed in find-file-not-found-hooks) is called when a find-file request fails because the file is not found. It checks to see if there is an RCS file corresponding to the file requested, and offers to check that file out for you. It makes sense for this to be the first hook that Emacs tries, since it will only prompt you if the RCS file actually exists, and you will usually want to check it out in those instances. If you reply negatively, the remaining file-not-found hooks you may have installed will be tried until one succeeds (these may, for example, offer to create a default header for the file based on a boilerplate, etc.). `rcs.el' will install its own hook at the beginning of this list; you should make sure that any other libraries you load after `rcs.el' append their own hooks to the end of the list.

The Modeline

The second hook (rcs-load-postprocessor, installed in find-file-hooks) is a very simple routine which is called once a file has been loaded. It checks to see whether that file is under RCS' supervision, and whether you currently have a lock on the file (that is, you are the person who checked it out for editing). If so, it puts the buffer into the minor mode rcs-mode and displays either the head revision level or the current locker and locked revision in the format `locker:rev' in the mode line. If there are several locks, they will be displayed with a space between each of them. For similar reasons to those outlined above, this should be the first hook in the find-file-hooks list. (There is an exception: if you are using Ashwin Ram's infer-file-mode code, which also hooks into find-file-hooks, just make sure that infer-file-mode occurs first in the list of hooks by loading `rcs.el' before pushing infer-file-mode onto the hooks list. Otherwise a major mode change in infer-file-mode will kill all local variables, including the RCS modeline variables.)

You may also call rcs-load-postprocessor interactively to refresh the modeline, e.g., after a major mode change that killed all local variables. Alternatively, just requesting the RCS status of a file using C-c S (rcs-status) will also update its modeline.

When `rcs.el' is active, and you are editing RCS-controlled files, the read-only status of the file buffer is synonymous with the file's locked status within RCS. That is, if you have a file locked for edit, it will be writable. Otherwise, it will be read-only. Buffers not associated with RCS files continue to behave as they used to.

The key sequence C-x C-q (toggle-read-only) is remapped to call rcs-toggle-read-only, which will ask if you want to check out an RCS-controlled file if its buffer was read-only and you do not presently have a lock on that file. Once you have checked a file out for edit, you can toggle the read-only status of the buffer repeatedly without changing its RCS status, but there is probably no pressing reason why you would want to do this.

The automatic behavior outlined above--noticing files are available from RCS and offering to check them out, and locking them for edit when you hit the toggle-read-only key, will address most of the needs of RCS users in day-to-day development.

Installation of Rcs

Your system manager should have installed the package and the manual in the correct place, as described in the `rcs.README' file that comes with the distribution.

To use `rcs.el', simply load it from your `~/.emacs':

(load "rcs")

Additionally, you can customize variable by adding a line like

(setq rcsdiff-switches "-u") ; or whatever you prefer
;; you can change key bindings here or set some other variables

If you do not like the key bindings established by default, here is an example of how to chose your own bindings:

(setq rcs-bind-keys nil)     ; prevent rcs.el from binding any keys
(load "rcs")
;; chose your own key bindings
;; here with lower instead of upper case keys:
(global-set-key "\C-cd" 'rcs-diff)
(global-set-key "\C-ci" 'rcs-check-in)
(global-set-key "\C-cl" 'rcs-log)
(global-set-key "\C-co" 'rcs-check-out)
(global-set-key "\C-cs" 'rcs-status)
(global-set-key "\C-cu" 'rcs-unlock)
(global-set-key "\C-cw" 'rcs-who)
;; you will almost always want to bind this:
(global-set-key "\C-x\C-q" 'rcs-toggle-read-only)

`rcs.el' cannot be autoloaded since it must be present in the various find-file hooks before the first potentially RCS controlled file is visited in Emacs.

Acknowledgement

`rcs.el' was originally written in 1990 by James Elliott <elliott@cs.wisc.edu>. I think he invented the overloading of C-x C-q to check out a locked file.

Around November 1990 I started to modify it to display the lockers (instead of just `RCS') in the modeline, to fix some bugs, and to make it work with newer versions of RCS. In 1991 I systematically rewrote the code, added the possibility to add switches to all RCS commands, and wrote the manual.

My thanks go to James Elliott for writing the original `rcs.el', Paul Eggert <eggert@twinsun.com> (Author of RCS 5) for helpful comments and advance notes about new RCS releases, and all those who reported bugs or suggested features.


Go to the first, previous, next, last section, table of contents.