]> code.delx.au - gnu-emacs/blobdiff - lisp/vc.el
(mail-reply-buffer): Add defvar.
[gnu-emacs] / lisp / vc.el
index fdc2d13aa2dcbfc8178a8c5af623e94d7fff170e..a0b6ffa0ad8595a8518cc7cd16d83aedac5f96ab 100644 (file)
@@ -1,13 +1,13 @@
 ;;; vc.el --- drive a version-control system from within Emacs
 
 ;;; vc.el --- drive a version-control system from within Emacs
 
-;; Copyright (C) 1992,93,94,95,96,97,98,2000,01,2003,2004
-;;           Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
+;;   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 ;; Author:     FSF (see below for full credits)
 ;; Maintainer: Andre Spiegel <spiegel@gnu.org>
 ;; Keywords: tools
 
 
 ;; Author:     FSF (see below for full credits)
 ;; Maintainer: Andre Spiegel <spiegel@gnu.org>
 ;; Keywords: tools
 
-;; $Id: vc.el,v 1.372 2004/03/26 06:07:55 spiegel Exp $
+;; $Id$
 
 ;; This file is part of GNU Emacs.
 
 
 ;; This file is part of GNU Emacs.
 
@@ -23,8 +23,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Credits:
 
 
 ;;; Credits:
 
@@ -46,7 +46,8 @@
 
 ;; This mode is fully documented in the Emacs user's manual.
 ;;
 
 ;; This mode is fully documented in the Emacs user's manual.
 ;;
-;; Supported version-control systems presently include SCCS, RCS, and CVS.
+;; Supported version-control systems presently include CVS, RCS, GNU Arch,
+;; Subversion, Meta-CVS, and SCCS (or its free replacement, CSSC).
 ;;
 ;; Some features will not work with old RCS versions.  Where
 ;; appropriate, VC finds out which version you have, and allows or
 ;;
 ;; Some features will not work with old RCS versions.  Where
 ;; appropriate, VC finds out which version you have, and allows or
@@ -68,7 +69,7 @@
 ;;
 ;; The vc code maintains some internal state in order to reduce expensive
 ;; version-control operations to a minimum.  Some names are only computed
 ;;
 ;; The vc code maintains some internal state in order to reduce expensive
 ;; version-control operations to a minimum.  Some names are only computed
-;; once.  If you perform version control operations with RCS/SCCS/CVS while
+;; once.  If you perform version control operations with the backend while
 ;; vc's back is turned, or move/rename master files while vc is running,
 ;; vc may get seriously confused.  Don't do these things!
 ;;
 ;; vc's back is turned, or move/rename master files while vc is running,
 ;; vc may get seriously confused.  Don't do these things!
 ;;
 ;;   have such a brief-comparison feature, the default implementation of
 ;;   this function can be used, which delegates to a full
 ;;   vc-BACKEND-diff.  (Note that vc-BACKEND-diff must not run
 ;;   have such a brief-comparison feature, the default implementation of
 ;;   this function can be used, which delegates to a full
 ;;   vc-BACKEND-diff.  (Note that vc-BACKEND-diff must not run
-;;   asynchronously in this case.)
+;;   asynchronously in this case, see variable `vc-disable-async-diff'.)
 ;;
 ;; - mode-line-string (file)
 ;;
 ;;
 ;; - mode-line-string (file)
 ;;
 ;;   vc-BACKEND-diff.  The default implementation does an explicit tree
 ;;   walk, calling vc-BACKEND-diff for each individual file.
 ;;
 ;;   vc-BACKEND-diff.  The default implementation does an explicit tree
 ;;   walk, calling vc-BACKEND-diff for each individual file.
 ;;
-;; - annotate-command (file buf rev)
+;; - annotate-command (file buf &optional 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.
+;;   If this function is provided, it should produce an annotated display
+;;   of FILE in BUF, relative to version REV.  Annotation means each line
+;;   of FILE displayed is prefixed with version information associated with
+;;   its addition (deleted lines leave no history) and that the text of the
+;;   file is fontified according to age.
 ;;
 ;; - annotate-time ()
 ;;
 ;;
 ;; - annotate-time ()
 ;;
 ;;   in the buffer.  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
 ;;   in the buffer.  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.
+;;   relevant backend.  This function also affects how much of the line
+;;   is fontified; where it leaves point is where fontification begins.
 ;;
 ;; - annotate-current-time ()
 ;;
 ;;
 ;; - annotate-current-time ()
 ;;
 ;;
 ;;   Return the hostname that the backend will have to contact
 ;;   in order to operate on a file in DIRNAME.  If the return value
 ;;
 ;;   Return the hostname that the backend will have to contact
 ;;   in order to operate on a file in DIRNAME.  If the return value
-;;   is nil, it is means that the repository is local.
+;;   is nil, it means that the repository is local.
 ;;   This function is used in `vc-stay-local-p' which backends can use
 ;;   for their convenience.
 ;;
 ;;   This function is used in `vc-stay-local-p' which backends can use
 ;;   for their convenience.
 ;;
@@ -563,6 +567,15 @@ specific to any particular backend."
   :group 'vc
   :version "21.1")
 
   :group 'vc
   :version "21.1")
 
+(defcustom vc-allow-async-revert nil
+  "*Specifies whether the diff during \\[vc-revert-buffer] may be asynchronous.
+Enabling this option means that you can confirm a revert operation even
+if the local changes in the file have not been found and displayed yet."
+  :type '(choice (const :tag "No" nil)
+                 (const :tag "Yes" t))
+  :group 'vc
+  :version "22.1")
+
 ;;;###autoload
 (defcustom vc-checkout-hook nil
   "*Normal hook (list of functions) run after checking out a file.
 ;;;###autoload
 (defcustom vc-checkout-hook nil
   "*Normal hook (list of functions) run after checking out a file.
@@ -604,23 +617,23 @@ version control backend imposes itself."
 
 ;; Annotate customization
 (defcustom vc-annotate-color-map
 
 ;; Annotate customization
 (defcustom vc-annotate-color-map
-  '(( 20. . "#FF0000")
-    ( 40. . "#FF3800")
-    ( 60. . "#FF7000")
-    ( 80. . "#FFA800")
-    (100. . "#FFE000")
-    (120. . "#E7FF00")
-    (140. . "#AFFF00")
-    (160. . "#77FF00")
-    (180. . "#3FFF00")
-    (200. . "#07FF00")
-    (220. . "#00FF31")
-    (240. . "#00FF69")
-    (260. . "#00FFA1")
-    (280. . "#00FFD9")
-    (300. . "#00EEFF")
-    (320. . "#00B6FF")
-    (340. . "#007EFF"))
+  '(( 20. . "#FFCC00")
+    ( 40. . "#FF6666")
+    ( 60. . "#FF6600")
+    ( 80. . "#FF3300")
+    (100. . "#FF00FF")
+    (120. . "#FF0000")
+    (140. . "#CCCC00")
+    (160. . "#CC00CC")
+    (180. . "#BC8F8F")
+    (200. . "#99CC00")
+    (220. . "#999900")
+    (240. . "#7AC5CD")
+    (260. . "#66CC00")
+    (280. . "#33CC33")
+    (300. . "#00CCFF")
+    (320. . "#00CC99")
+    (340. . "#0099FF"))
   "*Association list of age versus color, for \\[vc-annotate].
 Ages are given in units of fractional days.  Default is eighteen steps
 using a twenty day increment."
   "*Association list of age versus color, for \\[vc-annotate].
 Ages are given in units of fractional days.  Default is eighteen steps
 using a twenty day increment."
@@ -644,10 +657,6 @@ List of factors, used to expand/compress the time scale.  See `vc-annotate'."
   :type '(repeat number)
   :group 'vc)
 
   :type '(repeat number)
   :group 'vc)
 
-;; vc-annotate functionality (CVS only).
-(defvar vc-annotate-mode nil
-  "Variable indicating if VC-Annotate mode is active.")
-
 (defvar vc-annotate-mode-map
   (let ((m (make-sparse-keymap)))
     (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate"))
 (defvar vc-annotate-mode-map
   (let ((m (make-sparse-keymap)))
     (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate"))
@@ -715,6 +724,11 @@ The keys are \(BUFFER . BACKEND\).  See also `vc-annotate-get-backend'.")
 (defvar vc-parent-buffer-name nil)
 (put 'vc-parent-buffer-name 'permanent-local t)
 
 (defvar vc-parent-buffer-name nil)
 (put 'vc-parent-buffer-name 'permanent-local t)
 
+(defvar vc-disable-async-diff nil
+  "VC sets this to t locally to disable some async diff operations.
+Backends that offer asynchronous diffs should respect this variable
+in their implementation of vc-BACKEND-diff.")
+
 (defvar vc-log-file)
 (defvar vc-log-version)
 
 (defvar vc-log-file)
 (defvar vc-log-version)
 
@@ -724,6 +738,7 @@ The keys are \(BUFFER . BACKEND\).  See also `vc-annotate-get-backend'.")
 ;; functions that operate on RCS revision numbers.  This code should
 ;; also be moved into the backends.  It stays for now, however, since
 ;; it is used in code below.
 ;; functions that operate on RCS revision numbers.  This code should
 ;; also be moved into the backends.  It stays for now, however, since
 ;; it is used in code below.
+;;;###autoload
 (defun vc-trunk-p (rev)
   "Return t if REV is a revision on the trunk."
   (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev))))
 (defun vc-trunk-p (rev)
   "Return t if REV is a revision on the trunk."
   (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev))))
@@ -945,9 +960,14 @@ that is inserted into the command line before the filename."
                           (mapconcat 'identity vc-path path-separator))
                   process-environment))
            (w32-quote-process-args t))
                           (mapconcat 'identity vc-path path-separator))
                   process-environment))
            (w32-quote-process-args t))
+       (if (and (eq okstatus 'async) (file-remote-p default-directory))
+           ;; start-process does not support remote execution
+           (setq okstatus nil))
        (if (eq okstatus 'async)
        (if (eq okstatus 'async)
-           (let ((proc (apply 'start-process command (current-buffer) command
-                              squeezed)))
+           (let ((proc
+                  (let ((process-connection-type nil))
+                    (apply 'start-process command (current-buffer) command
+                           squeezed))))
               (unless (active-minibuffer-window)
                 (message "Running %s in the background..." command))
              ;;(set-process-sentinel proc (lambda (p msg) (delete-process p)))
               (unless (active-minibuffer-window)
                 (message "Running %s in the background..." command))
              ;;(set-process-sentinel proc (lambda (p msg) (delete-process p)))
@@ -955,7 +975,7 @@ that is inserted into the command line before the filename."
              (vc-exec-after
               `(unless (active-minibuffer-window)
                   (message "Running %s in the background... done" ',command))))
              (vc-exec-after
               `(unless (active-minibuffer-window)
                   (message "Running %s in the background... done" ',command))))
-         (setq status (apply 'call-process command nil t nil squeezed))
+         (setq status (apply 'process-file command nil t nil squeezed))
          (when (or (not (integerp status)) (and okstatus (< okstatus status)))
            (pop-to-buffer (current-buffer))
            (goto-char (point-min))
          (when (or (not (integerp status)) (and okstatus (< okstatus status)))
            (pop-to-buffer (current-buffer))
            (goto-char (point-min))
@@ -1017,28 +1037,32 @@ Used by `vc-restore-buffer-context' to later restore the context."
                           (vc-position-context (mark-marker))))
        ;; Make the right thing happen in transient-mark-mode.
        (mark-active nil)
                           (vc-position-context (mark-marker))))
        ;; Make the right thing happen in transient-mark-mode.
        (mark-active nil)
-       ;; We may want to reparse the compilation buffer after revert
-       (reparse (and (boundp 'compilation-error-list) ;compile loaded
-                     ;; Construct a list; each elt is nil or a buffer
-                     ;; iff that buffer is a compilation output buffer
-                     ;; that contains markers into the current buffer.
-                     (save-current-buffer
-                       (mapcar (lambda (buffer)
-                                 (set-buffer buffer)
-                                 (let ((errors (or
-                                                compilation-old-error-list
-                                                compilation-error-list))
-                                       (buffer-error-marked-p nil))
-                                   (while (and (consp errors)
-                                               (not buffer-error-marked-p))
-                                     (and (markerp (cdr (car errors)))
-                                          (eq buffer
-                                              (marker-buffer
-                                               (cdr (car errors))))
-                                          (setq buffer-error-marked-p t))
-                                     (setq errors (cdr errors)))
-                                   (if buffer-error-marked-p buffer)))
-                               (buffer-list))))))
+       ;; The new compilation code does not use compilation-error-list any
+       ;; more, so the code below is now ineffective and might as well
+       ;; be disabled.  -- Stef
+       ;; ;; We may want to reparse the compilation buffer after revert
+       ;; (reparse (and (boundp 'compilation-error-list) ;compile loaded
+       ;;            ;; Construct a list; each elt is nil or a buffer
+       ;;            ;; iff that buffer is a compilation output buffer
+       ;;            ;; that contains markers into the current buffer.
+       ;;            (save-current-buffer
+       ;;              (mapcar (lambda (buffer)
+       ;;                        (set-buffer buffer)
+       ;;                        (let ((errors (or
+       ;;                                       compilation-old-error-list
+       ;;                                       compilation-error-list))
+       ;;                              (buffer-error-marked-p nil))
+       ;;                          (while (and (consp errors)
+       ;;                                      (not buffer-error-marked-p))
+       ;;                            (and (markerp (cdr (car errors)))
+       ;;                                 (eq buffer
+       ;;                                     (marker-buffer
+       ;;                                      (cdr (car errors))))
+       ;;                                 (setq buffer-error-marked-p t))
+       ;;                            (setq errors (cdr errors)))
+       ;;                          (if buffer-error-marked-p buffer)))
+       ;;                      (buffer-list)))))
+       (reparse nil))
     (list point-context mark-context reparse)))
 
 (defun vc-restore-buffer-context (context)
     (list point-context mark-context reparse)))
 
 (defun vc-restore-buffer-context (context)
@@ -1047,23 +1071,26 @@ CONTEXT is that which `vc-buffer-context' returns."
   (let ((point-context (nth 0 context))
        (mark-context (nth 1 context))
        (reparse (nth 2 context)))
   (let ((point-context (nth 0 context))
        (mark-context (nth 1 context))
        (reparse (nth 2 context)))
-    ;; Reparse affected compilation buffers.
-    (while reparse
-      (if (car reparse)
-         (with-current-buffer (car reparse)
-           (let ((compilation-last-buffer (current-buffer)) ;select buffer
-                 ;; Record the position in the compilation buffer of
-                 ;; the last error next-error went to.
-                 (error-pos (marker-position
-                             (car (car-safe compilation-error-list)))))
-             ;; Reparse the error messages as far as they were parsed before.
-             (compile-reinitialize-errors '(4) compilation-parsing-end)
-             ;; Move the pointer up to find the error we were at before
-             ;; reparsing.  Now next-error should properly go to the next one.
-             (while (and compilation-error-list
-                         (/= error-pos (car (car compilation-error-list))))
-               (setq compilation-error-list (cdr compilation-error-list))))))
-      (setq reparse (cdr reparse)))
+    ;; The new compilation code does not use compilation-error-list any
+    ;; more, so the code below is now ineffective and might as well
+    ;; be disabled.  -- Stef
+    ;; ;; Reparse affected compilation buffers.
+    ;; (while reparse
+    ;;   (if (car reparse)
+    ;;           (with-current-buffer (car reparse)
+    ;;             (let ((compilation-last-buffer (current-buffer)) ;select buffer
+    ;;                   ;; Record the position in the compilation buffer of
+    ;;                   ;; the last error next-error went to.
+    ;;                   (error-pos (marker-position
+    ;;                               (car (car-safe compilation-error-list)))))
+    ;;               ;; Reparse the error messages as far as they were parsed before.
+    ;;               (compile-reinitialize-errors '(4) compilation-parsing-end)
+    ;;               ;; Move the pointer up to find the error we were at before
+    ;;               ;; reparsing.  Now next-error should properly go to the next one.
+    ;;               (while (and compilation-error-list
+    ;;                           (/= error-pos (car (car compilation-error-list))))
+    ;;                 (setq compilation-error-list (cdr compilation-error-list))))))
+    ;;   (setq reparse (cdr reparse)))
 
     ;; if necessary, restore point and mark
     (if (not (vc-context-matches-p (point) point-context))
 
     ;; if necessary, restore point and mark
     (if (not (vc-context-matches-p (point) point-context))
@@ -1110,12 +1137,6 @@ This default implementation always returns non-nil, which means that
 editing non-current versions is not supported by default."
   t)
 
 editing non-current versions is not supported by default."
   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
-function `vc-BACKEND-state', not the heuristic."
-  (vc-file-setprop file 'vc-state (vc-call state file)))
-
 (defun vc-next-action-on-file (file verbose &optional comment)
   "Do The Right Thing for a given FILE under version control.
 If COMMENT is specified, it will be used as an admin or checkin comment.
 (defun vc-next-action-on-file (file verbose &optional comment)
   "Do The Right Thing for a given FILE under version control.
 If COMMENT is specified, it will be used as an admin or checkin comment.
@@ -1677,10 +1698,10 @@ saving the buffer."
          (message "No changes to %s since latest version" file)
        (vc-version-diff file nil nil)))))
 
          (message "No changes to %s since latest version" file)
        (vc-version-diff file nil nil)))))
 
-(defun vc-version-diff (file rel1 rel2)
-  "List the differences between FILE's versions REL1 and REL2.
-If REL1 is empty or nil it means to use the current workfile version;
-REL2 empty or nil means the current file contents.  FILE may also be
+(defun vc-version-diff (file rev1 rev2)
+  "List the differences between FILE's versions REV1 and REV2.
+If REV1 is empty or nil it means to use the current workfile version;
+REV2 empty or nil means the current file contents.  FILE may also be
 a directory, in that case, generate diffs between the correponding
 versions of all registered files in or below it."
   (interactive
 a directory, in that case, generate diffs between the correponding
 versions of all registered files in or below it."
   (interactive
@@ -1689,7 +1710,7 @@ versions of all registered files in or below it."
                                     "File or dir to diff: (default visited file) "
                                   "File or dir to diff: ")
                                 default-directory buffer-file-name t)))
                                     "File or dir to diff: (default visited file) "
                                   "File or dir to diff: ")
                                 default-directory buffer-file-name t)))
-         (rel1-default nil) (rel2-default nil))
+         (rev1-default nil) (rev2-default nil))
      ;; compute default versions based on the file state
      (cond
       ;; if it's a directory, don't supply any version default
      ;; compute default versions based on the file state
      (cond
       ;; if it's a directory, don't supply any version default
@@ -1697,54 +1718,54 @@ versions of all registered files in or below it."
        nil)
       ;; if the file is not up-to-date, use current version as older version
       ((not (vc-up-to-date-p file))
        nil)
       ;; if the file is not up-to-date, use current version as older version
       ((not (vc-up-to-date-p file))
-       (setq rel1-default (vc-workfile-version file)))
+       (setq rev1-default (vc-workfile-version file)))
       ;; if the file is not locked, use last and previous version as default
       (t
       ;; if the file is not locked, use last and previous version as default
       (t
-       (setq rel1-default (vc-call previous-version file
+       (setq rev1-default (vc-call previous-version file
                                    (vc-workfile-version file)))
                                    (vc-workfile-version file)))
-       (if (string= rel1-default "") (setq rel1-default nil))
-       (setq rel2-default (vc-workfile-version file))))
+       (if (string= rev1-default "") (setq rev1-default nil))
+       (setq rev2-default (vc-workfile-version file))))
      ;; construct argument list
      (list file
      ;; construct argument list
      (list file
-           (read-string (if rel1-default
+           (read-string (if rev1-default
                            (concat "Older version: (default "
                            (concat "Older version: (default "
-                                   rel1-default ") ")
+                                   rev1-default ") ")
                          "Older version: ")
                          "Older version: ")
-                       nil nil rel1-default)
-           (read-string (if rel2-default
+                       nil nil rev1-default)
+           (read-string (if rev2-default
                            (concat "Newer version: (default "
                            (concat "Newer version: (default "
-                                   rel2-default ") ")
+                                   rev2-default ") ")
                          "Newer version (default: current source): ")
                          "Newer version (default: current source): ")
-                       nil nil rel2-default))))
+                       nil nil rev2-default))))
   (if (file-directory-p file)
       ;; recursive directory diff
       (progn
         (vc-setup-buffer "*vc-diff*")
   (if (file-directory-p file)
       ;; recursive directory diff
       (progn
         (vc-setup-buffer "*vc-diff*")
-       (if (string-equal rel1 "") (setq rel1 nil))
-       (if (string-equal rel2 "") (setq rel2 nil))
+       (if (string-equal rev1 "") (setq rev1 nil))
+       (if (string-equal rev2 "") (setq rev2 nil))
         (let ((inhibit-read-only t))
           (insert "Diffs between "
         (let ((inhibit-read-only t))
           (insert "Diffs between "
-                  (or rel1 "last version checked in")
+                  (or rev1 "last version checked in")
                   " and "
                   " and "
-                  (or rel2 "current workfile(s)")
+                  (or rev2 "current workfile(s)")
                   ":\n\n"))
         (let ((dir (file-name-as-directory file)))
           (vc-call-backend (vc-responsible-backend dir)
                   ":\n\n"))
         (let ((dir (file-name-as-directory file)))
           (vc-call-backend (vc-responsible-backend dir)
-                           'diff-tree dir rel1 rel2))
+                           'diff-tree dir rev1 rev2))
        (vc-exec-after `(let ((inhibit-read-only t))
                          (insert "\nEnd of diffs.\n"))))
     ;; Single file diff.  It is important that the vc-controlled buffer
     ;; is still current at this time, because any local settings in that
     ;; buffer should affect the diff command.
        (vc-exec-after `(let ((inhibit-read-only t))
                          (insert "\nEnd of diffs.\n"))))
     ;; Single file diff.  It is important that the vc-controlled buffer
     ;; is still current at this time, because any local settings in that
     ;; buffer should affect the diff command.
-    (vc-diff-internal file rel1 rel2))
+    (vc-diff-internal file rev1 rev2))
   (set-buffer "*vc-diff*")
   (if (and (zerop (buffer-size))
           (not (get-buffer-process (current-buffer))))
       (progn
   (set-buffer "*vc-diff*")
   (if (and (zerop (buffer-size))
           (not (get-buffer-process (current-buffer))))
       (progn
-       (if rel1
-           (if rel2
-               (message "No changes to %s between %s and %s" file rel1 rel2)
-             (message "No changes to %s since %s" file rel1))
+       (if rev1
+           (if rev2
+               (message "No changes to %s between %s and %s" file rev1 rev2)
+             (message "No changes to %s since %s" file rev1))
          (message "No changes to %s since latest version" file))
        nil)
     (pop-to-buffer (current-buffer))
          (message "No changes to %s since latest version" file))
        nil)
     (pop-to-buffer (current-buffer))
@@ -1758,29 +1779,40 @@ versions of all registered files in or below it."
                      (shrink-window-if-larger-than-buffer)))
     t))
 
                      (shrink-window-if-larger-than-buffer)))
     t))
 
-(defun vc-diff-internal (file rel1 rel2)
-  "Run diff to compare FILE's revisions REL1 and REL2.
+(defun vc-diff-label (file file-rev rev)
+  (concat (file-relative-name file)
+         (format-time-string "\t%d %b %Y %T %z\t"
+                             (nth 5 (file-attributes file-rev)))
+         rev))
+
+(defun vc-diff-internal (file rev1 rev2)
+  "Run diff to compare FILE's revisions REV1 and REV2.
 Diff output goes to the *vc-diff* buffer.  The exit status of the diff
 command is returned.
 
 This function takes care to set up a proper coding system for diff output.
 If both revisions are available as local files, then it also does not
 actually call the backend, but performs a local diff."
 Diff output goes to the *vc-diff* buffer.  The exit status of the diff
 command is returned.
 
 This function takes care to set up a proper coding system for diff output.
 If both revisions are available as local files, then it also does not
 actually call the backend, but performs a local diff."
-  (if (or (not rel1) (string-equal rel1 ""))
-      (setq rel1 (vc-workfile-version file)))
-  (if (string-equal rel2 "")
-      (setq rel2 nil))
-  (let ((file-rel1 (vc-version-backup-file file rel1))
-        (file-rel2 (if (not rel2)
+  (if (or (not rev1) (string-equal rev1 ""))
+      (setq rev1 (vc-workfile-version file)))
+  (if (string-equal rev2 "")
+      (setq rev2 nil))
+  (let ((file-rev1 (vc-version-backup-file file rev1))
+        (file-rev2 (if (not rev2)
                        file
                        file
-                     (vc-version-backup-file file rel2)))
+                     (vc-version-backup-file file rev2)))
         (coding-system-for-read (vc-coding-system-for-diff file)))
         (coding-system-for-read (vc-coding-system-for-diff file)))
-    (if (and file-rel1 file-rel2)
+    (if (and file-rev1 file-rev2)
         (apply 'vc-do-command "*vc-diff*" 1 "diff" nil
               (append (vc-switches nil 'diff)
         (apply 'vc-do-command "*vc-diff*" 1 "diff" nil
               (append (vc-switches nil 'diff)
-                      (list (file-relative-name file-rel1)
-                            (file-relative-name file-rel2))))
-      (vc-call diff file rel1 rel2))))
+                      ;; Provide explicit labels like RCS or CVS would do
+                      ;; so diff-mode refers to `file' rather than to
+                      ;; `file-rev1' when trying to find/apply/undo hunks.
+                      (list "-L" (vc-diff-label file file-rev1 rev1)
+                            "-L" (vc-diff-label file file-rev2 rev2)
+                            (file-relative-name file-rev1)
+                            (file-relative-name file-rev2))))
+      (vc-call diff file rev1 rev2))))
 
 
 (defun vc-switches (backend op)
 
 
 (defun vc-switches (backend op)
@@ -1802,11 +1834,11 @@ actually call the backend, but performs a local diff."
 
 ;; Old def for compatibility with Emacs-21.[123].
 (defmacro vc-diff-switches-list (backend) `(vc-switches ',backend 'diff))
 
 ;; Old def for compatibility with Emacs-21.[123].
 (defmacro vc-diff-switches-list (backend) `(vc-switches ',backend 'diff))
-(make-obsolete 'vc-diff-switches-list 'vc-switches "21.4")
+(make-obsolete 'vc-diff-switches-list 'vc-switches "22.1")
 
 
-(defun vc-default-diff-tree (backend dir rel1 rel2)
+(defun vc-default-diff-tree (backend dir rev1 rev2)
   "List differences for all registered files at and below DIR.
   "List differences for all registered files at and below DIR.
-The meaning of REL1 and REL2 is the same as for `vc-version-diff'."
+The meaning of REV1 and REV2 is the same as for `vc-version-diff'."
   ;; This implementation does an explicit tree walk, and calls
   ;; vc-BACKEND-diff directly for each file.  An optimization
   ;; would be to use `vc-diff-internal', so that diffs can be local,
   ;; This implementation does an explicit tree walk, and calls
   ;; vc-BACKEND-diff directly for each file.  An optimization
   ;; would be to use `vc-diff-internal', so that diffs can be local,
@@ -1821,7 +1853,7 @@ The meaning of REL1 and REL2 is the same as for `vc-version-diff'."
       `(let ((coding-system-for-read (vc-coding-system-for-diff ',f)))
          (message "Looking at %s" ',f)
          (vc-call-backend ',(vc-backend f)
       `(let ((coding-system-for-read (vc-coding-system-for-diff ',f)))
          (message "Looking at %s" ',f)
          (vc-call-backend ',(vc-backend f)
-                          'diff ',f ',rel1 ',rel2))))))
+                          'diff ',f ',rev1 ',rev2))))))
 
 (defun vc-coding-system-for-diff (file)
   "Return the coding system for reading diff output for FILE."
 
 (defun vc-coding-system-for-diff (file)
   "Return the coding system for reading diff output for FILE."
@@ -2337,13 +2369,23 @@ If FOCUS-REV is non-nil, leave the point at that revision."
     ;; Don't switch to the output buffer before running the command,
     ;; so that any buffer-local settings in the vc-controlled
     ;; buffer can be accessed by the command.
     ;; Don't switch to the output buffer before running the command,
     ;; so that any buffer-local settings in the vc-controlled
     ;; buffer can be accessed by the command.
-    (if (> (length (vc-arg-list (vc-backend file) 'print-log)) 1)
+    (condition-case err
         (progn
           (vc-call print-log file "*vc-change-log*")
           (set-buffer "*vc-change-log*"))
         (progn
           (vc-call print-log file "*vc-change-log*")
           (set-buffer "*vc-change-log*"))
-      ;; for backward compatibility
-      (vc-call print-log file)
-      (set-buffer "*vc*"))
+      (wrong-number-of-arguments
+       ;; If this error came from the above call to print-log, try again
+       ;; without the optional buffer argument (for backward compatibility).
+       ;; Otherwise, resignal.
+       (if (or (not (eq (cadr err)
+                        (indirect-function
+                         (vc-find-backend-function (vc-backend file)
+                                                   'print-log))))
+               (not (eq (caddr err) 2)))
+           (signal (car err) (cdr err))
+         ;; for backward compatibility
+         (vc-call print-log file)
+         (set-buffer "*vc*"))))
     (pop-to-buffer (current-buffer))
     (log-view-mode)
     (vc-exec-after
     (pop-to-buffer (current-buffer))
     (log-view-mode)
     (vc-exec-after
@@ -2414,11 +2456,13 @@ changes found in the master file; use \\[universal-argument] \\[vc-next-action]
         (unless (yes-or-no-p "File seems up-to-date.  Revert anyway? ")
           (error "Revert canceled")))
     (unless (vc-workfile-unchanged-p file)
         (unless (yes-or-no-p "File seems up-to-date.  Revert anyway? ")
           (error "Revert canceled")))
     (unless (vc-workfile-unchanged-p file)
+      (message "Finding changes...")
       ;; 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
       ;; moving her mouse to answer the yes-or-no-p question.
       ;; 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
       ;; moving her mouse to answer the yes-or-no-p question.
-      (let ((win (save-selected-window
-                  (setq status (vc-diff nil t)) (selected-window))))
+      (let* ((vc-disable-async-diff (not vc-allow-async-revert))
+             (win (save-selected-window
+                    (setq status (vc-diff nil t)) (selected-window))))
        (vc-exec-after `(message nil))
        (when status
          (unwind-protect
        (vc-exec-after `(message nil))
        (when status
          (unwind-protect
@@ -2815,7 +2859,7 @@ Uses `rcs2log' which only works for RCS and CVS."
                     (pop-to-buffer
                      (set-buffer (get-buffer-create "*vc*")))
                     (erase-buffer)
                     (pop-to-buffer
                      (set-buffer (get-buffer-create "*vc*")))
                     (erase-buffer)
-                    (insert-file tempfile)
+                    (insert-file-contents tempfile)
                     "failed"))
               (setq default-directory (file-name-directory changelog))
               (delete-file tempfile)))))
                     "failed"))
               (setq default-directory (file-name-directory changelog))
               (delete-file tempfile)))))
@@ -2868,11 +2912,11 @@ if present.  The current time is used as the offset."
   (message "Redisplaying annotation...done"))
 
 (defun vc-annotate-display-autoscale (&optional full)
   (message "Redisplaying annotation...done"))
 
 (defun vc-annotate-display-autoscale (&optional full)
-  "Highlight the output of \\[vc-annotate]] using an autoscaled color map.
+  "Highlight the output of \\[vc-annotate] using an autoscaled color map.
 Autoscaling means that the map is scaled from the current time to the
 Autoscaling means that the map is scaled from the current time to the
-oldest annotation in the buffer, or, with argument FULL non-nil, to
+oldest annotation in the buffer, or, with prefix argument FULL, to
 cover the range from the oldest annotation to the newest."
 cover the range from the oldest annotation to the newest."
-  (interactive)
+  (interactive "P")
   (let ((newest 0.0)
        (oldest 999999.)                ;Any CVS users at the founding of Rome?
        (current (vc-annotate-convert-time (current-time)))
   (let ((newest 0.0)
        (oldest 999999.)                ;Any CVS users at the founding of Rome?
        (current (vc-annotate-convert-time (current-time)))
@@ -2881,7 +2925,9 @@ cover the range from the oldest annotation to the newest."
     ;; Run through this file and find the oldest and newest dates annotated.
     (save-excursion
       (goto-char (point-min))
     ;; Run through this file and find the oldest and newest dates annotated.
     (save-excursion
       (goto-char (point-min))
-      (while (setq date (vc-call-backend vc-annotate-backend 'annotate-time))
+      (while (setq date (prog1 (vc-call-backend vc-annotate-backend
+                                                'annotate-time)
+                          (forward-line 1)))
        (if (> date newest)
            (setq newest date))
        (if (< date oldest)
        (if (> date newest)
            (setq newest date))
        (if (< date oldest)
@@ -2975,7 +3021,7 @@ use; you may override this using the second optional arg MODE."
   (when buffer
     (set-buffer buffer)
     (display-buffer buffer))
   (when buffer
     (set-buffer buffer)
     (display-buffer buffer))
-  (if (not vc-annotate-mode)           ; Turn on vc-annotate-mode if not done
+  (if (not vc-annotate-parent-rev)
       (vc-annotate-mode))
   (cond ((null vc-annotate-display-mode)
         (vc-annotate-display-default vc-annotate-ratio))
       (vc-annotate-mode))
   (cond ((null vc-annotate-display-mode)
         (vc-annotate-display-default vc-annotate-ratio))
@@ -2997,12 +3043,12 @@ use; you may override this using the second optional arg MODE."
 
 ;;;###autoload
 (defun vc-annotate (prefix &optional revision display-mode)
 
 ;;;###autoload
 (defun vc-annotate (prefix &optional revision display-mode)
-  "Display the edit history of the current file using colours.
+  "Display the edit history of the current file using colors.
 
 This command creates a buffer that shows, for each line of the current
 
 This command creates a buffer that shows, for each line of the current
-file, when it was last edited and by whom.  Additionally, colours are
+file, when it was last edited and by whom.  Additionally, colors are
 used to show the age of each line--blue means oldest, red means
 used to show the age of each line--blue means oldest, red means
-youngest, and intermediate colours indicate intermediate ages.  By
+youngest, and intermediate colors indicate intermediate ages.  By
 default, the time scale stretches back one year into the past;
 everything that is older than that is shown in blue.
 
 default, the time scale stretches back one year into the past;
 everything that is older than that is shown in blue.
 
@@ -3684,5 +3730,5 @@ Invoke FUNC f ARGS on each VC-managed file f underneath it."
 ;;
 ;;    Thus, there is no explicit recovery code.
 
 ;;
 ;;    Thus, there is no explicit recovery code.
 
-;;; arch-tag: ca82c1de-3091-4e26-af92-460abc6213a6
+;; arch-tag: ca82c1de-3091-4e26-af92-460abc6213a6
 ;;; vc.el ends here
 ;;; vc.el ends here