comparison lisp/vc.el @ 81963:535f90fff765

Put the lower half (the back-end) of NewVC in place. This commit makes only the minimum changes needed to get the old vc.el logic working with the new back ends.
author Eric S. Raymond <esr@snark.thyrsus.com>
date Wed, 18 Jul 2007 16:32:33 +0000
parents 8f9991bf3b41
children e320f477727a a1be62cbd32a
comparison
equal deleted inserted replaced
81962:0744b309302b 81963:535f90fff765
99 ;; 99 ;;
100 ;; In the list of functions below, each identifier needs to be prepended 100 ;; In the list of functions below, each identifier needs to be prepended
101 ;; with `vc-sys-'. Some of the functions are mandatory (marked with a 101 ;; with `vc-sys-'. Some of the functions are mandatory (marked with a
102 ;; `*'), others are optional (`-'). 102 ;; `*'), others are optional (`-').
103 ;; 103 ;;
104 ;; BACKEND PROPERTIES
105 ;;
106 ;; * revision-granularity
107 ;;
108 ;; Takes no arguments. Returns either 'file or 'repository.
109 ;;
104 ;; STATE-QUERYING FUNCTIONS 110 ;; STATE-QUERYING FUNCTIONS
105 ;; 111 ;;
106 ;; * registered (file) 112 ;; * registered (file)
107 ;; 113 ;;
108 ;; Return non-nil if FILE is registered in this backend. Both this 114 ;; Return non-nil if FILE is registered in this backend. Both this
169 ;; used in a vc-dired buffer. The default implementation deals well 175 ;; used in a vc-dired buffer. The default implementation deals well
170 ;; with all states that `vc-state' can return. 176 ;; with all states that `vc-state' can return.
171 ;; 177 ;;
172 ;; STATE-CHANGING FUNCTIONS 178 ;; STATE-CHANGING FUNCTIONS
173 ;; 179 ;;
174 ;; * register (file &optional rev comment) 180 ;; * create-repo (backend)
175 ;; 181 ;;
176 ;; Register FILE in this backend. Optionally, an initial revision REV 182 ;; Create an empty repository in the current directory and initialize
177 ;; and an initial description of the file, COMMENT, may be specified. 183 ;; it so VC mode can add files to it. For file-oriented systems, this
184 ;; need do no more than create a subdirectory with the right name.
185 ;;
186 ;; * register (files &optional rev comment)
187 ;;
188 ;; Register FILES in this backend. Optionally, an initial revision REV
189 ;; and an initial description of the file, COMMENT, may be specified,
190 ;; but it is not guaranteed that the backend will do anything with this.
178 ;; The implementation should pass the value of vc-register-switches 191 ;; The implementation should pass the value of vc-register-switches
179 ;; to the backend command. 192 ;; to the backend command. (Note: in older versions of VC, this
193 ;; command took a single file argument and not a list.)
180 ;; 194 ;;
181 ;; - init-version (file) 195 ;; - init-version (file)
182 ;; 196 ;;
183 ;; The initial version to use when registering FILE if one is not 197 ;; The initial version to use when registering FILE if one is not
184 ;; specified by the user. If not provided, the variable 198 ;; specified by the user. If not provided, the variable
208 ;; - unregister (file) 222 ;; - unregister (file)
209 ;; 223 ;;
210 ;; Unregister FILE from this backend. This is only needed if this 224 ;; Unregister FILE from this backend. This is only needed if this
211 ;; backend may be used as a "more local" backend for temporary editing. 225 ;; backend may be used as a "more local" backend for temporary editing.
212 ;; 226 ;;
213 ;; * checkin (file rev comment) 227 ;; * checkin (files rev comment)
214 ;; 228 ;;
215 ;; Commit changes in FILE to this backend. If REV is non-nil, that 229 ;; Commit changes in FILES to this backend. If REV is non-nil, that
216 ;; should become the new revision number. COMMENT is used as a 230 ;; should become the new revision number (not all backends do
217 ;; check-in comment. The implementation should pass the value of 231 ;; anything with it). COMMENT is used as a check-in comment. The
218 ;; vc-checkin-switches to the backend command. 232 ;; implementation should pass the value of vc-checkin-switches to
233 ;; the backend command. (Note: in older versions of VC, this
234 ;; command took a single file argument and not a list.)
219 ;; 235 ;;
220 ;; * find-version (file rev buffer) 236 ;; * find-version (file rev buffer)
221 ;; 237 ;;
222 ;; Fetch revision REV of file FILE and put it into BUFFER. 238 ;; Fetch revision REV of file FILE and put it into BUFFER.
223 ;; If REV is the empty string, fetch the head of the trunk. 239 ;; If REV is the empty string, fetch the head of the trunk.
240 ;; Revert FILE back to the current workfile version. If optional 256 ;; Revert FILE back to the current workfile version. If optional
241 ;; arg CONTENTS-DONE is non-nil, then the contents of FILE have 257 ;; arg CONTENTS-DONE is non-nil, then the contents of FILE have
242 ;; already been reverted from a version backup, and this function 258 ;; already been reverted from a version backup, and this function
243 ;; only needs to update the status of FILE within the backend. 259 ;; only needs to update the status of FILE within the backend.
244 ;; 260 ;;
245 ;; - rollback (file editable) 261 ;; - rollback (files)
246 ;; 262 ;;
247 ;; Cancel the current workfile version of FILE, i.e. remove it from the 263 ;; Remove the tip version of each of FILES from the repository. If
248 ;; master. EDITABLE non-nil means that FILE should be writable 264 ;; this function is not provided, trying to cancel a version is
249 ;; afterwards, and if locking is used for FILE, then a lock should also 265 ;; caught as an error. (Most backends don't provide it.) (Also
250 ;; be set. If this function is not provided, trying to cancel a 266 ;; note that older versions of this backend command were called
251 ;; version is caught as an error. 267 ;; 'cancel-version' and took a single file arg, not a list of
268 ;; files.)
252 ;; 269 ;;
253 ;; - merge (file rev1 rev2) 270 ;; - merge (file rev1 rev2)
254 ;; 271 ;;
255 ;; Merge the changes between REV1 and REV2 into the current working file. 272 ;; Merge the changes between REV1 and REV2 into the current working file.
256 ;; 273 ;;
265 ;; locking is used for files under this backend, and if files can 282 ;; locking is used for files under this backend, and if files can
266 ;; indeed be locked by other users. 283 ;; indeed be locked by other users.
267 ;; 284 ;;
268 ;; HISTORY FUNCTIONS 285 ;; HISTORY FUNCTIONS
269 ;; 286 ;;
270 ;; * print-log (file &optional buffer) 287 ;; * print-log (files &optional buffer)
271 ;; 288 ;;
272 ;; Insert the revision log of FILE into BUFFER, or the *vc* buffer 289 ;; Insert the revision log for FILES into BUFFER, or the *vc* buffer
273 ;; if BUFFER is nil. 290 ;; if BUFFER is nil. (Note: older versions of this function expected
291 ;; only a single file argument.)
274 ;; 292 ;;
275 ;; - log-view-mode () 293 ;; - log-view-mode ()
276 ;; 294 ;;
277 ;; Mode to use for the output of print-log. This defaults to 295 ;; Mode to use for the output of print-log. This defaults to
278 ;; `log-view-mode' and is expected to be changed (if at all) to a derived 296 ;; `log-view-mode' and is expected to be changed (if at all) to a derived
974 (defvar vc-post-command-functions nil 992 (defvar vc-post-command-functions nil
975 "Hook run at the end of `vc-do-command'. 993 "Hook run at the end of `vc-do-command'.
976 Each function is called inside the buffer in which the command was run 994 Each function is called inside the buffer in which the command was run
977 and is passed 3 arguments: the COMMAND, the FILE and the FLAGS.") 995 and is passed 3 arguments: the COMMAND, the FILE and the FLAGS.")
978 996
997 (defun vc-delistify (filelist)
998 "Smash a FILELIST into a file list string suitable for info messages."
999 (cond ((not filelist) ".")
1000 ((= (length filelist) 1) (car filelist))
1001 (t (concat (car filelist) " " (vc-delistify (cdr filelist))))))
1002
979 (defvar w32-quote-process-args) 1003 (defvar w32-quote-process-args)
980 ;;;###autoload 1004 ;;;###autoload
981 (defun vc-do-command (buffer okstatus command file &rest flags) 1005 (defun vc-do-command (buffer okstatus command file-or-list &rest flags)
982 "Execute a VC command, notifying user and checking for errors. 1006 "Execute a VC command, notifying user and checking for errors.
983 Output from COMMAND goes to BUFFER, or *vc* if BUFFER is nil or the 1007 Output from COMMAND goes to BUFFER, or *vc* if BUFFER is nil or the
984 current buffer if BUFFER is t. If the destination buffer is not 1008 current buffer if BUFFER is t. If the destination buffer is not
985 already current, set it up properly and erase it. The command is 1009 already current, set it up properly and erase it. The command is
986 considered successful if its exit status does not exceed OKSTATUS (if 1010 considered successful if its exit status does not exceed OKSTATUS (if
987 OKSTATUS is nil, that means to ignore error status, if it is `async', that 1011 OKSTATUS is nil, that means to ignore error status, if it is `async', that
988 means not to wait for termination of the subprocess; if it is t it means to 1012 means not to wait for termination of the subprocess; if it is t it means to
989 ignore all execution errors). FILE is the 1013 ignore all execution errors). FILE-OR-LIST is the name of a working file;
990 name of the working file (may also be nil, to execute commands that 1014 it may be a list of files or be nil (to execute commands that don't expect
991 don't expect a file name). If an optional list of FLAGS is present, 1015 a file name or set of files). If an optional list of FLAGS is present,
992 that is inserted into the command line before the filename." 1016 that is inserted into the command line before the filename."
993 (and file (setq file (expand-file-name file))) 1017 ;; FIXME: file-relative-name can return a bogus result because
994 (if vc-command-messages 1018 ;; it doesn't look at the actual file-system to see if symlinks
995 (message "Running %s on %s..." command file)) 1019 ;; come into play.
996 (save-current-buffer 1020 (let* ((files
997 (unless (or (eq buffer t) 1021 (mapcar 'file-relative-name
998 (and (stringp buffer) 1022 (cond ((not file-or-list) '())
999 (string= (buffer-name) buffer)) 1023 ((listp file-or-list) (mapcar 'expand-file-name file-or-list))
1000 (eq buffer (current-buffer))) 1024 (t (list (expand-file-name file-or-list))))))
1001 (vc-setup-buffer buffer)) 1025 (full-command
1002 (let ((squeezed (remq nil flags)) 1026 (concat command " " (vc-delistify flags) " " (vc-delistify files))))
1003 (inhibit-read-only t) 1027 (if vc-command-messages
1004 (status 0)) 1028 (message "Running %s..." full-command))
1005 (when file 1029 (save-current-buffer
1006 ;; FIXME: file-relative-name can return a bogus result because 1030 (unless (or (eq buffer t)
1007 ;; it doesn't look at the actual file-system to see if symlinks 1031 (and (stringp buffer)
1008 ;; come into play. 1032 (string= (buffer-name) buffer))
1009 (setq squeezed (append squeezed (list (file-relative-name file))))) 1033 (eq buffer (current-buffer)))
1010 (let ((exec-path (append vc-path exec-path)) 1034 (vc-setup-buffer buffer))
1011 ;; Add vc-path to PATH for the execution of this command. 1035 (let ((squeezed (remq nil flags))
1012 (process-environment 1036 (inhibit-read-only t)
1013 (cons (concat "PATH=" (getenv "PATH") 1037 (status 0))
1014 path-separator 1038 (when files
1015 (mapconcat 'identity vc-path path-separator)) 1039 (setq squeezed (nconc squeezed files)))
1016 process-environment)) 1040 (let ((exec-path (append vc-path exec-path))
1017 (w32-quote-process-args t)) 1041 ;; Add vc-path to PATH for the execution of this command.
1018 (if (and (eq okstatus 'async) (file-remote-p default-directory)) 1042 (process-environment
1019 ;; start-process does not support remote execution 1043 (cons (concat "PATH=" (getenv "PATH")
1020 (setq okstatus nil)) 1044 path-separator
1021 (if (eq okstatus 'async) 1045 (mapconcat 'identity vc-path path-separator))
1022 (let ((proc 1046 process-environment))
1023 (let ((process-connection-type nil)) 1047 (w32-quote-process-args t))
1024 (apply 'start-process command (current-buffer) command 1048 (if (and (eq okstatus 'async) (file-remote-p default-directory))
1025 squeezed)))) 1049 ;; start-process does not support remote execution
1026 (unless (active-minibuffer-window) 1050 (setq okstatus nil))
1027 (message "Running %s in the background..." command)) 1051 (if (eq okstatus 'async)
1028 ;;(set-process-sentinel proc (lambda (p msg) (delete-process p))) 1052 (let ((proc
1029 (set-process-filter proc 'vc-process-filter) 1053 (let ((process-connection-type nil))
1030 (vc-exec-after 1054 (apply 'start-process command (current-buffer) command
1031 `(unless (active-minibuffer-window) 1055 squeezed))))
1032 (message "Running %s in the background... done" ',command)))) 1056 (unless (active-minibuffer-window)
1033 (let ((buffer-undo-list t)) 1057 (message "Running %s in the background..." full-command))
1034 (setq status (apply 'process-file command nil t nil squeezed))) 1058 ;;(set-process-sentinel proc (lambda (p msg) (delete-process p)))
1035 (when (and (not (eq t okstatus)) 1059 (set-process-filter proc 'vc-process-filter)
1036 (or (not (integerp status)) 1060 (vc-exec-after
1037 (and okstatus (< okstatus status)))) 1061 `(unless (active-minibuffer-window)
1038 (pop-to-buffer (current-buffer)) 1062 (message "Running %s in the background... done" ',full-command))))
1039 (goto-char (point-min)) 1063 (let ((buffer-undo-list t))
1040 (shrink-window-if-larger-than-buffer) 1064 (setq status (apply 'process-file command nil t nil squeezed)))
1041 (error "Running %s...FAILED (%s)" command 1065 (when (and (not (eq t okstatus))
1042 (if (integerp status) (format "status %d" status) status)))) 1066 (or (not (integerp status))
1043 (if vc-command-messages 1067 (and okstatus (< okstatus status))))
1044 (message "Running %s...OK" command))) 1068 (pop-to-buffer (current-buffer))
1045 (vc-exec-after 1069 (goto-char (point-min))
1046 `(run-hook-with-args 'vc-post-command-functions ',command ',file ',flags)) 1070 (shrink-window-if-larger-than-buffer)
1047 status))) 1071 (error "Running %s...FAILED (%s)" full-command
1072 (if (integerp status) (format "status %d" status) status))))
1073 (if vc-command-messages
1074 (message "Running %s...OK" full-command)))
1075 (vc-exec-after
1076 `(run-hook-with-args 'vc-post-command-functions ',command ',file-or-list ',flags))
1077 status))))
1048 1078
1049 (defun vc-position-context (posn) 1079 (defun vc-position-context (posn)
1050 "Save a bit of the text around POSN in the current buffer. 1080 "Save a bit of the text around POSN in the current buffer.
1051 Used to help us find the corresponding position again later 1081 Used to help us find the corresponding position again later
1052 if markers are destroyed or corrupted." 1082 if markers are destroyed or corrupted."
1462 "Enter initial comment." 1492 "Enter initial comment."
1463 (lambda (file rev comment) 1493 (lambda (file rev comment)
1464 (message "Registering %s... " file) 1494 (message "Registering %s... " file)
1465 (let ((backend (vc-responsible-backend file t))) 1495 (let ((backend (vc-responsible-backend file t)))
1466 (vc-file-clearprops file) 1496 (vc-file-clearprops file)
1467 (vc-call-backend backend 'register file rev comment) 1497 (vc-call-backend backend 'register (list file) rev comment)
1468 (vc-file-setprop file 'vc-backend backend) 1498 (vc-file-setprop file 'vc-backend backend)
1469 (unless vc-make-backup-files 1499 (unless vc-make-backup-files
1470 (make-local-variable 'backup-inhibited) 1500 (make-local-variable 'backup-inhibited)
1471 (setq backup-inhibited t))) 1501 (setq backup-inhibited t)))
1472 (message "Registering %s... done" file)))) 1502 (message "Registering %s... done" file))))
1517 1547
1518 (defun vc-default-could-register (backend file) 1548 (defun vc-default-could-register (backend file)
1519 "Return non-nil if BACKEND could be used to register FILE. 1549 "Return non-nil if BACKEND could be used to register FILE.
1520 The default implementation returns t for all files." 1550 The default implementation returns t for all files."
1521 t) 1551 t)
1552
1553 (defun vc-expand-dirs (file-or-dir-list)
1554 "Expands directories in a file list specification.
1555 Only files already under version control are noticed."
1556 (let ((flattened '()))
1557 (dolist (node file-or-dir-list)
1558 (vc-file-tree-walk node (lambda (f) (if (vc-backend f) (setq flattened (cons f flattened))))))
1559 (nreverse flattened)))
1522 1560
1523 (defun vc-resynch-window (file &optional keep noquery) 1561 (defun vc-resynch-window (file &optional keep noquery)
1524 "If FILE is in the current buffer, either revert or unvisit it. 1562 "If FILE is in the current buffer, either revert or unvisit it.
1525 The choice between revert (to see expanded keywords) and unvisit depends on 1563 The choice between revert (to see expanded keywords) and unvisit depends on
1526 `vc-keep-workfiles'. NOQUERY if non-nil inhibits confirmation for 1564 `vc-keep-workfiles'. NOQUERY if non-nil inhibits confirmation for
1674 (with-vc-properties 1712 (with-vc-properties
1675 file 1713 file
1676 ;; Change buffers to get local value of vc-checkin-switches. 1714 ;; Change buffers to get local value of vc-checkin-switches.
1677 (with-current-buffer (or (get-file-buffer file) (current-buffer)) 1715 (with-current-buffer (or (get-file-buffer file) (current-buffer))
1678 (progn 1716 (progn
1679 (vc-call checkin file rev comment) 1717 (vc-call checkin (list file) rev comment)
1680 (vc-delete-automatic-version-backups file))) 1718 (vc-delete-automatic-version-backups file)))
1681 `((vc-state . up-to-date) 1719 `((vc-state . up-to-date)
1682 (vc-checkout-time . ,(nth 5 (file-attributes file))) 1720 (vc-checkout-time . ,(nth 5 (file-attributes file)))
1683 (vc-workfile-version . nil))) 1721 (vc-workfile-version . nil)))
1684 (message "Checking in %s...done" file)) 1722 (message "Checking in %s...done" file))
1894 (list (file-relative-name file-rev1) 1932 (list (file-relative-name file-rev1)
1895 (file-relative-name file-rev2))))) 1933 (file-relative-name file-rev2)))))
1896 (error "diff failed")) 1934 (error "diff failed"))
1897 (if (not vc-diff-knows-L) (setq vc-diff-knows-L 'yes))) 1935 (if (not vc-diff-knows-L) (setq vc-diff-knows-L 'yes)))
1898 status) 1936 status)
1899 (vc-call diff file rev1 rev2)))) 1937 (vc-call diff (list file) rev1 rev2))))
1900 1938
1901 (defun vc-switches (backend op) 1939 (defun vc-switches (backend op)
1902 (let ((switches 1940 (let ((switches
1903 (or (if backend 1941 (or (if backend
1904 (let ((sym (vc-make-backend-sym 1942 (let ((sym (vc-make-backend-sym
2478 (vc-find-backend-function (vc-backend file) 2516 (vc-find-backend-function (vc-backend file)
2479 'print-log)))) 2517 'print-log))))
2480 (not (eq (caddr err) 2))) 2518 (not (eq (caddr err) 2)))
2481 (signal (car err) (cdr err)) 2519 (signal (car err) (cdr err))
2482 ;; for backward compatibility 2520 ;; for backward compatibility
2483 (vc-call print-log file) 2521 (vc-call print-log (list file))
2484 (set-buffer "*vc*")))) 2522 (set-buffer "*vc*"))))
2485 (pop-to-buffer (current-buffer)) 2523 (pop-to-buffer (current-buffer))
2486 (vc-exec-after 2524 (vc-exec-after
2487 `(let ((inhibit-read-only t)) 2525 `(let ((inhibit-read-only t))
2488 (vc-call-backend ',(vc-backend file) 'log-view-mode) 2526 (vc-call-backend ',(vc-backend file) 'log-view-mode)
2657 `((vc-state . up-to-date) 2695 `((vc-state . up-to-date)
2658 (vc-checkout-time . ,(nth 5 (file-attributes file))))) 2696 (vc-checkout-time . ,(nth 5 (file-attributes file)))))
2659 (vc-resynch-buffer file t t)) 2697 (vc-resynch-buffer file t t))
2660 2698
2661 ;;;###autoload 2699 ;;;###autoload
2662 (defun vc-rollback (norevert) 2700 (defun vc-rollback ()
2663 "Get rid of most recently checked in version of this file. 2701 "Get rid of most recently checked in version of this file."
2664 A prefix argument NOREVERT means do not revert the buffer afterwards."
2665 (interactive "P") 2702 (interactive "P")
2666 (vc-ensure-vc-buffer) 2703 (vc-ensure-vc-buffer)
2667 (let* ((file buffer-file-name) 2704 (let* ((file buffer-file-name)
2668 (backend (vc-backend file)) 2705 (backend (vc-backend file))
2669 (target (vc-workfile-version file))) 2706 (target (vc-workfile-version file)))
2680 (yes-or-no-p "Revert buffer to most recent remaining version? ")))) 2717 (yes-or-no-p "Revert buffer to most recent remaining version? "))))
2681 2718
2682 (message "Removing last change from %s..." file) 2719 (message "Removing last change from %s..." file)
2683 (with-vc-properties 2720 (with-vc-properties
2684 file 2721 file
2685 (vc-call rollback file norevert) 2722 (vc-call rollback (list file))
2686 `((vc-state . ,(if norevert 'edited 'up-to-date)) 2723 `((vc-state . ,(if norevert 'edited 'up-to-date))
2687 (vc-checkout-time . ,(if norevert 2724 (vc-checkout-time . ,(if norevert
2688 0 2725 0
2689 (nth 5 (file-attributes file)))) 2726 (nth 5 (file-attributes file))))
2690 (vc-workfile-version . nil))) 2727 (vc-workfile-version . nil)))