Mercurial > emacs
comparison 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 |
comparison
equal
deleted
inserted
replaced
40123:e528f2adeed4 | 40124:9031427edfa3 |
---|---|
4 | 4 |
5 ;; Author: FSF (see below for full credits) | 5 ;; Author: FSF (see below for full credits) |
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 |
13 ;; GNU Emacs is free software; you can redistribute it and/or modify | 13 ;; GNU Emacs is free software; you can redistribute it and/or modify |
14 ;; it under the terms of the GNU General Public License as published by | 14 ;; it under the terms of the GNU General Public License as published by |
286 ;; use the current workfile version (as found in the repository) as the | 286 ;; use the current workfile version (as found in the repository) as the |
287 ;; older version; if REV2 is nil, use the current workfile contents as | 287 ;; older version; if REV2 is nil, use the current workfile contents as |
288 ;; the newer version. This function should return a status of either 0 | 288 ;; the newer version. This function should return a status of either 0 |
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 ;; | |
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. | |
291 ;; | 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 |
295 ;; of FILE in BUF, relative to version REV. This is currently only | 302 ;; of FILE in BUF, relative to version REV. This is currently only |
1682 Normally this compares the current file and buffer with the most recent | 1689 Normally this compares the current file and buffer with the most recent |
1683 checked in version of that file. This uses no arguments. | 1690 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) |
1693 (message "No changes to %s since latest version" file) | 1700 (message "No changes to %s since latest version" file) |
1694 (vc-version-diff file nil nil))))) | 1701 (vc-version-diff file nil nil))))) |
1739 (insert "Diffs between " | 1746 (insert "Diffs between " |
1740 (or rel1 "last version checked in") | 1747 (or rel1 "last version checked in") |
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)))) |
1778 (progn | 1761 (progn |
1779 (if rel1 | 1762 (if rel1 |
1791 (insert "No differences found.\n")) | 1774 (insert "No differences found.\n")) |
1792 (goto-char (point-min)) | 1775 (goto-char (point-min)) |
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'." |
1799 `(append | 1811 `(append |
1800 (if (listp diff-switches) diff-switches (list diff-switches)) | 1812 (if (listp diff-switches) diff-switches (list diff-switches)) |
1801 (if (listp vc-diff-switches) vc-diff-switches (list vc-diff-switches)) | 1813 (if (listp vc-diff-switches) vc-diff-switches (list vc-diff-switches)) |
1802 (let ((backend-switches | 1814 (let ((backend-switches |
1803 (eval (intern (concat "vc-" (symbol-name ',backend) | 1815 (eval (intern (concat "vc-" (symbol-name ',backend) |
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))))) |
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)) | |
1806 | 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. |
1810 If the current buffer is named `F', the version is named `F.~REV~'. | 1855 If the current buffer is named `F', the version is named `F.~REV~'. |