diff options
| author | André Spiegel | 2001-10-21 12:15:22 +0000 |
|---|---|---|
| committer | André Spiegel | 2001-10-21 12:15:22 +0000 |
| commit | 2c87edc17b3f7326aff24abe8393bfbfc842c3ba (patch) | |
| tree | bda992d5132e7d820fd22f2201edae5c05a59847 | |
| parent | 8c1a1077c0f85d34684a8faa7cfd9e47bab3e610 (diff) | |
| download | emacs-2c87edc17b3f7326aff24abe8393bfbfc842c3ba.tar.gz emacs-2c87edc17b3f7326aff24abe8393bfbfc842c3ba.zip | |
(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.
| -rw-r--r-- | lisp/vc.el | 105 |
1 files changed, 75 insertions, 30 deletions
diff --git a/lisp/vc.el b/lisp/vc.el index 6a20527d06f..b13c987df15 100644 --- a/lisp/vc.el +++ b/lisp/vc.el | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | ;; Maintainer: Andre Spiegel <spiegel@gnu.org> | 6 | ;; Maintainer: Andre Spiegel <spiegel@gnu.org> |
| 7 | ;; Keywords: tools | 7 | ;; Keywords: tools |
| 8 | 8 | ||
| 9 | ;; $Id: vc.el,v 1.310 2001/09/22 20:04:21 monnier Exp $ | 9 | ;; $Id: vc.el,v 1.311 2001/09/24 22:29:15 monnier Exp $ |
| 10 | 10 | ||
| 11 | ;; This file is part of GNU Emacs. | 11 | ;; This file is part of GNU Emacs. |
| 12 | 12 | ||
| @@ -289,6 +289,13 @@ | |||
| 289 | ;; (no differences found), or 1 (either non-empty diff or the diff is | 289 | ;; (no differences found), or 1 (either non-empty diff or the diff is |
| 290 | ;; run asynchronously). | 290 | ;; run asynchronously). |
| 291 | ;; | 291 | ;; |
| 292 | ;; - diff-tree (dir &optional rev1 rev2) | ||
| 293 | ;; | ||
| 294 | ;; Insert the diff for all files at and below DIR into the *vc-diff* | ||
| 295 | ;; buffer. The meaning of REV1 and REV2 is the same as for | ||
| 296 | ;; vc-BACKEND-diff. The default implementation does an explicit tree | ||
| 297 | ;; walk, calling vc-BACKEND-diff for each individual file. | ||
| 298 | ;; | ||
| 292 | ;; - annotate-command (file buf rev) | 299 | ;; - annotate-command (file buf rev) |
| 293 | ;; | 300 | ;; |
| 294 | ;; If this function is provided, it should produce an annotated version | 301 | ;; 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. | |||
| 1684 | With a prefix argument, it reads the file name to use | 1691 | With a prefix argument, it reads the file name to use |
| 1685 | and two version designators specifying which versions to compare." | 1692 | and two version designators specifying which versions to compare." |
| 1686 | (interactive (list current-prefix-arg t)) | 1693 | (interactive (list current-prefix-arg t)) |
| 1687 | (vc-ensure-vc-buffer) | ||
| 1688 | (if historic | 1694 | (if historic |
| 1689 | (call-interactively 'vc-version-diff) | 1695 | (call-interactively 'vc-version-diff) |
| 1696 | (vc-ensure-vc-buffer) | ||
| 1690 | (let ((file buffer-file-name)) | 1697 | (let ((file buffer-file-name)) |
| 1691 | (vc-buffer-sync not-urgent) | 1698 | (vc-buffer-sync not-urgent) |
| 1692 | (if (vc-workfile-unchanged-p buffer-file-name) | 1699 | (if (vc-workfile-unchanged-p buffer-file-name) |
| @@ -1741,37 +1748,13 @@ files in or below it." | |||
| 1741 | " and " | 1748 | " and " |
| 1742 | (or rel2 "current workfile(s)") | 1749 | (or rel2 "current workfile(s)") |
| 1743 | ":\n\n")) | 1750 | ":\n\n")) |
| 1744 | (setq default-directory (file-name-as-directory file)) | 1751 | (let ((dir (file-name-as-directory file))) |
| 1745 | ;; FIXME: this should do a single exec in CVS. | 1752 | (vc-call-backend (vc-responsible-backend dir) |
| 1746 | (vc-file-tree-walk | 1753 | 'diff-tree dir rel1 rel2)) |
| 1747 | default-directory | ||
| 1748 | (lambda (f) | ||
| 1749 | (vc-exec-after | ||
| 1750 | `(progn | ||
| 1751 | (message "Looking at %s" ',f) | ||
| 1752 | (vc-call-backend ',(vc-backend file) 'diff ',f ',rel1 ',rel2))))) | ||
| 1753 | (vc-exec-after `(let ((inhibit-read-only t)) | 1754 | (vc-exec-after `(let ((inhibit-read-only t)) |
| 1754 | (insert "\nEnd of diffs.\n")))) | 1755 | (insert "\nEnd of diffs.\n")))) |
| 1755 | ;; single file diff | 1756 | ;; single file diff |
| 1756 | (if (or (not rel1) (string-equal rel1 "")) | 1757 | (vc-diff-internal file rel1 rel2)) |
| 1757 | (setq rel1 (vc-workfile-version file))) | ||
| 1758 | (if (string-equal rel2 "") | ||
| 1759 | (setq rel2 nil)) | ||
| 1760 | (let ((file-rel1 (vc-version-backup-file file rel1)) | ||
| 1761 | (file-rel2 (if (not rel2) | ||
| 1762 | file | ||
| 1763 | (vc-version-backup-file file rel2)))) | ||
| 1764 | (if (and file-rel1 file-rel2) | ||
| 1765 | (apply 'vc-do-command "*vc-diff*" 1 "diff" nil | ||
| 1766 | (append (if (listp diff-switches) | ||
| 1767 | diff-switches | ||
| 1768 | (list diff-switches)) | ||
| 1769 | (if (listp vc-diff-switches) | ||
| 1770 | vc-diff-switches | ||
| 1771 | (list vc-diff-switches)) | ||
| 1772 | (list (file-relative-name file-rel1) | ||
| 1773 | (file-relative-name file-rel2)))) | ||
| 1774 | (vc-call diff file rel1 rel2)))) | ||
| 1775 | (set-buffer "*vc-diff*") | 1758 | (set-buffer "*vc-diff*") |
| 1776 | (if (and (zerop (buffer-size)) | 1759 | (if (and (zerop (buffer-size)) |
| 1777 | (not (get-buffer-process (current-buffer)))) | 1760 | (not (get-buffer-process (current-buffer)))) |
| @@ -1793,6 +1776,35 @@ files in or below it." | |||
| 1793 | (shrink-window-if-larger-than-buffer))) | 1776 | (shrink-window-if-larger-than-buffer))) |
| 1794 | t)) | 1777 | t)) |
| 1795 | 1778 | ||
| 1779 | (defun vc-diff-internal (file rel1 rel2) | ||
| 1780 | "Run diff to compare FILE's revisions REL1 and REL2. | ||
| 1781 | Output goes to the current buffer, which is assumed properly set up. | ||
| 1782 | The exit status of the diff command is returned. | ||
| 1783 | |||
| 1784 | This function takes care to set up a proper coding system for diff output. | ||
| 1785 | If both revisions are available as local files, then it also does not | ||
| 1786 | actually call the backend, but performs a local diff." | ||
| 1787 | (if (or (not rel1) (string-equal rel1 "")) | ||
| 1788 | (setq rel1 (vc-workfile-version file))) | ||
| 1789 | (if (string-equal rel2 "") | ||
| 1790 | (setq rel2 nil)) | ||
| 1791 | (let ((file-rel1 (vc-version-backup-file file rel1)) | ||
| 1792 | (file-rel2 (if (not rel2) | ||
| 1793 | file | ||
| 1794 | (vc-version-backup-file file rel2))) | ||
| 1795 | (coding-system-for-read (vc-coding-system-for-diff file))) | ||
| 1796 | (if (and file-rel1 file-rel2) | ||
| 1797 | (apply 'vc-do-command "*vc-diff*" 1 "diff" nil | ||
| 1798 | (append (if (listp diff-switches) | ||
| 1799 | diff-switches | ||
| 1800 | (list diff-switches)) | ||
| 1801 | (if (listp vc-diff-switches) | ||
| 1802 | vc-diff-switches | ||
| 1803 | (list vc-diff-switches)) | ||
| 1804 | (list (file-relative-name file-rel1) | ||
| 1805 | (file-relative-name file-rel2)))) | ||
| 1806 | (vc-call diff file rel1 rel2)))) | ||
| 1807 | |||
| 1796 | (defmacro vc-diff-switches-list (backend) | 1808 | (defmacro vc-diff-switches-list (backend) |
| 1797 | "Make a list of `diff-switches', `vc-diff-switches', | 1809 | "Make a list of `diff-switches', `vc-diff-switches', |
| 1798 | and `vc-BACKEND-diff-switches'." | 1810 | and `vc-BACKEND-diff-switches'." |
| @@ -1804,6 +1816,39 @@ and `vc-BACKEND-diff-switches'." | |||
| 1804 | "-diff-switches"))))) | 1816 | "-diff-switches"))))) |
| 1805 | (if (listp backend-switches) backend-switches (list backend-switches))))) | 1817 | (if (listp backend-switches) backend-switches (list backend-switches))))) |
| 1806 | 1818 | ||
| 1819 | (defun vc-default-diff-tree (backend dir rel1 rel2) | ||
| 1820 | "Default implementation for diffing an entire tree at and below DIR. | ||
| 1821 | The meaning of REL1 and REL2 is the same as for `vc-version-diff'." | ||
| 1822 | ;; This implementation does an explicit tree walk, and calls | ||
| 1823 | ;; vc-BACKEND-diff directly for each file. An optimization | ||
| 1824 | ;; would be to use `vc-diff-internal', so that diffs can be local, | ||
| 1825 | ;; and to call it only for files that are actually changed. | ||
| 1826 | ;; However, this is expensive for some backends, and so it is left | ||
| 1827 | ;; to backend-specific implementations. | ||
| 1828 | (setq default-directory dir) | ||
| 1829 | (vc-file-tree-walk | ||
| 1830 | default-directory | ||
| 1831 | (lambda (f) | ||
| 1832 | (vc-exec-after | ||
| 1833 | `(let ((coding-system-for-read (vc-coding-system-for-diff ',f))) | ||
| 1834 | (message "Looking at %s" ',f) | ||
| 1835 | (vc-call-backend ',(vc-backend f) | ||
| 1836 | 'diff ',f ',rel1 ',rel2)))))) | ||
| 1837 | |||
| 1838 | (defun vc-coding-system-for-diff (file) | ||
| 1839 | "Return the coding system for reading diff output for FILE." | ||
| 1840 | (or coding-system-for-read | ||
| 1841 | ;; if we already have this file open, | ||
| 1842 | ;; use the buffer's coding system | ||
| 1843 | (let ((buf (find-buffer-visiting file))) | ||
| 1844 | (if buf (with-current-buffer buf | ||
| 1845 | buffer-file-coding-system))) | ||
| 1846 | ;; otherwise, try to find one based on the file name | ||
| 1847 | (car (find-operation-coding-system 'insert-file-contents | ||
| 1848 | file)) | ||
| 1849 | ;; and a final fallback | ||
| 1850 | 'undecided)) | ||
| 1851 | |||
| 1807 | ;;;###autoload | 1852 | ;;;###autoload |
| 1808 | (defun vc-version-other-window (rev) | 1853 | (defun vc-version-other-window (rev) |
| 1809 | "Visit version REV of the current buffer in another window. | 1854 | "Visit version REV of the current buffer in another window. |