Mercurial > emacs
comparison lisp/vc.el @ 32058:4196f89984ce
* vc.el (vc-editable-p): Minor optimization.
(edit-vc-file, vc-next-action-on-file): Don't use find-file.
(vc-find-new-backend): New function split from vc-responsible-backend.
(vc-register): Use it.
(vc-responsible-backend): Remove REGISTER arg and add BACKENDS arg.
(vc-unregister): Drop BACKEND arg (it doesn't work anyway).
(vc-default-unregister, vc-revert-buffer): Docstring fix.
(vc-clear-headers): Don't use find-file.
(vc-revert-buffer): Use `and' again (must have been a braino).
(vc-switch-backend): Only prompt if requested.
(vc-default-receive-file): Update call to vc-unregister.
* vc-rcs.el (vc-rcs-unregister): Keep a backup of the master file.
(vc-rcs-receive-file): Avoid with-vc-properties.
Update call to vc-unregister.
Use constant `RCS' rather than (dynamically bound) var `backend'.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 01 Oct 2000 19:35:24 +0000 |
parents | fef29341db1c |
children | 13e0fdf65e3c |
comparison
equal
deleted
inserted
replaced
32057:acd9a3daf12b | 32058:4196f89984ce |
---|---|
148 ;; Only required if `annotate-command' is defined for the backend. | 148 ;; Only required if `annotate-command' is defined for the backend. |
149 | 149 |
150 (require 'vc-hooks) | 150 (require 'vc-hooks) |
151 (require 'ring) | 151 (require 'ring) |
152 (eval-when-compile | 152 (eval-when-compile |
153 (require 'cl) | |
153 (require 'compile) | 154 (require 'compile) |
154 (require 'dired) ; for dired-map-over-marks macro | 155 (require 'dired) ; for dired-map-over-marks macro |
155 (require 'dired-aux)) ; for dired-kill-{line,tree} | 156 (require 'dired-aux)) ; for dired-kill-{line,tree} |
156 | 157 |
157 (if (not (assoc 'vc-parent-buffer minor-mode-alist)) | 158 (if (not (assoc 'vc-parent-buffer minor-mode-alist)) |
490 | 491 |
491 ;; Random helper functions | 492 ;; Random helper functions |
492 | 493 |
493 (defsubst vc-editable-p (file) | 494 (defsubst vc-editable-p (file) |
494 (or (eq (vc-checkout-model file) 'implicit) | 495 (or (eq (vc-checkout-model file) 'implicit) |
495 (eq (vc-state file) 'edited) | 496 (memq (vc-state file) '(edited needs-merge)))) |
496 (eq (vc-state file) 'needs-merge))) | |
497 | 497 |
498 ;;; Two macros for elisp programming | 498 ;;; Two macros for elisp programming |
499 ;;;###autoload | 499 ;;;###autoload |
500 (defmacro with-vc-file (file comment &rest body) | 500 (defmacro with-vc-file (file comment &rest body) |
501 "Check out a writable copy of FILE if necessary and execute the body. | 501 "Check out a writable copy of FILE if necessary and execute the body. |
520 Checkin with COMMENT after executing BODY. | 520 Checkin with COMMENT after executing BODY. |
521 This macro uses `with-vc-file', passing args to it. | 521 This macro uses `with-vc-file', passing args to it. |
522 However, before executing BODY, find FILE, and after BODY, save buffer." | 522 However, before executing BODY, find FILE, and after BODY, save buffer." |
523 `(with-vc-file | 523 `(with-vc-file |
524 ,file ,comment | 524 ,file ,comment |
525 (find-file ,file) | 525 (set-buffer (find-file-noselect ,file)) |
526 ,@body | 526 ,@body |
527 (save-buffer))) | 527 (save-buffer))) |
528 | 528 |
529 (defun vc-ensure-vc-buffer () | 529 (defun vc-ensure-vc-buffer () |
530 "Make sure that the current buffer visits a version-controlled file." | 530 "Make sure that the current buffer visits a version-controlled file." |
819 ;; Check relation of buffer and file, and make sure | 819 ;; Check relation of buffer and file, and make sure |
820 ;; user knows what he's doing. First, finding the file | 820 ;; user knows what he's doing. First, finding the file |
821 ;; will check whether the file on disk is newer. | 821 ;; will check whether the file on disk is newer. |
822 (if vc-dired-mode | 822 (if vc-dired-mode |
823 (find-file-other-window file) | 823 (find-file-other-window file) |
824 (find-file file)) | 824 (set-buffer (find-file-noselect file))) |
825 (if (not (verify-visited-file-modtime (current-buffer))) | 825 (if (not (verify-visited-file-modtime (current-buffer))) |
826 (if (yes-or-no-p "Replace file on disk with buffer contents? ") | 826 (if (yes-or-no-p "Replace file on disk with buffer contents? ") |
827 (write-file (buffer-file-name)) | 827 (write-file (buffer-file-name)) |
828 (error "Aborted")) | 828 (error "Aborted")) |
829 ;; Now, check if we have unsaved changes. | 829 ;; Now, check if we have unsaved changes. |
1065 (or comment (not vc-initial-comment)) | 1065 (or comment (not vc-initial-comment)) |
1066 nil | 1066 nil |
1067 "Enter initial comment." | 1067 "Enter initial comment." |
1068 (lambda (file rev comment) | 1068 (lambda (file rev comment) |
1069 (message "Registering %s... " file) | 1069 (message "Registering %s... " file) |
1070 (let ((backend (vc-responsible-backend file))) | 1070 (let ((backend (vc-find-new-backend file))) |
1071 (vc-file-clearprops file) | 1071 (vc-file-clearprops file) |
1072 (vc-call-backend backend 'register file rev comment) | 1072 (vc-call-backend backend 'register file rev comment) |
1073 (vc-file-setprop file 'vc-backend backend) | 1073 (vc-file-setprop file 'vc-backend backend) |
1074 (unless vc-make-backup-files | 1074 (unless vc-make-backup-files |
1075 (make-local-variable 'backup-inhibited) | 1075 (make-local-variable 'backup-inhibited) |
1076 (setq backup-inhibited t))) | 1076 (setq backup-inhibited t))) |
1077 (message "Registering %s... done" file)))) | 1077 (message "Registering %s... done" file)))) |
1078 | 1078 |
1079 (defun vc-responsible-backend (file &optional register) | 1079 (defun vc-responsible-backend (file &optional backends) |
1080 "Return the name of the backend system that is responsible for FILE. | 1080 "Return the name of the backend system that is responsible for FILE. |
1081 If no backend in variable `vc-handled-backends' declares itself | 1081 If no backend in variable `vc-handled-backends' declares itself |
1082 responsible, the first backend in that list will be returned (if optional | 1082 responsible, the first backend in that list will be returned. |
1083 arg REGISTER is non-nil, return the first backend that could register the | 1083 FILE can also be a directory name (ending with a slash). |
1084 file). | 1084 If BACKENDS is non-nil it overrides any current backend or |
1085 FILE can also be a directory name (ending with a slash)." | 1085 `vc-handled-backends'." |
1086 (if (null vc-handled-backends) | 1086 (or (and (not backends) (not (file-directory-p file)) (vc-backend file)) |
1087 (error "Cannot register, no backends in `vc-handled-backends'")) | 1087 (progn |
1088 (or (and (not (file-directory-p file)) (vc-backend file)) | 1088 (unless backends (setq backends vc-handled-backends)) |
1089 (catch 'found | 1089 (unless backends (error "No reponsible backend")) |
1090 (mapcar (lambda (backend) | 1090 (catch 'found |
1091 (if (vc-call-backend backend 'responsible-p file) | 1091 (dolist (backend backends) |
1092 (throw 'found backend))) | 1092 (if (vc-call-backend backend 'responsible-p file) |
1093 vc-handled-backends) | 1093 (throw 'found backend))) |
1094 (if register | 1094 (car backends))))) |
1095 (mapcar (lambda (backend) | 1095 |
1096 (if (vc-call-backend backend 'could-register file) | 1096 (defun vc-find-new-backend (file) |
1097 (throw 'found backend))) | 1097 "Find a new backend to register FILE." |
1098 vc-handled-backends) | 1098 (let (backends) |
1099 (car vc-handled-backends))))) | 1099 ;; We can't register if it's already registered |
1100 (dolist (backend vc-handled-backends) | |
1101 (when (and (not (vc-call-backend backend 'registered file)) | |
1102 (vc-call-backend backend 'could-register file)) | |
1103 (push backend backends))) | |
1104 (unless backends | |
1105 (error "Cannot register, no appropriate backend in `vc-handled-backends'")) | |
1106 (vc-responsible-backend file (nreverse backends)))) | |
1100 | 1107 |
1101 (defun vc-default-responsible-p (backend file) | 1108 (defun vc-default-responsible-p (backend file) |
1102 "Indicate whether BACKEND is reponsible for FILE. | 1109 "Indicate whether BACKEND is reponsible for FILE. |
1103 The default is to return nil always." | 1110 The default is to return nil always." |
1104 nil) | 1111 nil) |
1106 (defun vc-default-could-register (backend file) | 1113 (defun vc-default-could-register (backend file) |
1107 "Return non-nil if BACKEND could be used to register FILE. | 1114 "Return non-nil if BACKEND could be used to register FILE. |
1108 The default implementation returns t for all files." | 1115 The default implementation returns t for all files." |
1109 t) | 1116 t) |
1110 | 1117 |
1111 (defun vc-unregister (file backend) | 1118 (defun vc-unregister (file) |
1112 "Unregister FILE from version control system BACKEND." | 1119 "Unregister FILE from version control system BACKEND." |
1113 (vc-call-backend backend 'unregister file) | 1120 (vc-call unregister file) |
1114 (vc-file-clearprops file)) | 1121 (vc-file-clearprops file)) |
1115 | 1122 |
1116 (defun vc-default-unregister (backend file) | 1123 (defun vc-default-unregister (backend file) |
1117 "Default implementation of vc-unregister, signals an error." | 1124 "Default implementation of `vc-unregister', signals an error." |
1118 (error "Unregistering files is not supported for %s" backend)) | 1125 (error "Unregistering files is not supported for %s" backend)) |
1119 | 1126 |
1120 (defun vc-resynch-window (file &optional keep noquery) | 1127 (defun vc-resynch-window (file &optional keep noquery) |
1121 "If FILE is in the current buffer, either revert or unvisit it. | 1128 "If FILE is in the current buffer, either revert or unvisit it. |
1122 The choice between revert (to see expanded keywords) and unvisit depends on | 1129 The choice between revert (to see expanded keywords) and unvisit depends on |
1586 ;; properly. If it fails, vc-restore-buffer-context | 1593 ;; properly. If it fails, vc-restore-buffer-context |
1587 ;; will give it a second try. | 1594 ;; will give it a second try. |
1588 (save-excursion | 1595 (save-excursion |
1589 (vc-call-backend backend 'clear-headers)) | 1596 (vc-call-backend backend 'clear-headers)) |
1590 (vc-restore-buffer-context context)) | 1597 (vc-restore-buffer-context context)) |
1591 (find-file filename) | 1598 (set-buffer (find-file-noselect filename)) |
1592 (vc-call-backend backend 'clear-headers) | 1599 (vc-call-backend backend 'clear-headers) |
1593 (kill-buffer filename))))) | 1600 (kill-buffer filename))))) |
1594 | 1601 |
1595 ;;;###autoload | 1602 ;;;###autoload |
1596 (defun vc-merge () | 1603 (defun vc-merge () |
2136 | 2143 |
2137 ;;;###autoload | 2144 ;;;###autoload |
2138 (defun vc-revert-buffer () | 2145 (defun vc-revert-buffer () |
2139 "Revert the current buffer's file back to the version it was based on. | 2146 "Revert the current buffer's file back to the version it was based on. |
2140 This asks for confirmation if the buffer contents are not identical | 2147 This asks for confirmation if the buffer contents are not identical |
2141 to that version. Note that for RCS and CVS, this function does not | 2148 to that version. This function does not automatically pick up newer |
2142 automatically pick up newer changes found in the master file; | 2149 changes found in the master file; use \\[universal-argument] \\[vc-next-action] to do so." |
2143 use \\[universal-argument] \\[vc-next-action] to do so." | |
2144 (interactive) | 2150 (interactive) |
2145 (vc-ensure-vc-buffer) | 2151 (vc-ensure-vc-buffer) |
2146 (let ((file buffer-file-name) | 2152 (let ((file buffer-file-name) |
2147 ;; This operation should always ask for confirmation. | 2153 ;; This operation should always ask for confirmation. |
2148 (vc-suppress-confirm nil) | 2154 (vc-suppress-confirm nil) |
2151 (vc-diff nil t) | 2157 (vc-diff nil t) |
2152 (vc-exec-after `(message nil)) | 2158 (vc-exec-after `(message nil)) |
2153 (unwind-protect | 2159 (unwind-protect |
2154 (if (not (yes-or-no-p "Discard changes? ")) | 2160 (if (not (yes-or-no-p "Discard changes? ")) |
2155 (error "Revert canceled")) | 2161 (error "Revert canceled")) |
2156 (if (or (window-dedicated-p (selected-window)) | 2162 (if (and (window-dedicated-p (selected-window)) |
2157 (one-window-p t 'selected-frame)) | 2163 (one-window-p t)) |
2158 (make-frame-invisible (selected-frame)) | 2164 (make-frame-invisible) |
2159 (delete-window)))) | 2165 (delete-window)))) |
2160 (set-buffer obuf) | 2166 (set-buffer obuf) |
2161 ;; Do the reverting | 2167 ;; Do the reverting |
2162 (message "Reverting %s..." file) | 2168 (message "Reverting %s..." file) |
2163 (with-vc-properties | 2169 (with-vc-properties |
2216 (vc-resynch-buffer file t t))) | 2222 (vc-resynch-buffer file t t))) |
2217 (message "Version %s has been removed from the master" target)))) | 2223 (message "Version %s has been removed from the master" target)))) |
2218 | 2224 |
2219 ;;;autoload | 2225 ;;;autoload |
2220 (defun vc-switch-backend (file backend) | 2226 (defun vc-switch-backend (file backend) |
2221 "Make BACKEND the current version control system for FILE. | 2227 "Make BACKEND the current version control system for FILE. |
2222 FILE must already be registered in BACKEND. The change is not | 2228 FILE must already be registered in BACKEND. The change is not |
2223 permanent, only for the current session. This function only changes | 2229 permanent, only for the current session. This function only changes |
2224 VC's perspective on FILE, it does not register or unregister it." | 2230 VC's perspective on FILE, it does not register or unregister it. |
2225 (interactive | 2231 By default, this command cycles through the registered backends. |
2232 To get a prompt, use a prefix argument." | |
2233 (interactive | |
2226 (list | 2234 (list |
2227 buffer-file-name | 2235 buffer-file-name |
2228 (intern (upcase (read-string "Switch to backend: "))))) | 2236 (let ((backend (vc-backend buffer-file-name)) |
2237 (backends nil)) | |
2238 ;; Find the registered backends. | |
2239 (dolist (backend vc-handled-backends) | |
2240 (when (vc-call-backend backend 'registered buffer-file-name) | |
2241 (push backend backends))) | |
2242 ;; Find the next backend. | |
2243 (let ((def (car (delq backend (memq backend (append backends backends))))) | |
2244 (others (delete backend backends))) | |
2245 (cond | |
2246 ((null others) (error "No other backend to switch to")) | |
2247 (current-prefix-arg | |
2248 (intern | |
2249 (upcase | |
2250 (completing-read | |
2251 (format "Switch to backend [%s]: " def) | |
2252 (mapcar (lambda (b) (list (downcase (symbol-name b)))) backends) | |
2253 nil t nil nil (downcase (symbol-name def)))))) | |
2254 (t def)))))) | |
2229 (unless (vc-call-backend backend 'registered file) | 2255 (unless (vc-call-backend backend 'registered file) |
2230 (error "%s is not registered in %s" file backend)) | 2256 (error "%s is not registered in %s" file backend)) |
2231 (vc-file-clearprops file) | 2257 (vc-file-clearprops file) |
2232 (vc-file-setprop file 'vc-backend backend) | 2258 (vc-file-setprop file 'vc-backend backend) |
2233 (vc-resynch-buffer file t t)) | 2259 (vc-resynch-buffer file t t)) |
2263 of the log entry buffer." | 2289 of the log entry buffer." |
2264 (let ((old-backend (vc-backend file)) | 2290 (let ((old-backend (vc-backend file)) |
2265 (rev (vc-workfile-version file)) | 2291 (rev (vc-workfile-version file)) |
2266 (state (vc-state file)) | 2292 (state (vc-state file)) |
2267 (comment (and move (vc-call comment-history file)))) | 2293 (comment (and move (vc-call comment-history file)))) |
2268 (if move (vc-unregister file old-backend)) | 2294 (if move (vc-unregister file)) |
2269 (vc-file-clearprops file) | 2295 (vc-file-clearprops file) |
2270 (if (not (vc-call-backend backend 'registered file)) | 2296 (if (not (vc-call-backend backend 'registered file)) |
2271 (with-vc-properties | 2297 (with-vc-properties |
2272 file | 2298 file |
2273 ;; TODO: If the file was 'edited under the old backend, | 2299 ;; TODO: If the file was 'edited under the old backend, |