Mercurial > emacs
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))) |