Skip to main content

28.1.12 Miscellaneous Commands and Features of VC

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

• Change Logs and VC  Generating a change log file from log entries.
• VC Delete/Rename  Deleting and renaming version-controlled files.
• Revision Tags  Symbolic names for revisions.
• Version Headers  Inserting version control headers into working files.

28.1.12.1 Change Logs and VC​

If you use RCS or CVS for a program with a ChangeLog file (see Change Log), you can generate change log entries from the version control log entries of previous commits.

Note that this only works with RCS or CVS. This procedure would be particularly incorrect on a modern changeset-based version control system, where changes to the ChangeLog file would normally be committed as part of a changeset. In that case, you should write the change log entries first, then pull them into the ‘*vc-log*’ buffer when you commit (see Log Buffer).

C-x v a​

Visit the current directory’s ChangeLog file and, for registered files in that directory, create new entries for versions committed since the most recent change log entry (vc-update-change-log).

C-u C-x v a​

As above, but only find entries for the current buffer’s file.

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 entry ‘Ignore log messages that start with '#'.’. Then C-x v a inserts this ChangeLog entry:

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

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

If the version control log entry specifies a function name (in parenthesis at the beginning of a line), that is reflected in the ChangeLog entry. For example, if a log entry for vc.el is ‘(vc-do-command): Check call-process status.’, the ChangeLog entry is:

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.

28.1.12.2 Deleting and Renaming Version-Controlled Files​

M-x vc-delete-file​

Prompt for a file name, delete the file from the working tree, and schedule the deletion for committing.

M-x vc-rename-file​

Prompt for two file names, old and new, rename them in the working tree, and schedule the renaming for committing. The old file defaults to the current buffer’s file name if it is under VC.

If you wish to delete a version-controlled file, use the command M-x vc-delete-file. This prompts for the file name, and deletes it via the version control system. The file is removed from the working tree, and in the VC Directory buffer (see VC Directory Mode), it is displayed with the ‘removed’ status. When you commit it, the deletion takes effect in the repository.

To rename a version-controlled file, type M-x vc-rename-file. This prompts for two arguments: the name of the file you wish to rename, and the new name; then it performs the renaming via the version control system. The renaming takes effect immediately in the working tree, and takes effect in the repository when you commit the renamed file.

On modern version control systems that have built-in support for renaming, the renamed file retains the full change history of the original file. On CVS and older version control systems, the vc-rename-file command actually works by creating a copy of the old file under the new name, registering it, and deleting the old file. In this case, the change history is not preserved.

28.1.12.3 Revision Tags​

Most version control systems allow you to apply a revision tag to a specific version of a version-controlled tree. On modern changeset-based version control systems, a revision tag is simply a symbolic name for a particular revision. On older file-based systems like CVS, each tag is added to the entire set of version-controlled files, allowing them to be handled as a unit. Revision tags are commonly used to identify releases that are distributed to users.

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

C-x v s name RET​

Define the working revision of every registered file in or under the current directory as a tag named name (vc-create-tag).

C-x v r name RET​

For all registered files at or below the current directory level, retrieve the tagged revision name. This command will switch to a branch if name is a branch name and your VCS distinguishes branches from tags. (vc-retrieve-tag).

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.

You can give a tag or branch name as an argument to C-x v = or C-x v ~ (see Old Revisions). Thus, you can use it to compare a tagged version against the current files, or two tagged versions against each other.

On SCCS, VC implements tags itself; these tags are visible only through VC. Most later systems (including CVS, Subversion, bzr, git, and hg) have a native tag facility, and VC uses it where available; those tags will be visible even when you bypass VC.

In file-based version control systems, when you rename a registered file you need to rename its master along with it; the command vc-rename-file will do this automatically (see VC Delete/Rename). If you are using SCCS, you must also update the records of the tag, to mention the file by its new name (vc-rename-file does this, too). An old tag 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 tags by hand. Using vc-rename-file makes the tag 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 tag, 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.

28.1.12.4 Inserting Version Control Headers​

On Subversion, CVS, RCS, and SCCS, you can put certain special strings called version headers into a work file. When the file is committed, the version control system automatically puts the revision number, the name of the user who made the commit, and other relevant information into the version header.

VC does not normally use the information in the version headers. As an exception, when using RCS, Emacs uses the version header, if there is one, to determine the file version, since it is often more reliable than the RCS master file. To inhibit using the version header this way, change the variable 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.

To insert a suitable header string into the current buffer, use the command M-x vc-insert-headers. This command works only on Subversion, CVS, RCS, and SCCS. The variable vc-backend-header contains the list of keywords to insert into the version header; for instance, CVS uses vc-cvs-header, whose default value is '("\$Id\$"). (The extra backslashes prevent the string constant from being interpreted as a header, if the Emacs Lisp file defining it is maintained with version control.) The vc-insert-headers command inserts each keyword in the list on a new line at point, surrounded by tabs, and inside comment delimiters if necessary.

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 also inserted as part of the version header. A ‘%s’ in format is replaced with the file’s version control type.