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.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.
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.
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:
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.
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.
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.
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.
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.
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).
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.
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.
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
backward-page) and C-x ] (forward-page) to move to
next day)
backward-paragraph) and M-] (forward-paragraph) to
move by entries and ESC h (mark-paragraph) to mark an
entry)You can use either C-x a or C-x 4 a to add a ChangeLog for the current file and defun:
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.
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
",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
"^\\([A-Z][A-Z_ ]+\\|[a-z_--A-Z]+\\)[ ]*[:=]"
Heuristic regexp used by add-log-current-defun for unknown major
modes.
add-log-current-defun
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.
The following variables can be used to customize `rcs.el':
rcs-bind-keys
rcs-active
rcs-ange-ftp-ignore
ftp.gnu.ai.mit.edu:ange-ftp/ange-ftp.el.Zor by email from its author, ange@hplb.hpl.hp.com (Andy Norman).
rcsdiff-switches
rcs-default-co-switches
rcs-check-out.
rcs-default-ci-switches
rcs-check-in.
rcs-default-rlog-switches
rcs-log.
rcs-read-log-function
(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.
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.
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 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.
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.
`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.