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,