Mercurial > emacs
diff lisp/vc.el @ 40124:9031427edfa3
(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.
author | André Spiegel <spiegel@gnu.org> |
---|---|
date | Sun, 21 Oct 2001 12:15:22 +0000 |
parents | 900ad37906a7 |
children | 2e0eb9ecea2c |
line wrap: on
line diff
--- a/lisp/vc.el Sun Oct 21 12:13:46 2001 +0000 +++ b/lisp/vc.el Sun Oct 21 12:15:22 2001 +0000 @@ -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 @@ 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 @@ " 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 @@ (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 @@ "-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.