Выбрать главу

If you type C-x v h (for vc-insert-headers) while visiting a registered and editable file, VC tries to determine from the syntax of the file how to insert the version control header(s) as a comment and then do so. VC knows about C and Java code, and nroff/troff/groff code especially, and can usually deduce the right thing from Emacs' comment-start and comment-end global variables (set by each major mode) so it can insert HTML comments, for example. It falls back to #-to-\n comments (like those used by shell, awk, Perl, tcl, and many other Unix languages) if it can't figure out anything better to do. This command is also smart enough to notice if you already seem to have version control headers present in the file and will ask you for confirmation before inserting a redundant set.

One special behavior with respect to C code is worth mentioning. C files don't actually get version headers put in comments by default. Instead, Emacs generates a string initialization for a static dummy variable called vcid. This action is taken so the header will actually be generated into the corresponding object file as a string, and you can use the strings command (if you've got a Unix-like environment) to see which versions of its sources a binary was generated from.

12.8.7 Making and Retrieving Snapshots

A snapshot of a project is a set of revisions of the project files treated as a unit. Typically, releases are associated with points at which the project's product goes to a customer or other outside evaluator.

When you're working with a subtree of project files and want to define a release of a document or program, you may find it tedious to have to do it by remembering or storing long lists of file revision numbers. Accordingly, most version control systems give you the ability to associate a symbolic release name with all the revisions that make up a release, and then to use that symbolic name later on when naming revisions for retrieval or difference reports.

Bare RCS and CVS both provide this capability. Bare SCCS does not, but VC includes code to simulate it under SCCS. In practice, the difference between native symbolic names and VC's is next to invisible. The only drawback of VC's simulation is that the SCCS tools won't know about symbolic names when you call them outside VC. (Note that this concept doesn't really apply to Subversion, because in that environment every revision is a snapshot of the files and directories comprising the entire module.)

The C-x v s (for vc-create-snapshot) prompts you for a symbolic name. VC then associates this name with the current revision level of every registered file under the current directory.

The symbolic names you create with vc-create-snapshot are also valid arguments to any other VC command that wants a revision number. Symbolic names are especially useful with vc-diff; it means you can compare named releases with each other or with your checked-out work files. The C-x v r (for vc-retrieve-snapshot) command takes a symbolic name and checks out every registered file underneath the current working directory at the revision level associated with the name.

Both the snapshot commands will fail, returning an error and not marking or retrieving any files, if any registered file under the current directory is checked out by anyone. The vc-create-snapshot command fails in order to avoid making a snapshot that, when retrieved later, won't restore the current state completely. It also fails in order to avoid stepping on your work file changes before you've had the chance to check them in or revert them out.

12.8.8 Updating ChangeLog Files

The command C-x v a (for vc-update-change-log) helps VC work with some project-management conventions used by the Free Software Foundation. FSF projects generally have in each directory a file called ChangeLog that is supposed to contain timestamped modification comments for every file in that directory. The ChangeLog, historically, provided the change history, or audit trail, for which VC uses change comments.

Rather than make you enter every change comment twice (!), VC provides a hook that copies recent change comments out of masters beneath the current directory and appends them to a ChangeLog in the approved format.

12.8.9 Renaming Version-Controlled Files

Renaming version-controlled files can be tricky. In RCS or SCCS, you have to rename not just the work file but its associated master. Under CVS, for reasons too arcane to go into here, it's hard to do at all without breaking something.

The vc-rename-file tries to insulate you from the details and to catch and inform you about various error conditions that can arise. It simply prompts for old and new filenames, tries to do the right thing, and tells you if it cannot.

Warning

Renaming interacts badly with the simulated symbolic-name feature under SCCS. This is one of the better reasons to use RCS or CVS. And, actually, if you think you might need to rename or move files, you're best off investigating Subversion since one of its major design goals was to be the first version control system in which this task is straightforward.

12.8.10 When VC Gets Confused

The filesystem operations required to determine a file's version control state can be expensive and slow, especially in an NFS or other networked environment. VC goes to some pains to compensate (unless, as we'll see later on, you tell it not to).

It has two major methods: (1) caching per-file information (such as the locking user and current revision number) in memory rather than running version control utilities to parse it out of the relevant master every time, and (2) assuming that it can deduce a registered file's version control state from its write permissions. Specifically, VC assumes that a registered file that is writable is in the checked-out-and-locked state and that a registered file that is not writable is not a checked-out version being edited.

Multiuser environments being what they are, VC's cached information and assumptions about permissions occasionally lead it down the wrong path. This situation almost always occurs because someone has manually changed a file's permissions behind VC's back.

If you think that this situation has occurred, call vc-clear-context. This command forces VC to throw away all its cached-in-memory assumptions about the version control state of the files you are working with.

It is also theoretically possible for VC to get confused by a race condition between two or more VCs, or between VC and someone running the bare SCCS, RCS, or CVS utilities. This is not just a VC problem; the same sort of race is possible (though less likely) between two or more people running the bare utilities. However, this kind of race is very rare even in VC; the authors haven't heard of any instance in hundreds of thousands of programmer-hours in which it's known to have happened.