ErgoEmacsEmacsLispBlogEmacsLispBuy Tutorial
Web Hosting by 1&1

32.1.5 Examining And Comparing Old Revisions

One of the convenient features of version control is the ability to examine any revision of a file, or compare two revisions.

C-x v ~
Prompt for a revision of the current file, and visit it in a buffer of its own (vc-revision-other-window).
C-x v =
Compare the files in the current fileset with the working revision(s) you started from (vc-diff). With a prefix argument, prompt for two revisions of the current fileset and compare them. You can call this command from a Dired buffer (see Dired).
C-x v D
Compare the entire tree corresponding to the current fileset with the tree you started from (vc-root-diff). With a prefix argument, prompt for two revisions and compare their trees.
C-x v g
Display an annotated version of the file: for each line, show the latest revision in which it was modified (vc-annotate).

To examine an old revision, visit the work file and type C-x v ~ revision <RET> (vc-revision-other-window). Here, revision is either the desired revision ID (see VCS Concepts), or the name of a tag or branch (see Tags). This command puts the text of the old revision in a file named filename.~revision~, and visits it in its own buffer in a separate window.

C-x v = (vc-diff) compares each file in the current VC fileset (saving them if necessary) with the repository revision(s) from which you started editing. Note that the latter may or may not be the latest revision of the file(s).

The diff is displayed in another window, in a Diff mode buffer (see Diff Mode) named *vc-diff*. In this buffer, the g (revert-buffer) command performs the file comparison again, generating a new diff.

To compare two arbitrary revisions of the current VC fileset, call vc-diff with a prefix argument: C-u C-x v =. This prompts for two revision IDs, using the minibuffer, and displays the diff in a special buffer in another window. Instead of providing a revision ID, you can give an empty input, which specifies the current contents of the work file; or a tag or branch name (see Tags). If your version control system is file-based (⁖ CVS) rather than changeset-based (Subversion, GNU Arch, git, Mercurial), supplying a revision ID for a multi-file fileset (as opposed to a symbolic tag name) is unlikely to return diffs that are connected in any meaningful way.

The command C-x v D (vc-root-diff) is similar to C-x v =, but it compares the entire tree associated with the current VC fileset with the tree you started with. This means all the files controlled by the current version control repository, even those that are not part of the current VC fileset.

If you invoke C-x v = or C-u C-x v = from a buffer that is neither visiting a version-controlled file nor a VC directory buffer, these commands generate a diff of all registered files in the current directory and its subdirectories.

C-x v = works by running a variant of the diff utility designed to work with the version control system in use. The options to pass to the diff command are taken from the first non-nil value of vc-backend-diff-switches, vc-diff-switches, and diff-switches (see Comparing Files), in that order. Since nil means to check the next variable in the sequence, either of the first two may use the value t to mean no switches at all. Most of the ‘vc...diff-switches’ variables default to nil, but some default to t. These are for those version control systems (⁖ SVN) whose diff implementations do not accept common options (⁖ ‘-c’) likely to be in diff-switches.

The buffer produced by C-x v = supports the commands of Compilation mode (see Compilation Mode), such as C-x ` and C-c C-c, in both the “old” and “new” text, and they always find the corresponding locations in the current work file. (Older revisions are not, in general, present as files on your disk.)

For some back ends, you can display the file annotated with per-line revision information, by typing C-x v g (vc-annotate). This creates a new buffer (the “annotate buffer”) displaying the file's text, with each part colored to show how old it is. Text colored red is new, blue means old, and intermediate colors indicate intermediate ages. By default, the color is scaled over the full range of ages, such that the oldest changes are blue, and the newest changes are red.

When you give a prefix argument to this command, Emacs reads two arguments using the minibuffer: the ID of which revision to display and annotate (instead of the current file contents), and the time span in days the color range should cover.

From the annotate buffer, these and other color scaling options are available from the ‘VC-Annotate’ menu. In this buffer, you can also use the following keys to browse the annotations of past revisions, view diffs, or view log entries:

p
Annotate the previous revision, that is to say, the revision before the one currently annotated. A numeric prefix argument is a repeat count, so C-u 10 p would take you back 10 revisions.
n
Annotate the next revision—the one after the revision currently annotated. A numeric prefix argument is a repeat count.
j
Annotate the revision indicated by the current line.
a
Annotate the revision before the one indicated by the current line. This is useful to see the state the file was in before the change on the current line was made.
f
Show in a buffer the file revision indicated by the current line.
d
Display the diff between the current line's revision and the previous revision. This is useful to see what the current line's revision actually changed in the file.
D
Display the diff between the current line's revision and the previous revision for all files in the changeset (for VC systems that support changesets). This is useful to see what the current line's revision actually changed in the tree.
l
Show the log of the current line's revision. This is useful to see the author's description of the changes in the revision on the current line.
w
Annotate the working revision–the one you are editing. If you used p and n to browse to other revisions, use this key to return to your working revision.
v
Toggle the annotation visibility. This is useful for looking just at the file contents without distraction from the annotations.
blog comments powered by Disqus