Commit 2c87edc1 authored by André Spiegel's avatar André Spiegel
Browse files

(vc-diff-internal, vc-coding-system-for-diff, vc-default-diff-tree):

New functions.
(vc-version-diff): Use them.  As a result, coding systems are now set
up properly for all sorts of diffs, and tree diffs can now also be
done locally.
(vc-diff): With a prefix argument, don't require that it's called from
a buffer under version control.
parent 8c1a1077
......@@ -6,7 +6,7 @@
;; Maintainer: Andre Spiegel <spiegel@gnu.org>
;; Keywords: tools
;; $Id: vc.el,v 1.310 2001/09/22 20:04:21 monnier Exp $
;; $Id: vc.el,v 1.311 2001/09/24 22:29:15 monnier Exp $
;; This file is part of GNU Emacs.
......@@ -289,6 +289,13 @@
;; (no differences found), or 1 (either non-empty diff or the diff is
;; run asynchronously).
;;
;; - diff-tree (dir &optional rev1 rev2)
;;
;; Insert the diff for all files at and below DIR into the *vc-diff*
;; buffer. The meaning of REV1 and REV2 is the same as for
;; vc-BACKEND-diff. The default implementation does an explicit tree
;; walk, calling vc-BACKEND-diff for each individual file.
;;
;; - annotate-command (file buf rev)
;;
;; If this function is provided, it should produce an annotated version
......@@ -1684,9 +1691,9 @@ checked in version of that file. This uses no arguments.
With a prefix argument, it reads the file name to use
and two version designators specifying which versions to compare."
(interactive (list current-prefix-arg t))
(vc-ensure-vc-buffer)
(if historic
(call-interactively 'vc-version-diff)
(vc-ensure-vc-buffer)
(let ((file buffer-file-name))
(vc-buffer-sync not-urgent)
(if (vc-workfile-unchanged-p buffer-file-name)
......@@ -1741,37 +1748,13 @@ files in or below it."
" 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
default-directory
(lambda (f)
(vc-exec-after
`(progn
(message "Looking at %s" ',f)
(vc-call-backend ',(vc-backend file) 'diff ',f ',rel1 ',rel2)))))
(let ((dir (file-name-as-directory file)))
(vc-call-backend (vc-responsible-backend dir)
'diff-tree dir rel1 rel2))
(vc-exec-after `(let ((inhibit-read-only t))
(insert "\nEnd of diffs.\n"))))
;; single file 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)
file
(vc-version-backup-file file rel2))))
(if (and file-rel1 file-rel2)
(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))))
(vc-call diff file rel1 rel2))))
(vc-diff-internal file rel1 rel2))
(set-buffer "*vc-diff*")
(if (and (zerop (buffer-size))
(not (get-buffer-process (current-buffer))))
......@@ -1793,6 +1776,35 @@ files in or below it."
(shrink-window-if-larger-than-buffer)))
t))
(defun vc-diff-internal (file rel1 rel2)
"Run diff to compare FILE's revisions REL1 and REL2.
Output goes to the current buffer, which is assumed properly set up.
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)
file
(vc-version-backup-file file rel2)))
(coding-system-for-read (vc-coding-system-for-diff file)))
(if (and file-rel1 file-rel2)
(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))))
(vc-call diff file rel1 rel2))))
(defmacro vc-diff-switches-list (backend)
"Make a list of `diff-switches', `vc-diff-switches',
and `vc-BACKEND-diff-switches'."
......@@ -1804,6 +1816,39 @@ and `vc-BACKEND-diff-switches'."
"-diff-switches")))))
(if (listp backend-switches) backend-switches (list backend-switches)))))
(defun vc-default-diff-tree (backend dir rel1 rel2)
"Default implementation for diffing an entire tree at and below DIR.
The meaning of REL1 and REL2 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,
;; and to call it only for files that are actually changed.
;; However, this is expensive for some backends, and so it is left
;; to backend-specific implementations.
(setq default-directory dir)
(vc-file-tree-walk
default-directory
(lambda (f)
(vc-exec-after
`(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))))))
(defun vc-coding-system-for-diff (file)
"Return the coding system for reading diff output for FILE."
(or coding-system-for-read
;; if we already have this file open,
;; use the buffer's coding system
(let ((buf (find-buffer-visiting file)))
(if buf (with-current-buffer buf
buffer-file-coding-system)))
;; otherwise, try to find one based on the file name
(car (find-operation-coding-system 'insert-file-contents
file))
;; and a final fallback
'undecided))
;;;###autoload
(defun vc-version-other-window (rev)
"Visit version REV of the current buffer in another window.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment