12.8 Individual VC Commands
We've already explained what the main command, vc-next-action, does. Now we'll describe each of VC's other commands in detail. We have chosen the order of these descriptions to take you from frequently used and simpler commands to rarer and more complex ones.
You can, accordingly, read to the end of chapter or bail out at any point if you think you've learned all you need to. But try to persevere because you may find that the descriptions of the less common commands give you some new ideas about how to track and organize your project files.
12.8.1 Working with Groups and Subtrees of Files
Usually, the projects you want to put under version control have more than one file; it's normal for them to contain all the files under a specific directory and subdirectory. Therefore, seeing a list of all version-controlled files beneath the current working directory is often useful. Being able to perform an operation on all of them en masse is even more useful.
VC mode supports this directly. The command C-x v d (for vc-directory) puts you in a buffer running a customized Dired (directory editing) mode, which lists all registered files under the current directory, indicating which, if any, are checked out and who has locked them. The status field in this listing is automatically kept up to date by check-in and check-out operations.
If you mark several files in this Dired buffer (with the ordinary Dired mark command described in Chapter 5) and then perform either a vc-next-action or vc-revert-buffer, VC performs that operation on all the marked files. The most common case in which you'll perform this procedure is when you want to check in changes to several files simultaneously. VC helps you out: it pops up a buffer for only one change comment, which it then applies to every revision the check-in creates.
The vc-revert-buffer design is a bit more conservative; normally, it prompts you once for each file to make sure you really want to discard its changes.
Some Dired commands are rebound in VC Dired to run version-control commands. The = keystroke, for example, runs vc-diff on the current file rather than a Dired diff. And g refreshes all the VC status fields in the directory.
12.8.2 Difference Reports
Earlier, we mentioned that version control systems help you generate difference reports between versions. VC's command for this is C-x v = (for vc-diff). This command normally shows you the difference between your work file and the last revision you checked in so that you can see exactly what changes you'll be committing if you check in again.
If you give this command a prefix argument, C-u C-x v =, it prompts you for a file name and two revision numbers and reports the difference between those revisions of the file. If the older revision number is empty (that is, you simply press Enter at that prompt), it defaults to the last checked-in revision. If the newer revision is empty, it defaults to the work file. So pressing Enter twice compares the work file with what was last checked in to the repository, a very common task.
It's also possible to get a difference report for a whole tree of project files. If the filename you give C-u C-x v = is actually a directory, you'll see the differences between your specified versions for every registered file underneath that directory.
By design, such a difference report can be shipped and mechanically applied as a patch using Larry Wall's patch utility (available on all modern Unixes). This is a tremendous help when you're cooperating on a software project by email; you can download sources, register them, make modifications—and then, with one command, generate a complete patch set of your changes to mail to your collaborators.
The exact format of these reports varies somewhat between version control systems because VC uses each system's native difference reporter.[87] Generally, the output resembles that of the Unix diff command. We'll see how to customize the report later in this chapter. Finally, the last section of the chapter introduces Ediff, an alternate and powerful way to compare and resolve differences between multiple files or versions.
12.8.3 Retrieving Old Revisions
You can use the command C-x v ~ (for vc-version-other-window) to retrieve any saved revision of a file. The revision is retrieved into a work file with the same name as your file, except for a suffix that identifies its revision number (the suffix is actually a dot, followed by a tilde, followed by the revision number, followed by another tilde). So you can retrieve several revisions, and they won't step on each other. This command is useful when you want to eyeball the entire old version of a file, as opposed to just its changes from previous versions or its differences from later ones.
The version suffix format is very close to what Emacs generates for saved versions if you set the global Emacs Lisp variable version-control (which VC has made pretty much obsolete). For example, if you're visiting a file named foo.html and you retrieve version 1.3 by typing C-x v ~ 1 . 3 Enter, you will now be visiting a file named foo.html.~1.3~ (and because it ends with a tilde, Dired's command to flag backup files will mark it, as discussed in Chapter 5).
12.8.4 Viewing Change Histories
If you use C-x v l (for vc-print-log) on a registered file, VC pops up a buffer containing that file's change history. This command is most useful for viewing the change comments associated with each revision.
12.8.5 Registering a File
Normally, registering a file for version control with C-x v v (for vc-next-action) with a nonconcurrent version control system also checks out an editable copy. Occasionally it's useful to be able to just register a file without checking it out. The command C-x v i (for vc-register) does this. With modern concurrent version control systems, this distinction is fading away.
12.8.6 Inserting Version Control Headers
Most version control systems encourage you to embed in your file one or more magic strings that get automatically updated at check-in, check-out, and revert time. The purpose of these strings is to carry automatically inserted information about the current revision number of the file, who last modified it, and when it was last checked in.
These header strings largely duplicate within the file the version information that VC puts on the mode line—and the rest of that information you can get with C-x v l (for vc-print-log). This feature might not seem very useful, but (in particular) embedding a version string can make it possible to mine version-control information out of a compiled binary program.
Further, you may frequently view version-controlled files through something other than Emacs. If so, you won't have an Emacs mode line displaying version control information, and there is some value in having the magic headers visible in the file. Accordingly, VC provides you with a command to insert them. (Note that what VC inserts are correctly formatted placeholders for the headers; the actual values get filled in by the underlying version control system each time you commit the file.)
87
This is a slight oversimplification. VC actually has its own script as a wrapper around SCCS's sccsdiff, in order to give it a calling sequence more like RCS's rcsdiff.