Remote Repositories
-------------------

A common way of using CVS is to set up a central CVS repository on some Internet host, then have each developer check out a personal working copy of the files on his local machine.  Committing changes to the repository, and picking up changes from other users into one's own working area, then works by direct interactions with the CVS server.

One difficulty is that access to the CVS server is often slow, and that developers might need to work off-line as well.  VC is designed to reduce the amount of network interaction necessary.

Version Backups
...............

When VC sees that the CVS repository for a file is on a remote machine, it automatically makes local backups of unmodified versions of the file---automatic version backups.  This means that you can compare the file to the repository version (C-x v =), or revert to that version (C-x v u), without any network interactions.

The local copy of the unmodified file is called a version backup to indicate that it corresponds exactly to a version that is stored in the repository.  Note that version backups are not the same as ordinary Emacs backup files (see Backup). But they follow a similar naming convention.

For a file that comes from a remote CVS repository, VC makes a version backup whenever you save the first changes to the file, and removes it after you have committed your modified version to the repository. You can disable the making of automatic version backups by setting vc-cvs-stay-local to nil (see CVS Options).

The name of the automatic version backup for version VERSION of file FILE is FILE.~VERSION.~.  This is almost the same as the name used by C-x v ~ (see Old Versions), the only difference being the additional dot (.)  after the version number.  This similarity is intentional, because both kinds of files store the same kind of information.  The file made by C-x v ~ acts as a manual version backup.

All the VC commands that operate on old versions of a file can use both kinds of version backups.  For instance, C-x v ~ uses either an automatic or a manual version backup, if possible, to get the contents of the version you request.  Likewise, C-x v = and C-x v u use either an automatic or a manual version backup, if one of them exists, to get the contents of a version to compare or revert to.  If you changed a file outside of Emacs, so that no automatic version backup was created for the previous text, you can create a manual backup of that version using C-x v ~, and thus obtain the benefit of the local copy for Emacs commands.

The only difference in Emacs's handling of manual and automatic version backups, once they exist, is that Emacs deletes automatic version backups when you commit to the repository.  By contrast, manual version backups remain until you delete them.

Local Version Control
.....................

When you make many changes to a file that comes from a remote repository, it can be convenient to have version control on your local machine as well.  You can then record intermediate versions, revert to a previous state, etc., before you actually commit your changes to the remote server.

VC lets you do this by putting a file under a second, local version control system, so that the file is effectively registered in two systems at the same time.  For the description here, we will assume that the remote system is CVS, and you use RCS locally, although the mechanism works with any combination of version control systems (back ends).

To make it work with other back ends, you must make sure that the ``more local'' back end comes before the ``more remote'' back end in the setting of vc-handled-backends (see Customizing VC).  By default, this variable is set up so that you can use remote CVS and local RCS as described here.

To start using local RCS for a file that comes from a remote CVS server, you must register the file in RCS, by typing C-u C-x v v rcs RET.  (In other words, use vc-next-action with a prefix argument, and specify RCS as the back end.)

You can do this at any time; it does not matter whether you have already modified the file with respect to the version in the CVS repository.  If possible, VC tries to make the RCS master start with the unmodified repository version, then checks in any local changes as a new version.  This works if you have not made any changes yet, or if the unmodified repository version exists locally as a version backup (see Version Backups).  If the unmodified version is not available locally, the RCS master starts with the modified version; the only drawback to this is that you cannot compare your changes locally to what is stored in the repository.

The version number of the RCS master is derived from the current CVS version, starting a branch from it.  For example, if the current CVS version is 1.23, the local RCS branch will be 1.23.1.  Version 1.23 in the RCS master will be identical to version 1.23 under CVS; your first changes are checked in as 1.23.1.1.  (If the unmodified file is not available locally, VC will check in the modified file twice, both as 1.23 and 1.23.1.1, to make the revision numbers consistent.)

If you do not use locking under CVS (the default), locking is also disabled for RCS, so that editing under RCS works exactly as under CVS.

When you are done with local editing, you can commit the final version back to the CVS repository by typing C-u C-x v v cvs RET. This initializes the log entry buffer (see Log Buffer) to contain all the log entries you have recorded in the RCS master; you can edit them as you wish, and then commit in CVS by typing C-c C-c.  If the commit is successful, VC removes the RCS master, so that the file is once again registered under CVS only. (The RCS master is not actually deleted, just renamed by appending ~ to the name, so that you can refer to it later if you wish.)

While using local RCS, you can pick up recent changes from the CVS repository into your local file, or commit some of your changes back to CVS, without terminating local RCS version control.  To do this, switch to the CVS back end temporarily, with the C-x v b command:

C-x v b
     Switch to another back end that the current file is registered under (vc-switch-backend).

C-u C-x v b BACKEND RET
     Switch to BACKEND for the current file.

C-x v b does not change the buffer contents, or any files; it only changes VC's perspective on how to handle the file.  Any subsequent VC commands for that file will operate on the back end that is currently selected.

If the current file is registered in more than one back end, typing C-x v b ``cycles'' through all of these back ends.  With a prefix argument, it asks for the back end to use in the minibuffer.

Thus, if you are using local RCS, and you want to pick up some recent changes in the file from remote CVS, first visit the file, then type C-x v b to switch to CVS, and finally use C-x v m RET to merge the news (see Merging). You can then switch back to RCS by typing C-x v b again, and continue to edit locally.

But if you do this, the revision numbers in the RCS master no longer correspond to those of CVS.  Technically, this is not a problem, but it can become difficult to keep track of what is in the CVS repository and what is not.  So we suggest that you return from time to time to CVS-only operation, by committing your local changes back to the repository using C-u C-x v v cvs RET.

Snapshots
---------

A snapshot is a named set of file versions (one for each registered file) that you can treat as a unit.  One important kind of snapshot is a release, a (theoretically) stable version of the system that is ready for distribution to users.

Making and Using Snapshots
..........................

There are two basic commands for snapshots; one makes a snapshot with a given name, the other retrieves a named snapshot.

C-x v s NAME RET
     Define the last saved versions of every registered file in or under the current directory as a snapshot named NAME (vc-create-snapshot).

C-x v r NAME RET
     For all registered files at or below the current directory level, select whatever versions correspond to the snapshot NAME (vc-retrieve-snapshot).

     This command reports an error if any files are locked at or below the current directory, without changing anything; this is to avoid overwriting work in progress.

A snapshot uses a very small amount of resources---just enough to record the list of file names and which version belongs to the snapshot.  Thus, you need not hesitate to create snapshots whenever they are useful.

You can give a snapshot name as an argument to C-x v = or C-x v ~ (see Old Versions). Thus, you can use it to compare a snapshot against the current files, or two snapshots against each other, or a snapshot against a named version.

Snapshot Caveats
................

VC's snapshot facilities are modeled on RCS's named-configuration support.  They use RCS's native facilities for this, so snapshots made using RCS through VC are visible even when you bypass VC.

With CVS, Meta-CVS, and Subversion, VC also uses the native mechanism provided by that back end to make snapshots and retrieve them (tags for CVS and Meta-CVS, copies for Subversion).

For SCCS, VC implements snapshots itself.  The files it uses contain name/file/version-number triples.  These snapshots are visible only through VC.

There is no support for VC snapshots using GNU Arch yet.

A snapshot is a set of checked-in versions.  So make sure that all the files are checked in and not locked when you make a snapshot.

File renaming and deletion can create some difficulties with snapshots. This is not a VC-specific problem, but a general design issue in version control systems that no one has solved very well yet.

If you rename a registered file, you need to rename its master along with it (the command vc-rename-file does this automatically).  If you are using SCCS, you must also update the records of the snapshot, to mention the file by its new name (vc-rename-file does this, too).  An old snapshot that refers to a master file that no longer exists under the recorded name is invalid; VC can no longer retrieve it.  It would be beyond the scope of this manual to explain enough about RCS and SCCS to explain how to update the snapshots by hand.

Using vc-rename-file makes the snapshot remain valid for retrieval, but it does not solve all problems.  For example, some of the files in your program probably refer to others by name.  At the very least, the makefile probably mentions the file that you renamed.  If you retrieve an old snapshot, the renamed file is retrieved under its new name, which is not the name that the makefile expects.  So the program won't really work as retrieved.

Miscellaneous Commands and Features of VC
-----------------------------------------

This section explains the less-frequently-used features of VC.

Change Logs and VC
..................

If you use RCS or CVS for a program and also maintain a change log file for it (see Change Log), you can generate change log entries automatically from the version control log entries:

C-x v a
     Visit the current directory's change log file and, for registered files in that directory, create new entries for versions checked in since the most recent entry in the change log file. (vc-update-change-log).

     This command works with RCS or CVS only, not with any of the other back ends.

C-u C-x v a
     As above, but only find entries for the current buffer's file.

M-1 C-x v a
     As above, but find entries for all the currently visited files that are maintained with version control.  This works only with RCS, and it puts all entries in the log for the default directory, which may not be appropriate.

For example, suppose the first line of ChangeLog is dated 1999-04-10, and that the only check-in since then was by Nathaniel Bowditch to rcs2log on 1999-05-22 with log text Ignore log messages that start with `#'..  Then C-x v a visits ChangeLog and inserts text like this:

     1999-05-22  Nathaniel Bowditch  <nat@apn.org>

             * rcs2log: Ignore log messages that start with `#'.

You can then edit the new change log entry further as you wish.

Some of the new change log entries may duplicate what's already in ChangeLog.  You will have to remove these duplicates by hand.

Normally, the log entry for file foo is displayed as * foo: TEXT OF LOG ENTRY.  The : after foo is omitted if the text of the log entry starts with (FUNCTIONNAME): .  For example, if the log entry for vc.el is (vc-do-command): Check call-process status., then the text in ChangeLog looks like this:

     1999-05-06  Nathaniel Bowditch  <nat@apn.org>

             * vc.el (vc-do-command): Check call-process status.

When C-x v a adds several change log entries at once, it groups related log entries together if they all are checked in by the same author at nearly the same time.  If the log entries for several such files all have the same text, it coalesces them into a single entry. For example, suppose the most recent check-ins have the following log entries:

* For vc.texinfo: Fix expansion typos.
* For vc.el: Don't call expand-file-name.
* For vc-hooks.el: Don't call expand-file-name.

They appear like this in ChangeLog:

     1999-04-01  Nathaniel Bowditch  <nat@apn.org>

             * vc.texinfo: Fix expansion typos.

             * vc.el, vc-hooks.el: Don't call expand-file-name.

Normally, C-x v a separates log entries by a blank line, but you can mark several related log entries to be clumped together (without an intervening blank line) by starting the text of each related log entry with a label of the form {CLUMPNAME} .  The label itself is not copied to ChangeLog.  For example, suppose the log entries are:

* For vc.texinfo: {expand} Fix expansion typos.
* For vc.el: {expand} Don't call expand-file-name.
* For vc-hooks.el: {expand} Don't call expand-file-name.

Then the text in ChangeLog looks like this:

     1999-04-01  Nathaniel Bowditch  <nat@apn.org>

             * vc.texinfo: Fix expansion typos.
             * vc.el, vc-hooks.el: Don't call expand-file-name.

A log entry whose text begins with # is not copied to ChangeLog.  For example, if you merely fix some misspellings in comments, you can log the change with an entry beginning with # to avoid putting such trivia into ChangeLog.

Renaming VC Work Files and Master Files
.......................................

When you rename a registered file, you must also rename its master file correspondingly to get proper results.  Use vc-rename-file to rename the source file as you specify, and rename its master file accordingly.  It also updates any snapshots (see Snapshots) that mention the file, so that they use the new name; despite this, the snapshot thus modified may not completely work (see Snapshot Caveats).

Some back ends do not provide an explicit rename operation to their repositories.  After issuing vc-rename-file, use C-x v v on the original and renamed buffers and provide the necessary edit log.

You cannot use vc-rename-file on a file that is locked by someone else.

Inserting Version Control Headers
.................................

Sometimes it is convenient to put version identification strings directly into working files.  Certain special strings called version headers are replaced in each successive version by the number of that version, the name of the user who created it, and other relevant information.  All of the back ends that VC supports have such a mechanism, except GNU Arch.

VC does not normally use the information contained in these headers. The exception is RCS---with RCS, version headers are sometimes more reliable than the master file to determine which version of the file you are editing.  Note that in a multi-branch environment, version headers are necessary to make VC behave correctly (see Multi-User Branching).

Searching for RCS version headers is controlled by the variable vc-consult-headers.  If it is non-nil (the default), Emacs searches for headers to determine the version number you are editing.  Setting it to nil disables this feature.

Note that although CVS uses the same kind of version headers as RCS does, VC never searches for these headers if you are using CVS, regardless of the above setting.

You can use the C-x v h command (vc-insert-headers) to insert a suitable header string.

C-x v h
     Insert headers in a file for use with your version-control system.

The default header string is $Id$ for RCS and %W% for SCCS.  You can specify other headers to insert by setting the variables vc-BACKEND-header where BACKEND is rcs or sccs.

Instead of a single string, you can specify a list of strings; then each string in the list is inserted as a separate header on a line of its own.

It may be necessary to use apparently-superfluous backslashes when writing the strings that you put in this variable.  For instance, you might write "$Id\$" rather than "$Id$".  The extra backslash prevents the string constant from being interpreted as a header, if the Emacs Lisp file containing it is maintained with version control.

Each header is inserted surrounded by tabs, inside comment delimiters, on a new line at point.  Normally the ordinary comment start and comment end strings of the current mode are used, but for certain modes, there are special comment delimiters for this purpose; the variable vc-comment-alist specifies them.  Each element of this list has the form (MODE STARTER ENDER).

The variable vc-static-header-alist specifies further strings to add based on the name of the buffer.  Its value should be a list of elements of the form (REGEXP . FORMAT).  Whenever REGEXP matches the buffer name, FORMAT is inserted as part of the header.  A header line is inserted for each element that matches the buffer name, and for each string specified by vc-BACKEND-header.  The header line is made by processing the string from vc-BACKEND-header with the format taken from the element.  The default value for vc-static-header-alist is as follows:

     (("\\.c$" .
       "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n\
     #endif /* lint */\n"))

It specifies insertion of text of this form:

     #ifndef lint
     static char vcid[] = "STRING";
     #endif /* lint */

Note that the text above starts with a blank line.

If you use more than one version header in a file, put them close together in the file.  The mechanism in revert-buffer that preserves markers may not handle markers positioned between two version headers.

Customizing VC
--------------

The variable vc-handled-backends determines which version control systems VC should handle.  The default value is (RCS CVS SVN SCCS GIT HG Arch MCVS), so it contains all six version systems that are currently supported.  If you want VC to ignore one or more of these systems, exclude its name from the list.  To disable VC entirely, set this variable to nil.

The order of systems in the list is significant: when you visit a file registered in more than one system (see Local Version Control), VC uses the system that comes first in vc-handled-backends by default.  The order is also significant when you register a file for the first time, see Registering, for details.

General Options
...............

Emacs normally does not save backup files for source files that are maintained with version control.  If you want to make backup files even for files that use version control, set the variable vc-make-backup-files to a non-nil value.

Normally the work file exists all the time, whether it is locked or not.  If you set vc-keep-workfiles to nil, then checking in a new version with C-x v v deletes the work file; but any attempt to visit the file with Emacs creates it again.  (With CVS, work files are always kept.)

Editing a version-controlled file through a symbolic link can be dangerous.  It bypasses the version control system---you can edit the file without locking it, and fail to check your changes in.  Also, your changes might overwrite those of another user.  To protect against this, VC checks each symbolic link that you visit, to see if it points to a file under version control.

The variable vc-follow-symlinks controls what to do when a symbolic link points to a version-controlled file.  If it is nil, VC only displays a warning message.  If it is t, VC automatically follows the link, and visits the real file instead, telling you about this in the echo area.  If the value is ask (the default), VC asks you each time whether to follow the link.

If vc-suppress-confirm is non-nil, then C-x v v and C-x v i can save the current buffer without asking, and C-x v u also operates without asking for confirmation.  (This variable does not affect C-x v c; that operation is so drastic that it should always ask for confirmation.)

VC mode does much of its work by running the shell commands for RCS, CVS and SCCS.  If vc-command-messages is non-nil, VC displays messages to indicate which shell commands it runs, and additional messages when the commands finish.

You can specify additional directories to search for version control programs by setting the variable vc-path.  These directories are searched before the usual search path.  It is rarely necessary to set this variable, because VC normally finds the proper files automatically.

Options for RCS and SCCS
........................

By default, RCS uses locking to coordinate the activities of several users, but there is a mode called non-strict locking in which you can check-in changes without locking the file first.  Use rcs -U to switch to non-strict locking for a particular file, see the rcs manual page for details.

When deducing the version control state of an RCS file, VC first looks for an RCS version header string in the file (see Version Headers).  If there is no header string, VC normally looks at the file permissions of the work file; this is fast.  But there might be situations when the file permissions cannot be trusted.  In this case the master file has to be consulted, which is rather expensive.  Also the master file can only tell you if there's any lock on the file, but not whether your work file really contains that locked version.

You can tell VC not to use version headers to determine the file status by setting vc-consult-headers to nil.  VC then always uses the file permissions (if it is supposed to trust them), or else checks the master file.

You can specify the criterion for whether to trust the file permissions by setting the variable vc-mistrust-permissions. Its value can be t (always mistrust the file permissions and check the master file), nil (always trust the file permissions), or a function of one argument which makes the decision. The argument is the directory name of the RCS subdirectory.  A non-nil value from the function says to mistrust the file permissions.  If you find that the file permissions of work files are changed erroneously, set vc-mistrust-permissions to t. Then VC always checks the master file to determine the file's status.

VC determines the version control state of files under SCCS much as with RCS.  It does not consider SCCS version headers, though.  Thus, the variable vc-mistrust-permissions affects SCCS use, but vc-consult-headers does not.

Options specific for CVS
........................

By default, CVS does not use locking to coordinate the activities of several users; anyone can change a work file at any time.  However, there are ways to restrict this, resulting in behavior that resembles locking.

For one thing, you can set the CVSREAD environment variable (the value you use makes no difference).  If this variable is defined, CVS makes your work files read-only by default.  In Emacs, you must type C-x v v to make the file writable, so that editing works in fact similar as if locking was used.  Note however, that no actual locking is performed, so several users can make their files writable at the same time.  When setting CVSREAD for the first time, make sure to check out all your modules anew, so that the file protections are set correctly.

Another way to achieve something similar to locking is to use the watch feature of CVS.  If a file is being watched, CVS makes it read-only by default, and you must also use C-x v v in Emacs to make it writable.  VC calls cvs edit to make the file writable, and CVS takes care to notify other developers of the fact that you intend to change the file.  See the CVS documentation for details on using the watch feature.

When a file's repository is on a remote machine, VC tries to keep network interactions to a minimum.  This is controlled by the variable vc-cvs-stay-local.  There is another variable, vc-stay-local, which enables the feature also for other back ends that support it, including CVS.  In the following, we will talk only about vc-cvs-stay-local, but everything applies to vc-stay-local as well.

If vc-cvs-stay-local is t (the default), then VC uses only the entry in the local CVS subdirectory to determine the file's state (and possibly information returned by previous CVS commands). One consequence of this is that when you have modified a file, and somebody else has already checked in other changes to the file, you are not notified of it until you actually try to commit.  (But you can try to pick up any recent changes from the repository first, using C-x v m RET, see Merging).

When vc-cvs-stay-local is t, VC also makes local version backups, so that simple diff and revert operations are completely local (see Version Backups).

On the other hand, if you set vc-cvs-stay-local to nil, then VC queries the remote repository before it decides what to do in vc-next-action (C-x v v), just as it does for local repositories.  It also does not make any version backups.

You can also set vc-cvs-stay-local to a regular expression that is matched against the repository host name; VC then stays local only for repositories from hosts that match the pattern.

You can specify additional command line options to pass to all CVS operations in the variable vc-cvs-global-switches.  These switches are inserted immediately after the cvs command, before the name of the operation to invoke.