Using CVS inside emacs

emacs comes with a standard version control interface, vc.el, which does a pretty good job with CVS when you're only modifying and committing a single file. I use it for probably 80% of my commits.

To use it, just edit the file that you want to change and then, when you're ready to commit your changes, enter Ctrl-X Ctrl-Q. (If vc.el hasn't yet been loaded, this may do nothing except toggle the read-only status of the file. If nothing appears to happen, press Ctrl-X Ctrl-Q again and then type ESC x vc-next-action. This will force the right thing to happen and will load vc.el so that the next time Ctrl-X Ctrl-Q will work.)

There are various other useful commands available. The other one that I use the most often is Ctrl-X v =, which shows a diff from the previous version of the file in another window. Since I prefer unified diff, I put:

    ;; I prefer unified context diffs.
    (setq diff-switches "-u")

in my .emacs files. For information about other available commands (not all of which work with CVS), type:

    info emacs 'version control'

We also have pcl-cvs available, an emacs interface to CVS in particular that operates by directory rather than by file. I used to use it a lot and it's quite nice (although I've mostly fallen back to doing multiple file commits, and all adds and removes from the command line since it's faster for me). I put the following in my .emacs to make invoking pcl-cvs easier:

    ;; Run cvs-update-other-window, but checks the directory the file
    ;; being currently edited is in first and uses that to set the CVS
    ;; repository.
    (defun rra-cvs-update ()
      "Customized cvs-update-other-window that doesn't prompt for a
      (if (string-match "XEmacs" emacs-version)
            (if (one-window-p) (split-window-vertically))
            (other-window 1)
            (cvs-update (file-name-directory (buffer-file-name)) t))
        (cvs-update-other-window (file-name-directory (buffer-file-name)))))

I can then just press Ctrl-C c when editing a file and pcl-cvs runs. pcl-cvs starts by doing a cvs update (so don't use it in directory trees where you want to carefully control when updates happen) and parses the results. It then shows you a list of files that changed, with words like "Updated" or "Modified" instead of cvs update's fairly terse single character notes. Files that CVS doesn't know about show up as "Unknown".

You can then commit files by going down to that line and pressing c, and pcl-cvs will pop up a new editing window for you to enter the commit notice in. You can mark multiple files with m (or M to mark everything) and use c to commit them all at once. You can also add new files with a (and pcl-cvs will prompt you for the description you'd normally have to use the -m flag to set).

If any of the files you committed you already had open in emacs, pcl-cvs will even re-read those files from disk for you, so that you'll get the CVS keyword changes.

You can press "g" anywhere in the pcl-cvs window to re-run cvs update and refresh the window.

I still do file deletions (cvs remove) outside of pcl-cvs because it's a bit tricky with the standard pcl-cvs interface.

There's plenty of help available, both by typing:

    info pcl-cvs

for the full manual and just by pressing ? in the pcl-cvs buffer, which will list all of the available commands. Nearly everything CVS can do pcl-cvs can do with a keystroke.

One final note: Sometimes, when using emacs with CVS-controlled files, files will be opened in read-only mode and emacs will beep at you when you try to change them. This happens when vc gets confused about the file and thinks that someone else has it locked. To get out of read-only mode, use ESC x toggle-read-only (this is normally bound to Ctrl-X Ctrl-Q, but vc takes over that key binding).

Last modified and spun 2014-08-17