*** empty log message ***
[bpt/emacs.git] / lisp / vc.el
index 6d7d3e9..2d879b3 100644 (file)
@@ -1,11 +1,11 @@
 ;;; vc.el --- drive a version-control system from within Emacs
 
-;; Copyright (C) 1992,93,94,95,96,97,98,2000  Free Software Foundation, Inc.
+;; Copyright (C) 1992,93,94,95,96,97,98,2000,2001  Free Software Foundation, Inc.
 
 ;; Author:     FSF (see below for full credits)
 ;; Maintainer: Andre Spiegel <spiegel@gnu.org>
 
-;; $Id: vc.el,v 1.283 2000/10/26 12:38:02 fx Exp $
+;; $Id: vc.el,v 1.298 2001/03/10 10:44:35 spiegel Exp $
 
 ;; This file is part of GNU Emacs.
 
 ;;
 ;; Developer's notes on some concurrency issues are included at the end of
 ;; the file.
-
-;;; Code:
-
-;;;;;;;;;;;;;;;;; Backend-specific functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
-;; for each operation FUN, the backend should provide a function vc-BACKEND-FUN.
-;; Operations marked with a `-' instead of a `*' are optional.
-
+;; ADDING SUPPORT FOR OTHER BACKENDS
+;;
+;; VC can use arbitrary version control systems as a backend.  To add
+;; support for a new backend named SYS, write a library vc-sys.el that
+;; contains functions of the form `vc-sys-...' (note that SYS is in lower
+;; case for the function and library names).  VC will use that library if
+;; you put the symbol SYS somewhere into the list of
+;; `vc-handled-backends'.  Then, for example, if `vc-sys-registered'
+;; returns non-nil for a file, all SYS-specific versions of VC commands
+;; will be available for that file.
+;;
+;; VC keeps some per-file information in the form of properties (see
+;; vc-file-set/getprop in vc-hooks.el).  The backend-specific functions
+;; do not generally need to be aware of these properties.  For example,
+;; `vc-sys-workfile-version' should compute the workfile version and
+;; return it; it should not look it up in the property, and it needn't
+;; store it there either.  However, if a backend-specific function does
+;; store a value in a property, that value takes precedence over any
+;; value that the generic code might want to set (check for uses of 
+;; the macro `with-vc-properties' in vc.el).
+;;
+;; In the list of functions below, each identifier needs to be prepended
+;; with `vc-sys-'.  Some of the functions are mandatory (marked with a
+;; `*'), others are optional (`-').
+;;
+;; STATE-QUERYING FUNCTIONS
+;;
 ;; * registered (file)
-;; * state (file)
+;;
+;;   Return non-nil if FILE is registered in this backend.
+;;
+;; * state (file) 
+;;
+;;   Return the current version control state of FILE.  For a list of
+;;   possible values, see `vc-state'.  This function should do a full and
+;;   reliable state computation; it is usually called immediately after
+;;   C-x v v.  If you want to use a faster heuristic when visiting a
+;;   file, put that into `state-heuristic' below.
+;;
 ;; - state-heuristic (file)
-;;     The default behavior delegates to `state'.
+;;
+;;   If provided, this function is used to estimate the version control
+;;   state of FILE at visiting time.  It should be considerably faster
+;;   than the implementation of `state'.  For a list of possible values,
+;;   see the doc string of `vc-state'.
+;;
 ;; - dir-state (dir)
+;;
+;;   If provided, this function is used to find the version control state
+;;   of all files in DIR in a fast way.  The function should not return
+;;   anything, but rather store the files' states into the corresponding
+;;   `vc-state' properties.
+;;
+;; * workfile-version (file)
+;;
+;;   Return the current workfile version of FILE.
+;;
+;; - latest-on-branch-p (file)
+;;
+;;   Return non-nil if the current workfile version of FILE is the latest
+;;   on its branch.  The default implementation always returns t, which
+;;   means that working with non-current versions is not supported by
+;;   default.
+;;
 ;; * checkout-model (file)
+;;
+;;   Indicate whether FILE needs to be "checked out" before it can be
+;;   edited.  See `vc-checkout-model' for a list of possible values.
+;;
+;; - workfile-unchanged-p (file)
+;;
+;;   Return non-nil if FILE is unchanged from its current workfile
+;;   version.  This function should do a brief comparison of FILE's
+;;   contents with those of the master version.  If the backend does not
+;;   have such a brief-comparison feature, the default implementation of
+;;   this function can be used, which delegates to a full
+;;   vc-BACKEND-diff.
+;;
 ;; - mode-line-string (file)
-;; * workfile-version (file)
-;; * revert (file)
-;; - merge-news (file)
-;;     Only needed if state `needs-merge' is possible.
-;; - merge (file rev1 rev2)
-;; - steal-lock (file &optional version)
-;;     Only required if files can be locked by somebody else.
-;; * register (file rev comment)
-;; * unregister (file backend)
-;; - receive-file (file rev)
+;;
+;;   If provided, this function should return the VC-specific mode line
+;;   string for FILE.  The default implementation deals well with all
+;;   states that `vc-state' can return.
+;;
+;; - dired-state-info (file)
+;;
+;;   Translate the `vc-state' property of FILE into a string that can be
+;;   used in a vc-dired buffer.  The default implementation deals well
+;;   with all states that `vc-state' can return.
+;;
+;; STATE-CHANGING FUNCTIONS
+;;
+;; * register (file &optional rev comment)
+;;
+;;   Register FILE in this backend.  Optionally, an initial revision REV
+;;   and an initial description of the file, COMMENT, may be specified.
+;;
 ;; - responsible-p (file)
-;;     Should also work if FILE is a directory (ends with a slash).
+;;
+;;   Return non-nil if this backend considers itself "responsible" for
+;;   FILE, which can also be a directory.  This function is used to find
+;;   out what backend to use for registration of new files and for things
+;;   like change log generation.  The default implementation always
+;;   returns nil.
+;;
 ;; - could-register (file)
-;; * checkout (file writable &optional rev destfile)
-;;     Checkout revision REV of FILE into DESTFILE.
-;;     DESTFILE defaults to FILE.
-;;     The file should be made writable if WRITABLE is non-nil.
-;;     REV can be nil (BASE) or "" (HEAD) or any other revision.
+;;
+;;   Return non-nil if FILE could be registered under this backend.  The
+;;   default implementation always returns t.
+;;
+;; - receive-file (file rev)
+;;
+;;   Let this backend "receive" a file that is already registered under
+;;   another backend.  The default implementation simply calls `register'
+;;   for FILE, but it can be overridden to do something more specific,
+;;   e.g. keep revision numbers consistent or choose editing modes for
+;;   FILE that resemble those of the other backend.
+;;
+;; - unregister (file)
+;;
+;;   Unregister FILE from this backend.  This is only needed if this
+;;   backend may be used as a "more local" backend for temporary editing.
+;;
 ;; * checkin (file rev comment)
-;; - logentry-check ()
-;; * diff (file &optional rev1 rev2)
-;;     Insert the diff for FILE into the current buffer.
-;;     REV1 should default to workfile-version.
-;;     REV2 should default to the current workfile
-;;     Return a status of either 0 (i.e. no diff) or 1 (i.e. either non-empty
-;;     diff or the diff is run asynchronously).
-;; - workfile-unchanged-p (file)
-;;     Return non-nil if FILE is unchanged from its current workfile version.
-;;     This function should do a brief comparison of FILE's contents
-;;     with those of the master version.  If the backend does not have
-;;     such a brief-comparison feature, the default implementation of this
-;;     function can be used, which delegates to a full vc-BACKEND-diff.
-;; - clear-headers ()
-;; * check-headers ()
-;; - dired-state-info (file)
-;; - create-snapshot (dir name branchp)
-;;     Take a snapshot of the current state of files under DIR and name it NAME.
-;;     This should make sure that files are up-to-date before proceeding
-;;     with the action.
-;;     DIR can also be a file and if BRANCHP is specified, NAME
-;;     should be created as a branch and DIR should be checked out under
-;;     this new branch.  The default behavior does not support branches
-;;     but does a sanity check, a tree traversal and for each file calls
-;;     `assign-name'.
-;; * assign-name (file name)
-;;     Give name NAME to the current version of FILE, assuming it is
-;;     up-to-date.  Only used by the default version of `create-snapshot'.
-;; - retrieve-snapshot (dir name update)
-;;     Retrieve a named snapshot of all registered files at or below DIR.
-;;     If UPDATE is non-nil, then update buffers of any files in the snapshot
-;;     that are currently visited.
+;;
+;;   Commit changes in FILE to this backend.  If REV is non-nil, that
+;;   should become the new revision number.  COMMENT is used as a
+;;   check-in comment.
+;;
+;; * checkout (file &optional editable rev destfile)
+;;
+;;   Check out revision REV of FILE into the working area.  If EDITABLE
+;;   is non-nil, FILE should be writable by the user and if locking is
+;;   used for FILE, a lock should also be set.  If REV is non-nil, that
+;;   is the revision to check out (default is current workfile version);
+;;   if REV is the empty string, that means to check out the head of the
+;;   trunk.  If optional arg DESTFILE is given, it is an alternate
+;;   filename to write the contents to.
+;;
+;; * revert (file)
+;;
+;;   Revert FILE back to the current workfile version.
+;;
+;; - cancel-version (file editable)
+;;
+;;   Cancel the current workfile version of FILE, i.e. remove it from the
+;;   master.  EDITABLE non-nil means that FILE should be writable
+;;   afterwards, and if locking is used for FILE, then a lock should also
+;;   be set.  If this function is not provided, trying to cancel a
+;;   version is caught as an error.
+;;
+;; - merge (file rev1 rev2)
+;;
+;;   Merge the changes between REV1 and REV2 into the current working file.
+;;
+;; - merge-news (file)
+;;
+;;   Merge recent changes from the current branch into FILE.
+;;
+;; - steal-lock (file &optional version)
+;;
+;;   Steal any lock on the current workfile version of FILE, or on
+;;   VERSION if that is provided.  This function is only needed if
+;;   locking is used for files under this backend, and if files can
+;;   indeed be locked by other users.
+;;
+;; HISTORY FUNCTIONS
+;;
 ;; * print-log (file)
-;;     Insert the revision log of FILE into the current buffer.
+;;
+;;   Insert the revision log of FILE into the *vc* buffer.
+;;
 ;; - show-log-entry (version)
+;;
+;;   If provided, search the log entry for VERSION in the current buffer,
+;;   and make sure it is displayed in the buffer's window.  The default
+;;   implementation of this function works for RCS-style logs.
+;;
 ;; - wash-log (file)
-;;     Remove all non-comment information from the output of print-log
+;;
+;;   Remove all non-comment information from the output of print-log.  The
+;;   default implementation of this function works for RCS-style logs.
+;;
+;; - logentry-check ()
+;;
+;;   If defined, this function is run to find out whether the user
+;;   entered a valid log entry for check-in.  The log entry is in the
+;;   current buffer, and if it is not a valid one, the function should
+;;   throw an error.
+;;
 ;; - comment-history (file)
+;;
+;;   Return a string containing all log entries that were made for FILE.
+;;   This is used for transferring a file from one backend to another,
+;;   retaining comment information.  The default implementation of this
+;;   function does this by calling print-log and then wash-log, and
+;;   returning the resulting buffer contents as a string.
+;;
 ;; - update-changelog (files)
-;;     Find changelog entries for FILES, or for all files at or below
-;;     the default-directory if FILES is nil.
-;; * latest-on-branch-p (file)
-;; - cancel-version (file writable)
+;;
+;;   Using recent log entries, create ChangeLog entries for FILES, or for
+;;   all files at or below the default-directory if FILES is nil.  The
+;;   default implementation runs rcs2log, which handles RCS- and
+;;   CVS-style logs.
+;;
+;; * diff (file &optional rev1 rev2)
+;;
+;;   Insert the diff for FILE into the *vc-diff* buffer.  If REV1 and REV2
+;;   are non-nil, report differences from REV1 to REV2.  If REV1 is nil,
+;;   use the current workfile version (as found in the repository) as the
+;;   older version; if REV2 is nil, use the current workfile contents as
+;;   the newer version.  This function should return a status of either 0
+;;   (no differences found), or 1 (either non-empty diff or the diff is
+;;   run asynchronously).
+;;
+;; - annotate-command (file buf rev)
+;;
+;;   If this function is provided, it should produce an annotated version
+;;   of FILE in BUF, relative to version REV.  This is currently only
+;;   implemented for CVS, using the `cvs annotate' command.
+;;
+;; - annotate-difference (point)
+;;
+;;   Only required if `annotate-command' is defined for the backend.
+;;   Return the difference between the age of the line at point and the
+;;   current time.  Return NIL if there is no more comparison to be made
+;;   in the buffer.  Return value as defined for `current-time'.  You can
+;;   safely assume that point is placed at the beginning of each line,
+;;   starting at `point-min'.  The buffer that point is placed in is the
+;;   Annotate output, as defined by the relevant backend.
+;;
+;; SNAPSHOT SYSTEM
+;;
+;; - create-snapshot (dir name branchp)
+;;
+;;   Take a snapshot of the current state of files under DIR and name it
+;;   NAME.  This should make sure that files are up-to-date before
+;;   proceeding with the action.  DIR can also be a file and if BRANCHP
+;;   is specified, NAME should be created as a branch and DIR should be
+;;   checked out under this new branch.  The default implementation does
+;;   not support branches but does a sanity check, a tree traversal and
+;;   for each file calls `assign-name'.
+;;
+;; - assign-name (file name)
+;;
+;;   Give name NAME to the current version of FILE, assuming it is
+;;   up-to-date.  Only used by the default version of `create-snapshot'.
+;;
+;; - retrieve-snapshot (dir name update)
+;;
+;;   Retrieve a named snapshot of all registered files at or below DIR.
+;;   If UPDATE is non-nil, then update buffers of any files in the
+;;   snapshot that are currently visited.  The default implementation
+;;   does a sanity check whether there aren't any uncommitted changes at
+;;   or below DIR, and then performs a tree walk, using the `checkout'
+;;   function to retrieve the corresponding versions.
+;;
+;; MISCELLANEOUS
+;;
+;; - make-version-backups-p (file)
+;;
+;;   Return non-nil if unmodified repository versions of FILE should be
+;;   backed up locally.  If this is done, VC can perform `diff' and
+;;   `revert' operations itself, without calling the backend system.  The
+;;   default implementation always returns nil.
+;;
+;; - check-headers ()
+;;
+;;   Return non-nil if the current buffer contains any version headers.
+;;
+;; - clear-headers ()
+;;
+;;   In the current buffer, reset all version headers to their unexpanded
+;;   form.  This function should be provided if the state-querying code
+;;   for this backend uses the version headers to determine the state of
+;;   a file.  This function will then be called whenever VC changes the
+;;   version control state in such a way that the headers would give
+;;   wrong information.
+;;
 ;; - rename-file (old new)
-;; - annotate-command (file buf)
-;; - annotate-difference (pos)
-;;     Only required if `annotate-command' is defined for the backend.
+;;
+;;   Rename file OLD to NEW, both in the working area and in the
+;;   repository.  If this function is not provided, the command
+;;   `vc-rename-file' will signal an error.
+
+;;; Code:
 
 (require 'vc-hooks)
 (require 'ring)
@@ -260,6 +466,18 @@ These are passed to the checkin program by \\[vc-register]."
 (defvar diff-switches "-c"
   "*A string or list of strings specifying switches to be passed to diff.")
 
+(defcustom vc-diff-switches nil
+  "*A string or list of strings specifying switches for diff under VC.
+There is also an option vc-BACKEND-diff-switches for each BACKEND that
+VC can handle."
+  :type '(choice (const :tag "None" nil)
+                (string :tag "Argument String")
+                (repeat :tag "Argument List"
+                        :value ("")
+                        string))
+  :group 'vc
+  :version "21.1")
+
 ;;;###autoload
 (defcustom vc-checkin-hook nil
   "*Normal hook (list of functions) run after a checkin is done.
@@ -608,19 +826,24 @@ and is passed 3 argument: the COMMAND, the FILE and the FLAGS.")
 
 (defun vc-do-command (buffer okstatus command file &rest flags)
   "Execute a version control command, notifying user and checking for errors.
-Output from COMMAND goes to BUFFER, or *vc* if BUFFER is nil or the current
-buffer (which is assumed to be properly setup) if BUFFER is t.  The
-command is considered successful if its exit status does not exceed
-OKSTATUS (if OKSTATUS is nil, that means to ignore errors, if it is 'async,
-that means not to wait for termination of the subprocess).  FILE is
-the name of the working file (may also be nil, to execute commands
-that don't expect a file name).  If an optional list of FLAGS is present,
+Output from COMMAND goes to BUFFER, or *vc* if BUFFER is nil or the
+current buffer if BUFFER is t.  If the destination buffer is not
+already current, set it up properly and erase it.  The command is
+considered successful if its exit status does not exceed OKSTATUS (if
+OKSTATUS is nil, that means to ignore errors, if it is 'async, that
+means not to wait for termination of the subprocess).  FILE is the
+name of the working file (may also be nil, to execute commands that
+don't expect a file name).  If an optional list of FLAGS is present,
 that is inserted into the command line before the filename."
   (and file (setq file (expand-file-name file)))
   (if vc-command-messages
       (message "Running %s on %s..." command file))
   (save-current-buffer
-    (unless (eq buffer t) (vc-setup-buffer buffer))
+    (unless (or (eq buffer t)
+                (and (stringp buffer)
+                     (string= (buffer-name) buffer))
+                (eq buffer (current-buffer)))
+      (vc-setup-buffer buffer))
     (let ((squeezed nil)
          (inhibit-read-only t)
          (status 0))
@@ -641,11 +864,13 @@ that is inserted into the command line before the filename."
        (if (eq okstatus 'async)
            (let ((proc (apply 'start-process command (current-buffer) command
                               squeezed)))
-             (message "Running %s in the background..." command)
+              (unless (active-minibuffer-window)
+                (message "Running %s in the background..." command))
              ;;(set-process-sentinel proc (lambda (p msg) (delete-process p)))
              (set-process-filter proc 'vc-process-filter)
              (vc-exec-after
-              `(message "Running %s in the background... done" ',command)))
+              `(unless (active-minibuffer-window)
+                  (message "Running %s in the background... done" ',command))))
          (setq status (apply 'call-process command nil t nil squeezed))
          (when (or (not (integerp status)) (and okstatus (< okstatus status)))
            (pop-to-buffer (current-buffer))
@@ -805,10 +1030,15 @@ NOT-URGENT means it is ok to continue if the user says not to save."
         (vc-file-setprop file 'vc-checkout-time (if unchanged lastmod 0))
         unchanged))))
 
-(defun vc-default-workfile-unchanged-p (file)
+(defun vc-default-workfile-unchanged-p (backend file)
   "Default check whether FILE is unchanged: diff against master version."
   (zerop (vc-call diff file (vc-workfile-version file))))
 
+(defun vc-default-latest-on-branch-p (backend file)
+  "Default check whether the current workfile version of FILE is the 
+latest on its branch."
+  t)
+
 (defun vc-recompute-state (file)
   "Force a recomputation of the version control state of FILE.
 The state is computed using the exact, and possibly expensive
@@ -866,7 +1096,8 @@ If VERBOSE is non-nil, query the user rather than using default parameters."
          (message "%s is up-to-date" file))))
 
        ;; Abnormal: edited but read-only
-       ((and visited (eq state 'edited) buffer-read-only)
+       ((and visited (eq state 'edited)
+            buffer-read-only (not (file-writable-p file)))
        ;; Make the file+buffer read-write.  If the user really wanted to
        ;; commit, he'll get a chance to do that next time around, anyway.
        (message "File is edited but read-only; making it writable")
@@ -1502,17 +1733,18 @@ files in or below it."
                                    rel2-default ") ")
                          "Newer version (default: current source): ")
                        nil nil rel2-default))))
-  (vc-setup-buffer "*vc-diff*")
   (if (file-directory-p file)
       ;; recursive directory diff
-      (let ((inhibit-read-only t))
+      (progn
+        (vc-setup-buffer "*vc-diff*")
        (if (string-equal rel1 "") (setq rel1 nil))
        (if (string-equal rel2 "") (setq rel2 nil))
-       (insert "Diffs between "
-               (or rel1 "last version checked in")
-               " and "
-               (or rel2 "current workfile(s)")
-               ":\n\n")
+        (let ((inhibit-read-only t))
+          (insert "Diffs between "
+                  (or rel1 "last version checked in")
+                  " and "
+                  (or rel2 "current workfile(s)")
+                  ":\n\n"))
        (setq default-directory (file-name-as-directory file))
        ;; FIXME: this should do a single exec in CVS.
        (vc-file-tree-walk
@@ -1534,14 +1766,17 @@ files in or below it."
                         file
                       (vc-version-backup-file file rel2))))
       (if (and file-rel1 file-rel2)
-         (apply 'vc-do-command t 1 "diff" nil
+         (apply 'vc-do-command "*vc-diff*" 1 "diff" nil
                 (append (if (listp diff-switches)
                             diff-switches
                           (list diff-switches))
+                         (if (listp vc-diff-switches)
+                             vc-diff-switches
+                           (list vc-diff-switches))
                         (list (file-relative-name file-rel1)
                               (file-relative-name file-rel2))))
-       (cd (file-name-directory file))
        (vc-call diff file rel1 rel2))))
+  (set-buffer "*vc-diff*")
   (if (and (zerop (buffer-size))
           (not (get-buffer-process (current-buffer))))
       (progn
@@ -1555,12 +1790,24 @@ files in or below it."
     ;; Gnus-5.8.5 sets up an autoload for diff-mode, even if it's
     ;; not available.  Work around that.
     (if (require 'diff-mode nil t) (diff-mode))
-    (vc-exec-after '(progn (if (eq (buffer-size) 0)
-                            (insert "No differences found.\n"))
-                          (goto-char (point-min))
-                          (shrink-window-if-larger-than-buffer)))
+    (vc-exec-after '(let ((inhibit-read-only t))
+                     (if (eq (buffer-size) 0)
+                         (insert "No differences found.\n"))
+                     (goto-char (point-min))
+                     (shrink-window-if-larger-than-buffer)))
     t))
 
+(defmacro vc-diff-switches-list (backend)
+  "Make a list of `diff-switches', `vc-diff-switches', 
+and `vc-BACKEND-diff-switches'."
+  `(append 
+    (if (listp diff-switches) diff-switches (list diff-switches))
+    (if (listp vc-diff-switches) vc-diff-switches (list vc-diff-switches))
+    (let ((backend-switches 
+           (eval (intern (concat "vc-" (symbol-name ',backend) 
+                                 "-diff-switches")))))
+      (if (listp backend-switches) backend-switches (list backend-switches)))))
+
 ;;;###autoload
 (defun vc-version-other-window (rev)
   "Visit version REV of the current buffer in another window.
@@ -1576,7 +1823,7 @@ If `F.~REV~' already exists, it is used instead of being re-created."
          (manual-backup (vc-version-backup-file-name file version 'manual)))
     (unless (file-exists-p manual-backup)
       (if (file-exists-p automatic-backup)
-          (copy-file automatic-backup manual-backup nil 'keep-date)
+          (rename-file automatic-backup manual-backup nil)
         (vc-call checkout file nil version manual-backup)))
     (find-file-other-window manual-backup)))
 
@@ -2110,10 +2357,9 @@ allowed and simply skipped)."
         (setq update (and (eq result 'visited) update))
         (vc-file-tree-walk
          dir
-         (lambda (f) (and
-                      (vc-error-occurred
-                       (vc-call checkout f nil name)
-                       (if update (vc-resynch-buffer f t t))))))))))
+         (lambda (f) (vc-error-occurred
+                     (vc-call checkout f nil name)
+                     (if update (vc-resynch-buffer f t t)))))))))
 
 ;; Miscellaneous other entry points
 
@@ -2123,9 +2369,8 @@ allowed and simply skipped)."
   (interactive)
   (vc-ensure-vc-buffer)
   (let ((file buffer-file-name))
-    (vc-setup-buffer nil)
-    (setq default-directory (file-name-directory file))
     (vc-call print-log file)
+    (set-buffer "*vc*")
     (pop-to-buffer (current-buffer))
     (if (fboundp 'log-view-mode) (log-view-mode))
     (vc-exec-after
@@ -2187,6 +2432,9 @@ changes found in the master file; use \\[universal-argument] \\[vc-next-action]
        (vc-suppress-confirm nil)
        (obuf (current-buffer))
        status)
+    (if (vc-up-to-date-p file)
+        (unless (yes-or-no-p "File seems up-to-date.  Revert anyway? ")
+          (error "Revert canceled")))
     (unless (vc-workfile-unchanged-p file)
       ;; vc-diff selects the new window, which is not what we want:
       ;; if the new window is on another frame, that'd require the user
@@ -2210,9 +2458,10 @@ changes found in the master file; use \\[universal-argument] \\[vc-next-action]
     (message "Reverting %s...done" file)))
 
 (defun vc-version-backup-file (file &optional rev)
-  "If version backups should be used for FILE, and there exists
+  "Return name of backup file for revision REV of FILE.
+If version backups should be used for FILE, and there exists
 such a backup for REV or the current workfile version of file,
-return the name of it; otherwise return nil."
+return its name; otherwise return nil."
   (when (vc-call make-version-backups-p file)
     (let ((backup-file (vc-version-backup-file-name file rev)))
       (if (file-exists-p backup-file)
@@ -2422,12 +2671,6 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
 (defun vc-rename-file (old new)
   "Rename file OLD to NEW, and rename its master file likewise."
   (interactive "fVC rename file: \nFRename to: ")
-  ;; There are several ways of renaming files under CVS 1.3, but they all
-  ;; have serious disadvantages.  See the FAQ (available from think.com in
-  ;; pub/cvs/).  I'd rather send the user an error, than do something he might
-  ;; consider to be wrong.  When the famous, long-awaited rename database is
-  ;; implemented things might change for the better.  This is unlikely to occur
-  ;; until CVS 2.0 is released.  --ceder 1994-01-23 21:27:51
   (let ((oldbuf (get-file-buffer old))
        (backend (vc-backend old)))
     (unless (or (null backend) (vc-find-backend-function backend 'rename-file))
@@ -2612,30 +2855,40 @@ menu items."
 ;;;;  the contents in BUFFER.
 
 ;;;###autoload
-(defun vc-annotate (ratio)
+(defun vc-annotate (prefix)
   "Display the result of the \"Annotate\" command using colors.
 \"Annotate\" is defined by `vc-BACKEND-annotate-command'.  New lines
-are displayed in red, old in blue.  A prefix argument specifies a
-factor for stretching the time scale.
+are displayed in red, old in blue.  When given a prefix argument, asks
+for a version to annotate from, and a factor for stretching the time 
+scale.
 
 `vc-annotate-menu-elements' customizes the menu elements of the
 mode-specific menu. `vc-annotate-color-map' and
 `vc-annotate-very-old-color' defines the mapping of time to
 colors. `vc-annotate-background' specifies the background color."
-  (interactive "p")
+  (interactive "P")
   (vc-ensure-vc-buffer)
-  (message "Annotating...")
   (let ((temp-buffer-name (concat "*Annotate " (buffer-name) "*"))
-       (temp-buffer-show-function 'vc-annotate-display)
-       (vc-annotate-ratio ratio)
-       (vc-annotate-backend (vc-backend (buffer-file-name))))
+        (temp-buffer-show-function 'vc-annotate-display)
+        (vc-annotate-version 
+         (if prefix (read-string 
+                     (format "Annotate from version: (default %s) "
+                             (vc-workfile-version (buffer-file-name)))
+                     nil nil (vc-workfile-version (buffer-file-name)))))
+        (vc-annotate-ratio 
+         (if prefix (string-to-number
+                     (read-string "Annotate ratio: (default 1.0) " 
+                                  nil nil "1.0"))))
+        (vc-annotate-backend (vc-backend (buffer-file-name))))
+    (message "Annotating...")
     (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command))
        (error "Sorry, annotating is not implemented for %s"
               vc-annotate-backend))
     (with-output-to-temp-buffer temp-buffer-name
       (vc-call-backend vc-annotate-backend 'annotate-command
                       (file-name-nondirectory (buffer-file-name))
-                      (get-buffer temp-buffer-name)))
+                      (get-buffer temp-buffer-name)
+                       vc-annotate-version))
     ;; Don't use the temp-buffer-name until the buffer is created
     ;; (only after `with-output-to-temp-buffer'.)
     (setq vc-annotate-buffers
@@ -2674,16 +2927,6 @@ nil otherwise"
    tmp-cons))                          ; Return the appropriate value
 
 
-;;;; (defun vc-BACKEND-annotate-difference (point) ...)
-;;;;
-;;;;  Return the difference between the age of the line at point and
-;;;;  the current time.  Return NIL if there is no more comparison to
-;;;;  be made in the buffer.  Return value as defined for
-;;;;  `current-time'.  You can safely assume that point is placed at
-;;;;  the beginning of each line, starting at `point-min'.  The buffer
-;;;;  that point is placed in is the Annotate output, as defined by
-;;;;  the relevant backend.
-
 (defun vc-annotate-display (buffer &optional color-map backend)
   "Do the VC-Annotate display in BUFFER using COLOR-MAP.
 The original annotating file is supposed to be handled by BACKEND.
@@ -2747,6 +2990,10 @@ This function is destructive on VC-ANNOTATE-BACKEND when BACKEND is non-nil."
   (interactive)
   (vc-call-backend (vc-backend buffer-file-name) 'check-headers))
 
+(defun vc-default-check-headers (backend)
+  "Default implementation of check-headers; always returns nil."
+  nil)
+
 ;; Back-end-dependent stuff ends here.
 
 ;; Set up key bindings for use while editing log messages
@@ -2790,8 +3037,7 @@ Global user options:
        `vc-keep-workfiles'     Non-nil value prevents workfiles from being
                                deleted when changes are checked in
 
-        `vc-suppress-confirm'  Suppresses some confirmation prompts,
-                               notably for reversions.
+        `vc-suppress-confirm'  Suppresses some confirmation prompts.
 
        vc-BACKEND-header       Which keywords to insert when adding headers
                                with \\[vc-insert-headers].  Defaults to