diff options
| author | Eric S. Raymond | 2007-10-10 13:17:53 +0000 |
|---|---|---|
| committer | Eric S. Raymond | 2007-10-10 13:17:53 +0000 |
| commit | d7b60083ce07eb9d4af2bdb97c1062e42445f395 (patch) | |
| tree | d2f4e53f66b9423c908fb25c828f6fac24347352 | |
| parent | 84062ef1fea8e708c12a0e087c48b9e589690a99 (diff) | |
| download | emacs-d7b60083ce07eb9d4af2bdb97c1062e42445f395.tar.gz emacs-d7b60083ce07eb9d4af2bdb97c1062e42445f395.zip | |
Merge in new VC with filesets.
| -rwxr-xr-x | configure | 12 | ||||
| -rw-r--r-- | lisp/ChangeLog | 51 | ||||
| -rw-r--r-- | lisp/vc.el | 1092 |
3 files changed, 594 insertions, 561 deletions
| @@ -18532,11 +18532,13 @@ _ACEOF | |||
| 18532 | cat confdefs.h >>conftest.$ac_ext | 18532 | cat confdefs.h >>conftest.$ac_ext |
| 18533 | cat >>conftest.$ac_ext <<_ACEOF | 18533 | cat >>conftest.$ac_ext <<_ACEOF |
| 18534 | /* end confdefs.h. */ | 18534 | /* end confdefs.h. */ |
| 18535 | #include <stdio.h> | 18535 | #include <sys/types.h> /* for off_t */ |
| 18536 | #include <stdio.h> | ||
| 18536 | int | 18537 | int |
| 18537 | main () | 18538 | main () |
| 18538 | { | 18539 | { |
| 18539 | return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0); | 18540 | int (*fp) (FILE *, off_t, int) = fseeko; |
| 18541 | return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); | ||
| 18540 | ; | 18542 | ; |
| 18541 | return 0; | 18543 | return 0; |
| 18542 | } | 18544 | } |
| @@ -18576,11 +18578,13 @@ cat confdefs.h >>conftest.$ac_ext | |||
| 18576 | cat >>conftest.$ac_ext <<_ACEOF | 18578 | cat >>conftest.$ac_ext <<_ACEOF |
| 18577 | /* end confdefs.h. */ | 18579 | /* end confdefs.h. */ |
| 18578 | #define _LARGEFILE_SOURCE 1 | 18580 | #define _LARGEFILE_SOURCE 1 |
| 18579 | #include <stdio.h> | 18581 | #include <sys/types.h> /* for off_t */ |
| 18582 | #include <stdio.h> | ||
| 18580 | int | 18583 | int |
| 18581 | main () | 18584 | main () |
| 18582 | { | 18585 | { |
| 18583 | return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0); | 18586 | int (*fp) (FILE *, off_t, int) = fseeko; |
| 18587 | return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); | ||
| 18584 | ; | 18588 | ; |
| 18585 | return 0; | 18589 | return 0; |
| 18586 | } | 18590 | } |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8bf8c4a9342..77642d58232 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,54 @@ | |||
| 1 | 2007-10-10 Eric S. Raymond <esr@snark.thyrsus.com> | ||
| 2 | |||
| 3 | * vc.el (vc-next-action): Completely rewritten; this principal | ||
| 4 | entry point now operates on a current fileset selected either | ||
| 5 | explicitly via VC-Dired or implicitly by visiting a file buffer, | ||
| 6 | rather than always operating on the file of the current buffer as | ||
| 7 | in older versions. The rest of the mode has been rewritten to | ||
| 8 | match. | ||
| 9 | (with-vc-properties): Rewritten to operate on a file list. | ||
| 10 | (with-vc-file): vc-checkin takes a file list argument now. | ||
| 11 | (vc-post-command-functions): This hook now receives a file list. | ||
| 12 | (vc-do-command): Now takes a either a file or a file list as | ||
| 13 | argument. | ||
| 14 | (vc-deduce-fileset): New function for deducing a file list to | ||
| 15 | operate on. | ||
| 16 | (vc-next-action-on-file): This function is gone, it is merged into | ||
| 17 | vc-next-action. | ||
| 18 | (vc-next-action-dired): This function is gone, it is merged into | ||
| 19 | vc-next-action. | ||
| 20 | (vc-register): Adapted to the fact that vc-start-entry now takes a | ||
| 21 | file list. | ||
| 22 | (vc-register-with): New function. | ||
| 23 | (vc-start-entry): Now takes a file list argument rather than a | ||
| 24 | file argument. | ||
| 25 | (vc-checkout): Modified to cope with vc-start-entry taking a file | ||
| 26 | list. | ||
| 27 | (vc-steal-lock): Modified to cope with with-vc-properties taking a | ||
| 28 | file list. | ||
| 29 | (vc-checkin): Now takes a file list argument rather than a file | ||
| 30 | argument. | ||
| 31 | (vc-finish-logentry): Use the filelist passed by vc-start-entry. | ||
| 32 | (vc-diff-internal): Completely rewritten for filesets. | ||
| 33 | (vc-diff-sentinel): New function, tests whether changes were | ||
| 34 | written into a diff buffer. | ||
| 35 | (vc-diff): Completely rewritten for filesets. | ||
| 36 | (vc-version-diff): Completely rewritten for filesets. | ||
| 37 | (vc-print-log): Now takes a fileset argument. | ||
| 38 | (vc-revert): Now reverts the entire selected fileset, not just the | ||
| 39 | current buffer. | ||
| 40 | (vc-rollback): Now rolls back the entire selected fileset, if | ||
| 41 | possible. No longer accepts a prefix argument. | ||
| 42 | (vc-update): Now merges new changes for the entire selected | ||
| 43 | fileset, not just the current buffer. | ||
| 44 | (vc-revert-file): Modified to cope with with-vc-properties taking | ||
| 45 | a file list. | ||
| 46 | (vc-default-dired-state-info): Add + status suffix if the file is | ||
| 47 | modified. | ||
| 48 | (vc-annotate-warp-version): Use the new diff machinery. | ||
| 49 | (vc-log-edit): Now takes a file list argument rather than a file | ||
| 50 | argument. | ||
| 51 | |||
| 1 | 2007-10-10 Michael Albinus <michael.albinus@gmx.de> | 52 | 2007-10-10 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 53 | ||
| 3 | Sync with Tramp 2.1.11. | 54 | Sync with Tramp 2.1.11. |
diff --git a/lisp/vc.el b/lisp/vc.el index bfcea833c9d..d88852eb8c8 100644 --- a/lisp/vc.el +++ b/lisp/vc.el | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | ;; Maintainer: Andre Spiegel <spiegel@gnu.org> | 7 | ;; Maintainer: Andre Spiegel <spiegel@gnu.org> |
| 8 | ;; Keywords: tools | 8 | ;; Keywords: tools |
| 9 | 9 | ||
| 10 | ;; $Id: vc.el,v 1.139 2007/10/10 13:14:41 esr Exp $ | ||
| 11 | |||
| 10 | ;; This file is part of GNU Emacs. | 12 | ;; This file is part of GNU Emacs. |
| 11 | 13 | ||
| 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | 14 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| @@ -360,17 +362,17 @@ | |||
| 360 | ;; default implementation runs rcs2log, which handles RCS- and | 362 | ;; default implementation runs rcs2log, which handles RCS- and |
| 361 | ;; CVS-style logs. | 363 | ;; CVS-style logs. |
| 362 | ;; | 364 | ;; |
| 363 | ;; * diff (file &optional rev1 rev2 buffer) | 365 | ;; * diff (files &optional rev1 rev2 buffer) |
| 364 | ;; | 366 | ;; |
| 365 | ;; Insert the diff for FILE into BUFFER, or the *vc-diff* buffer if | 367 | ;; Insert the diff for FILE into BUFFER, or the *vc-diff* buffer if |
| 366 | ;; BUFFER is nil. If REV1 and REV2 are non-nil, report differences | 368 | ;; BUFFER is nil. If REV1 and REV2 are non-nil, report differences |
| 367 | ;; from REV1 to REV2. If REV1 is nil, use the focus version (as | 369 | ;; from REV1 to REV2. If REV1 is nil, use the current focus |
| 368 | ;; found in the repository) as the older version; if REV2 is nil, | 370 | ;; version (as found in the repository) as the older version; if |
| 369 | ;; use the current working-copy contents as the newer version. This | 371 | ;; REV2 is nil, use the current working-copy contents as the newer |
| 370 | ;; function should pass the value of (vc-switches BACKEND 'diff) to | 372 | ;; version. This function should pass the value of (vc-switches |
| 371 | ;; the backend command. It should return a status of either 0 (no | 373 | ;; BACKEND 'diff) to the backend command. It should return a status |
| 372 | ;; differences found), or 1 (either non-empty diff or the diff is | 374 | ;; of either 0 (no differences found), or 1 (either non-empty diff |
| 373 | ;; run asynchronously). | 375 | ;; or the diff is run asynchronously). |
| 374 | ;; | 376 | ;; |
| 375 | ;; - revision-completion-table (file) | 377 | ;; - revision-completion-table (file) |
| 376 | ;; | 378 | ;; |
| @@ -835,7 +837,7 @@ and that its contents match what the master file says." | |||
| 835 | Backends that offer asynchronous diffs should respect this variable | 837 | Backends that offer asynchronous diffs should respect this variable |
| 836 | in their implementation of vc-BACKEND-diff.") | 838 | in their implementation of vc-BACKEND-diff.") |
| 837 | 839 | ||
| 838 | (defvar vc-log-file) | 840 | (defvar vc-log-fileset) |
| 839 | (defvar vc-log-version) | 841 | (defvar vc-log-version) |
| 840 | 842 | ||
| 841 | (defvar vc-dired-mode nil) | 843 | (defvar vc-dired-mode nil) |
| @@ -848,20 +850,21 @@ in their implementation of vc-BACKEND-diff.") | |||
| 848 | (interactive) | 850 | (interactive) |
| 849 | (fillarray vc-file-prop-obarray 0)) | 851 | (fillarray vc-file-prop-obarray 0)) |
| 850 | 852 | ||
| 851 | (defmacro with-vc-properties (file form settings) | 853 | (defmacro with-vc-properties (files form settings) |
| 852 | "Execute FORM, then maybe set per-file properties for FILE. | 854 | "Execute FORM, then maybe set per-file properties for FILES. |
| 853 | SETTINGS is an association list of property/value pairs. After | 855 | SETTINGS is an association list of property/value pairs. After |
| 854 | executing FORM, set those properties from SETTINGS that have not yet | 856 | executing FORM, set those properties from SETTINGS that have not yet |
| 855 | been updated to their corresponding values." | 857 | been updated to their corresponding values." |
| 856 | (declare (debug t)) | 858 | (declare (debug t)) |
| 857 | `(let ((vc-touched-properties (list t))) | 859 | `(let ((vc-touched-properties (list t))) |
| 858 | ,form | 860 | ,form |
| 859 | (mapcar (lambda (setting) | 861 | (dolist (file ,files) |
| 862 | (mapc (lambda (setting) | ||
| 860 | (let ((property (car setting))) | 863 | (let ((property (car setting))) |
| 861 | (unless (memq property vc-touched-properties) | 864 | (unless (memq property vc-touched-properties) |
| 862 | (put (intern ,file vc-file-prop-obarray) | 865 | (put (intern ,file vc-file-prop-obarray) |
| 863 | property (cdr setting))))) | 866 | property (cdr setting))))) |
| 864 | ,settings))) | 867 | ,settings)))) |
| 865 | 868 | ||
| 866 | ;; Two macros for elisp programming | 869 | ;; Two macros for elisp programming |
| 867 | 870 | ||
| @@ -885,7 +888,7 @@ somebody else, signal error." | |||
| 885 | (vc-checkout ,filevar t)))) | 888 | (vc-checkout ,filevar t)))) |
| 886 | (save-excursion | 889 | (save-excursion |
| 887 | ,@body) | 890 | ,@body) |
| 888 | (vc-checkin ,filevar nil ,comment)))) | 891 | (vc-checkin (list ,filevar) nil ,comment)))) |
| 889 | 892 | ||
| 890 | ;;;###autoload | 893 | ;;;###autoload |
| 891 | (defmacro edit-vc-file (file comment &rest body) | 894 | (defmacro edit-vc-file (file comment &rest body) |
| @@ -988,7 +991,7 @@ Else, add CODE to the process' sentinel." | |||
| 988 | (defvar vc-post-command-functions nil | 991 | (defvar vc-post-command-functions nil |
| 989 | "Hook run at the end of `vc-do-command'. | 992 | "Hook run at the end of `vc-do-command'. |
| 990 | Each function is called inside the buffer in which the command was run | 993 | Each function is called inside the buffer in which the command was run |
| 991 | and is passed 3 arguments: the COMMAND, the FILE and the FLAGS.") | 994 | and is passed 3 arguments: the COMMAND, the FILES and the FLAGS.") |
| 992 | 995 | ||
| 993 | (defvar w32-quote-process-args) | 996 | (defvar w32-quote-process-args) |
| 994 | 997 | ||
| @@ -1016,10 +1019,17 @@ that is inserted into the command line before the filename." | |||
| 1016 | (let* ((files | 1019 | (let* ((files |
| 1017 | (mapcar (lambda (f) (file-relative-name (expand-file-name f))) | 1020 | (mapcar (lambda (f) (file-relative-name (expand-file-name f))) |
| 1018 | (if (listp file-or-list) file-or-list (list file-or-list)))) | 1021 | (if (listp file-or-list) file-or-list (list file-or-list)))) |
| 1019 | (full-command | 1022 | (full-command |
| 1020 | (concat command " " (vc-delistify flags) " " (vc-delistify files)))) | 1023 | ;; What we're doing here is preparing a version of the command |
| 1021 | (if vc-command-messages | 1024 | ;; for display in a debug-progess message. If it's fewer than |
| 1022 | (message "Running %s..." full-command)) | 1025 | ;; 20 characters display the entire command (without trailing |
| 1026 | ;; newline). Otherwise display the first 20 followed by an ellipsis. | ||
| 1027 | (concat (if (string= (substring command -1) "\n") | ||
| 1028 | (substring command 0 -1) | ||
| 1029 | command) | ||
| 1030 | " " | ||
| 1031 | (vc-delistify (mapcar (lambda (s) (if (> (length s) 20) (concat (substring s 0 2) "...") s)) flags)) | ||
| 1032 | " " (vc-delistify files)))) | ||
| 1023 | (save-current-buffer | 1033 | (save-current-buffer |
| 1024 | (unless (or (eq buffer t) | 1034 | (unless (or (eq buffer t) |
| 1025 | (and (stringp buffer) | 1035 | (and (stringp buffer) |
| @@ -1048,13 +1058,16 @@ that is inserted into the command line before the filename." | |||
| 1048 | (let ((process-connection-type nil)) | 1058 | (let ((process-connection-type nil)) |
| 1049 | (apply 'start-process command (current-buffer) command | 1059 | (apply 'start-process command (current-buffer) command |
| 1050 | squeezed)))) | 1060 | squeezed)))) |
| 1051 | (unless (active-minibuffer-window) | 1061 | (if vc-command-messages |
| 1052 | (message "Running %s in the background..." full-command)) | 1062 | (message "Running %s in background..." full-command)) |
| 1053 | ;;(set-process-sentinel proc (lambda (p msg) (delete-process p))) | 1063 | ;;(set-process-sentinel proc (lambda (p msg) (delete-process p))) |
| 1054 | (set-process-filter proc 'vc-process-filter) | 1064 | (set-process-filter proc 'vc-process-filter) |
| 1055 | (vc-exec-after | 1065 | (vc-exec-after |
| 1056 | `(unless (active-minibuffer-window) | 1066 | `(if vc-command-messages |
| 1057 | (message "Running %s in the background... done" ',full-command)))) | 1067 | (message "Running %s in background... done" ',full-command)))) |
| 1068 | ;; Run synchrously | ||
| 1069 | (if vc-command-messages | ||
| 1070 | (message "Running %s in foreground..." full-command)) | ||
| 1058 | (let ((buffer-undo-list t)) | 1071 | (let ((buffer-undo-list t)) |
| 1059 | (setq status (apply 'process-file command nil t nil squeezed))) | 1072 | (setq status (apply 'process-file command nil t nil squeezed))) |
| 1060 | (when (and (not (eq t okstatus)) | 1073 | (when (and (not (eq t okstatus)) |
| @@ -1065,11 +1078,12 @@ that is inserted into the command line before the filename." | |||
| 1065 | (shrink-window-if-larger-than-buffer) | 1078 | (shrink-window-if-larger-than-buffer) |
| 1066 | (error "Running %s...FAILED (%s)" full-command | 1079 | (error "Running %s...FAILED (%s)" full-command |
| 1067 | (if (integerp status) (format "status %d" status) status)))) | 1080 | (if (integerp status) (format "status %d" status) status)))) |
| 1081 | ;; We're done | ||
| 1068 | (if vc-command-messages | 1082 | (if vc-command-messages |
| 1069 | (message "Running %s...OK" full-command))) | 1083 | (message "Running %s...OK = %d" full-command status))) |
| 1070 | (vc-exec-after | 1084 | (vc-exec-after |
| 1071 | `(run-hook-with-args 'vc-post-command-functions | 1085 | `(run-hook-with-args 'vc-post-command-functions |
| 1072 | ',command ',file-or-list ',flags)) | 1086 | ',command ',file-or-list ',flags)) |
| 1073 | status)))) | 1087 | status)))) |
| 1074 | 1088 | ||
| 1075 | (defun vc-position-context (posn) | 1089 | (defun vc-position-context (posn) |
| @@ -1186,6 +1200,8 @@ CONTEXT is that which `vc-buffer-context' returns." | |||
| 1186 | (let ((new-mark (vc-find-position-by-context mark-context))) | 1200 | (let ((new-mark (vc-find-position-by-context mark-context))) |
| 1187 | (if new-mark (set-mark new-mark)))))) | 1201 | (if new-mark (set-mark new-mark)))))) |
| 1188 | 1202 | ||
| 1203 | ;;; Code for deducing what fileset and backend to assume | ||
| 1204 | |||
| 1189 | (defun vc-responsible-backend (file &optional register) | 1205 | (defun vc-responsible-backend (file &optional register) |
| 1190 | "Return the name of a backend system that is responsible for FILE. | 1206 | "Return the name of a backend system that is responsible for FILE. |
| 1191 | The optional argument REGISTER means that a backend suitable for | 1207 | The optional argument REGISTER means that a backend suitable for |
| @@ -1234,6 +1250,50 @@ Only files already under version control are noticed." | |||
| 1234 | node (lambda (f) (if (vc-backend f) (push f flattened))))) | 1250 | node (lambda (f) (if (vc-backend f) (push f flattened))))) |
| 1235 | (nreverse flattened))) | 1251 | (nreverse flattened))) |
| 1236 | 1252 | ||
| 1253 | (defun vc-deduce-fileset (&optional allow-directory-wildcard) | ||
| 1254 | "Deduce a set of files and a backend to apply an operation to. | ||
| 1255 | |||
| 1256 | If we're in VC-dired-mode, the fileset is the list of marked | ||
| 1257 | files. Otherwise, if we're looking at a buffer visiting a | ||
| 1258 | version-controlled file. the fileset is a singleton containing | ||
| 1259 | the relative filename, throw an error. | ||
| 1260 | |||
| 1261 | If neither of these things is true, but allow-directory-wildcard is on, | ||
| 1262 | select all files under version control at and below the current | ||
| 1263 | directory. | ||
| 1264 | |||
| 1265 | Otherwise, throw an error. | ||
| 1266 | " | ||
| 1267 | (cond (vc-dired-mode | ||
| 1268 | (let ((regexp (dired-marker-regexp)) | ||
| 1269 | (marked (dired-map-over-marks (dired-get-filename) nil))) | ||
| 1270 | (unless marked | ||
| 1271 | (error "No files have been selected.")) | ||
| 1272 | ;; All members of the fileset must have the same backend | ||
| 1273 | (let ((firstbackend (vc-backend (car marked)))) | ||
| 1274 | (mapc (lambda (f) (unless (eq (vc-backend f) firstbackend) | ||
| 1275 | (error "All members of a fileset must be under the same version-control system."))) | ||
| 1276 | (cdr marked))) | ||
| 1277 | marked)) | ||
| 1278 | ((vc-backend buffer-file-name) | ||
| 1279 | (list buffer-file-name)) | ||
| 1280 | ((and vc-parent-buffer (buffer-file-name vc-parent-buffer)) | ||
| 1281 | (progn | ||
| 1282 | (set-buffer vc-parent-buffer) | ||
| 1283 | (vc-deduce-fileset))) | ||
| 1284 | ;; This is guarded by an enabling arg so users won't potentially | ||
| 1285 | ;; shoot themselves in the foot by modifying a fileset they can't | ||
| 1286 | ;; verify by eyeball. Allow it for nondestructive commands like | ||
| 1287 | ;; making diffs, or possibly for destructive ones that have | ||
| 1288 | ;; confirmation prompts. | ||
| 1289 | (allow-directory-wildcard | ||
| 1290 | (progn | ||
| 1291 | (setq marked (list default-directory)) | ||
| 1292 | (message "All version-controlled files below %s selected." | ||
| 1293 | default-directory) | ||
| 1294 | (list default-directory))) | ||
| 1295 | (t (error "No fileset is available here.")))) | ||
| 1296 | |||
| 1237 | (defun vc-ensure-vc-buffer () | 1297 | (defun vc-ensure-vc-buffer () |
| 1238 | "Make sure that the current buffer visits a version-controlled file." | 1298 | "Make sure that the current buffer visits a version-controlled file." |
| 1239 | (if vc-dired-mode | 1299 | (if vc-dired-mode |
| @@ -1287,192 +1347,170 @@ NOT-URGENT means it is ok to continue if the user says not to save." | |||
| 1287 | 1347 | ||
| 1288 | ;;;###autoload | 1348 | ;;;###autoload |
| 1289 | (defun vc-next-action (verbose) | 1349 | (defun vc-next-action (verbose) |
| 1290 | "Do the next logical version control operation on the current file. | 1350 | "Do the next logical version control operation on the current fileset. |
| 1291 | 1351 | This requires that all files in the fileset be in the same state. | |
| 1292 | If you call this from within a VC dired buffer with no files marked, | ||
| 1293 | it will operate on the file in the current line. | ||
| 1294 | 1352 | ||
| 1295 | If you call this from within a VC dired buffer, and one or more | 1353 | For locking systems: |
| 1296 | files are marked, it will accept a log message and then operate on | 1354 | If every file is not already registered, this registers each for version |
| 1297 | each one. The log message will be used as a comment for any register | ||
| 1298 | or checkin operations, but ignored when doing checkouts. Attempted | ||
| 1299 | lock steals will raise an error. | ||
| 1300 | |||
| 1301 | A prefix argument lets you specify the version number to use. | ||
| 1302 | |||
| 1303 | For RCS and SCCS files: | ||
| 1304 | If the file is not already registered, this registers it for version | ||
| 1305 | control. | 1355 | control. |
| 1306 | If the file is registered and not locked by anyone, this checks out | 1356 | If every file is registered and not locked by anyone, this checks out |
| 1307 | a writable and locked file ready for editing. | 1357 | a writable and locked file of each ready for editing. |
| 1308 | If the file is checked out and locked by the calling user, this | 1358 | If every file is checked out and locked by the calling user, this |
| 1309 | first checks to see if the file has changed since checkout. If not, | 1359 | first checks to see if each file has changed since checkout. If not, |
| 1310 | it performs a revert. | 1360 | it performs a revert on that file. |
| 1311 | If the file has been changed, this pops up a buffer for entry | 1361 | If every file has been changed, this pops up a buffer for entry |
| 1312 | of a log message; when the message has been entered, it checks in the | 1362 | of a log message; when the message has been entered, it checks in the |
| 1313 | resulting changes along with the log message as change commentary. If | 1363 | resulting changes along with the log message as change commentary. If |
| 1314 | the variable `vc-keep-workfiles' is non-nil (which is its default), a | 1364 | the variable `vc-keep-workfiles' is non-nil (which is its default), a |
| 1315 | read-only copy of the changed file is left in place afterwards. | 1365 | read-only copy of each changed file is left in place afterwards. |
| 1316 | If the file is registered and locked by someone else, you are given | 1366 | If the affected file is registered and locked by someone else, you are |
| 1317 | the option to steal the lock. | 1367 | given the option to steal the lock(s). |
| 1318 | 1368 | ||
| 1319 | For CVS files: | 1369 | For merging systems: |
| 1320 | If the file is not already registered, this registers it for version | 1370 | If every file is not already registered, this registers each one for version |
| 1321 | control. This does a \"cvs add\", but no \"cvs commit\". | 1371 | control. This does an add, but not a commit. |
| 1322 | If the file is added but not committed, it is committed. | 1372 | If every file is added but not committed, each one is committed. |
| 1323 | If your working file is changed, but the repository file is | 1373 | If every working file is changed, but the corresponding repository file is |
| 1324 | unchanged, this pops up a buffer for entry of a log message; when the | 1374 | unchanged, this pops up a buffer for entry of a log message; when the |
| 1325 | message has been entered, it checks in the resulting changes along | 1375 | message has been entered, it checks in the resulting changes along |
| 1326 | with the logmessage as change commentary. A writable file is retained. | 1376 | with the logmessage as change commentary. A writable file is retained. |
| 1327 | If the repository file is changed, you are asked if you want to | 1377 | If the repository file is changed, you are asked if you want to |
| 1328 | merge in the changes into your working copy." | 1378 | merge in the changes into your working copy." |
| 1329 | (interactive "P") | 1379 | (interactive "P") |
| 1330 | (catch 'nogo | 1380 | (let* ((files (vc-deduce-fileset)) |
| 1331 | (if vc-dired-mode | 1381 | (backend (vc-backend (car files))) |
| 1332 | (let ((files (dired-get-marked-files))) | 1382 | (state (vc-state (car files))) |
| 1333 | (set (make-local-variable 'vc-dired-window-configuration) | 1383 | (model (vc-checkout-model (car files))) |
| 1334 | (current-window-configuration)) | 1384 | version) |
| 1335 | (if (string= "" | 1385 | ;; Verify that the fileset is homogenous |
| 1336 | (mapconcat | 1386 | (dolist (file (cdr files)) |
| 1337 | (lambda (f) | 1387 | (if (not (eq (vc-state file) state)) |
| 1338 | (if (not (vc-up-to-date-p f)) "@" "")) | 1388 | (error "Fileset is in a mixed-up state")) |
| 1339 | files "")) | 1389 | (if (not (eq (vc-checkout-model file) model)) |
| 1340 | (vc-next-action-dired nil nil "dummy") | 1390 | (error "Fileset has mixed checkout models"))) |
| 1341 | (vc-start-entry nil nil nil nil | 1391 | ;; Check for buffers in the fileset not matching the on-disk contents. |
| 1342 | "Enter a change comment for the marked files." | 1392 | (dolist (file files) |
| 1343 | 'vc-next-action-dired)) | 1393 | (let ((visited (get-file-buffer file))) |
| 1344 | (throw 'nogo nil))) | 1394 | (when visited |
| 1345 | (while vc-parent-buffer | 1395 | (if vc-dired-mode |
| 1346 | (pop-to-buffer vc-parent-buffer)) | 1396 | (switch-to-buffer-other-window visited) |
| 1347 | (if buffer-file-name | 1397 | (set-buffer visited)) |
| 1348 | (vc-next-action-on-file buffer-file-name verbose) | 1398 | ;; Check relation of buffer and file, and make sure |
| 1349 | (error "Buffer %s is not associated with a file" (buffer-name))))) | 1399 | ;; user knows what he's doing. First, finding the file |
| 1350 | 1400 | ;; will check whether the file on disk is newer. | |
| 1351 | ;; These functions help the vc-next-action entry point | 1401 | ;; Ignore buffer-read-only during this test, and |
| 1352 | 1402 | ;; preserve find-file-literally. | |
| 1353 | (defun vc-next-action-on-file (file verbose &optional comment) | 1403 | (let ((buffer-read-only (not (file-writable-p file)))) |
| 1354 | "Do The Right Thing for a given FILE under version control. | 1404 | (find-file-noselect file nil find-file-literally)) |
| 1355 | If COMMENT is specified, it will be used as an admin or checkin comment. | 1405 | (if (not (verify-visited-file-modtime (current-buffer))) |
| 1356 | If VERBOSE is non-nil, query the user rather than using default parameters." | 1406 | (if (yes-or-no-p (format "Replace %s on disk with buffer contents? " file)) |
| 1357 | (let ((visited (get-file-buffer file)) | 1407 | (write-file buffer-file-name) |
| 1358 | state version) | 1408 | (error "Aborted")) |
| 1359 | (when visited | 1409 | ;; Now, check if we have unsaved changes. |
| 1360 | (if vc-dired-mode | 1410 | (vc-buffer-sync t) |
| 1361 | (switch-to-buffer-other-window visited) | 1411 | (if (buffer-modified-p) |
| 1362 | (set-buffer visited)) | 1412 | (or (y-or-n-p (message "Use %s on disk, keeping modified buffer? " file)) |
| 1363 | ;; Check relation of buffer and file, and make sure | 1413 | (error "Aborted"))))))) |
| 1364 | ;; user knows what he's doing. First, finding the file | ||
| 1365 | ;; will check whether the file on disk is newer. | ||
| 1366 | ;; Ignore buffer-read-only during this test, and | ||
| 1367 | ;; preserve find-file-literally. | ||
| 1368 | (let ((buffer-read-only (not (file-writable-p file)))) | ||
| 1369 | (find-file-noselect file nil find-file-literally)) | ||
| 1370 | (if (not (verify-visited-file-modtime (current-buffer))) | ||
| 1371 | (if (yes-or-no-p "Replace file on disk with buffer contents? ") | ||
| 1372 | (write-file buffer-file-name) | ||
| 1373 | (error "Aborted")) | ||
| 1374 | ;; Now, check if we have unsaved changes. | ||
| 1375 | (vc-buffer-sync t) | ||
| 1376 | (if (buffer-modified-p) | ||
| 1377 | (or (y-or-n-p "Operate on disk file, keeping modified buffer? ") | ||
| 1378 | (error "Aborted"))))) | ||
| 1379 | |||
| 1380 | ;; Do the right thing | 1414 | ;; Do the right thing |
| 1381 | (if (not (vc-registered file)) | 1415 | (cond |
| 1382 | (vc-register verbose comment) | 1416 | ;; Files aren't registered |
| 1383 | (vc-recompute-state file) | 1417 | ((not state) |
| 1384 | (if visited (vc-mode-line file)) | 1418 | (mapc 'vc-register files)) |
| 1385 | (setq state (vc-state file)) | 1419 | ;; Files are up-to-date, or need a merge and user specified a version |
| 1420 | ((or (eq state 'up-to-date) (and verbose (eq state 'needs-patch))) | ||
| 1386 | (cond | 1421 | (cond |
| 1387 | ;; up-to-date | 1422 | (verbose |
| 1388 | ((or (eq state 'up-to-date) | 1423 | ;; go to a different version |
| 1389 | (and verbose (eq state 'needs-patch))) | 1424 | (setq version (read-string "Branch, version, or backend to move to: ")) |
| 1390 | (cond | 1425 | (let ((vsym (intern-soft (upcase version)))) |
| 1391 | (verbose | 1426 | (if (member vsym vc-handled-backends) |
| 1392 | ;; go to a different version | 1427 | (mapc (lambda (file) vc-transfer-file file vsym) files) |
| 1393 | (setq version | 1428 | (mapc (lambda (file) |
| 1394 | (read-string "Branch, version, or backend to move to: ")) | 1429 | (vc-checkout file (eq model 'implicit) version)))))) |
| 1395 | (let ((vsym (intern-soft (upcase version)))) | 1430 | ((not (eq model 'implicit)) |
| 1396 | (if (member vsym vc-handled-backends) | 1431 | ;; check the files out |
| 1397 | (vc-transfer-file file vsym) | 1432 | (mapc (lambda (file) (vc-checkout file t)) files)) |
| 1398 | (vc-checkout file (eq (vc-checkout-model file) 'implicit) | 1433 | (t |
| 1399 | version)))) | 1434 | ;; do nothing |
| 1400 | ((not (eq (vc-checkout-model file) 'implicit)) | 1435 | (message "Fileset is up-to-date")))) |
| 1401 | ;; check the file out | 1436 | ;; Files have local changes |
| 1402 | (vc-checkout file t)) | 1437 | ((eq state 'edited) |
| 1403 | (t | 1438 | (let ((ready-for-commit files)) |
| 1404 | ;; do nothing | 1439 | ;; If files are edited but read-only, give user a chance to correct |
| 1405 | (message "%s is up-to-date" file)))) | 1440 | (dolist (file files) |
| 1406 | 1441 | (if (not (file-writable-p file)) | |
| 1407 | ;; Abnormal: edited but read-only | 1442 | (progn |
| 1408 | ((and visited (eq state 'edited) | 1443 | ;; Make the file+buffer read-write. |
| 1409 | buffer-read-only (not (file-writable-p file))) | 1444 | (unless (y-or-no-p (format "%s is edited but read-only; make it writable and continue?" file)) |
| 1410 | ;; Make the file+buffer read-write. If the user really wanted to | 1445 | (error "Aborted")) |
| 1411 | ;; commit, he'll get a chance to do that next time around, anyway. | 1446 | (set-file-modes file (logior (file-modes file) 128)) |
| 1412 | (message "File is edited but read-only; making it writable") | 1447 | (let ((visited (get-file-buffer file))) |
| 1413 | (set-file-modes buffer-file-name | 1448 | (if visited |
| 1414 | (logior (file-modes buffer-file-name) 128)) | 1449 | (save-excursion |
| 1415 | (toggle-read-only -1)) | 1450 | (set-buffer visited) |
| 1416 | 1451 | (toggle-read-only -1))))))) | |
| 1417 | ;; edited | 1452 | ;; Allow user to revert files with no changes |
| 1418 | ((eq state 'edited) | 1453 | (save-excursion |
| 1419 | (cond | 1454 | (let ((revertlist '())) |
| 1420 | ;; For files with locking, if the file does not contain | 1455 | (dolist (file files) |
| 1421 | ;; any changes, just let go of the lock, i.e. revert. | 1456 | (let ((visited (get-file-buffer file))) |
| 1422 | ((and (not (eq (vc-checkout-model file) 'implicit)) | 1457 | ;; For files with locking, if the file does not contain |
| 1423 | (vc-workfile-unchanged-p file) | 1458 | ;; any changes, just let go of the lock, i.e. revert. |
| 1424 | ;; If buffer is modified, that means the user just | 1459 | (if (and (not (eq model 'implicit)) |
| 1425 | ;; said no to saving it; in that case, don't revert, | 1460 | (vc-workfile-unchanged-p file) |
| 1426 | ;; because the user might intend to save after | 1461 | ;; If buffer is modified, that means the user just |
| 1427 | ;; finishing the log entry. | 1462 | ;; said no to saving it; in that case, don't revert, |
| 1428 | (not (and visited (buffer-modified-p)))) | 1463 | ;; because the user might intend to save after |
| 1429 | ;; DO NOT revert the file without asking the user! | 1464 | ;; finishing the log entry and committing. |
| 1430 | (if (not visited) (find-file-other-window file)) | 1465 | (not (and visited (buffer-modified-p)))) |
| 1431 | (if (yes-or-no-p "Revert to master version? ") | 1466 | (progn |
| 1432 | (vc-revert))) | 1467 | (vc-revert-file file) |
| 1433 | (t ;; normal action | 1468 | (delete file ready-for-commit))))))) |
| 1469 | ;; Remaining files need to be committed | ||
| 1470 | (if (not ready-for-commit) | ||
| 1471 | (message "No files remain to be committed") | ||
| 1434 | (if (not verbose) | 1472 | (if (not verbose) |
| 1435 | (vc-checkin file nil comment) | 1473 | (vc-checkin ready-for-commit) |
| 1436 | (setq version (read-string "New version or backend: ")) | 1474 | (progn |
| 1437 | (let ((vsym (intern (upcase version)))) | 1475 | (setq version (read-string "New version or backend: ")) |
| 1438 | (if (member vsym vc-handled-backends) | 1476 | (let ((vsym (intern (upcase version)))) |
| 1439 | (vc-transfer-file file vsym) | 1477 | (if (member vsym vc-handled-backends) |
| 1440 | (vc-checkin file version comment))))))) | 1478 | (vc-transfer-file file vsym) |
| 1441 | 1479 | (vc-checkin ready-for-commit version)))))))) | |
| 1442 | ;; locked by somebody else | 1480 | ;; locked by somebody else (locking VCSes only) |
| 1443 | ((stringp state) | 1481 | ((stringp state) |
| 1444 | (if comment | 1482 | (let ((version |
| 1445 | (error "Sorry, you can't steal the lock on %s this way" | 1483 | (if verbose |
| 1446 | (file-name-nondirectory file))) | 1484 | (read-string "Version to steal: ") |
| 1447 | (vc-steal-lock file | 1485 | (vc-workfile-version file)))) |
| 1448 | (if verbose (read-string "Version to steal: ") | 1486 | (mapc (lambda (file) (vc-steal-lock file version) state) files))) |
| 1449 | (vc-workfile-version file)) | 1487 | ;; needs-patch |
| 1450 | state)) | 1488 | ((eq state 'needs-patch) |
| 1451 | 1489 | (dolist (file files) | |
| 1452 | ;; needs-patch | ||
| 1453 | ((eq state 'needs-patch) | ||
| 1454 | (if (yes-or-no-p (format | 1490 | (if (yes-or-no-p (format |
| 1455 | "%s is not up-to-date. Get latest version? " | 1491 | "%s is not up-to-date. Get latest version? " |
| 1456 | (file-name-nondirectory file))) | 1492 | (file-name-nondirectory file))) |
| 1457 | (vc-checkout file (eq (vc-checkout-model file) 'implicit) t) | 1493 | (vc-checkout file (eq model 'implicit) t) |
| 1458 | (if (and (not (eq (vc-checkout-model file) 'implicit)) | 1494 | (if (and (not (eq model 'implicit)) |
| 1459 | (yes-or-no-p "Lock this version? ")) | 1495 | (yes-or-no-p "Lock this version? ")) |
| 1460 | (vc-checkout file t) | 1496 | (vc-checkout file t))))) |
| 1461 | (error "Aborted")))) | 1497 | ;; needs-merge |
| 1462 | 1498 | ((eq state 'needs-merge) | |
| 1463 | ;; needs-merge | 1499 | (dolist (file files) |
| 1464 | ((eq state 'needs-merge) | ||
| 1465 | (if (yes-or-no-p (format | 1500 | (if (yes-or-no-p (format |
| 1466 | "%s is not up-to-date. Merge in changes now? " | 1501 | "%s is not up-to-date. Merge in changes now? " |
| 1467 | (file-name-nondirectory file))) | 1502 | (file-name-nondirectory file))) |
| 1468 | (vc-maybe-resolve-conflicts file (vc-call merge-news file)) | 1503 | (vc-maybe-resolve-conflicts file (vc-call merge-news file))))) |
| 1469 | (error "Aborted"))) | ||
| 1470 | 1504 | ||
| 1471 | ;; unlocked-changes | 1505 | ;; unlocked-changes |
| 1472 | ((eq state 'unlocked-changes) | 1506 | ((eq state 'unlocked-changes) |
| 1473 | (if (not visited) (find-file-other-window file)) | 1507 | (dolist (file files) |
| 1508 | (if (not (equal buffer-file-name file)) | ||
| 1509 | (find-file-other-window file)) | ||
| 1474 | (if (save-window-excursion | 1510 | (if (save-window-excursion |
| 1475 | (vc-version-diff file (vc-workfile-version file) nil) | 1511 | (vc-diff-internal |
| 1512 | (vc-backend file) nil (list file) | ||
| 1513 | (vc-workfile-version file) nil) | ||
| 1476 | (goto-char (point-min)) | 1514 | (goto-char (point-min)) |
| 1477 | (let ((inhibit-read-only t)) | 1515 | (let ((inhibit-read-only t)) |
| 1478 | (insert | 1516 | (insert |
| @@ -1493,20 +1531,6 @@ If VERBOSE is non-nil, query the user rather than using default parameters." | |||
| 1493 | (vc-revert-buffer-internal t t) | 1531 | (vc-revert-buffer-internal t t) |
| 1494 | (vc-checkout file t)))))))) | 1532 | (vc-checkout file t)))))))) |
| 1495 | 1533 | ||
| 1496 | (defun vc-next-action-dired (file rev comment) | ||
| 1497 | "Call `vc-next-action-on-file' on all the marked files. | ||
| 1498 | Ignores FILE and REV, but passes on COMMENT." | ||
| 1499 | (let ((dired-buffer (current-buffer))) | ||
| 1500 | (dired-map-over-marks | ||
| 1501 | (let ((file (dired-get-filename))) | ||
| 1502 | (message "Processing %s..." file) | ||
| 1503 | (vc-next-action-on-file file nil comment) | ||
| 1504 | (set-buffer dired-buffer) | ||
| 1505 | (set-window-configuration vc-dired-window-configuration) | ||
| 1506 | (message "Processing %s...done" file)) | ||
| 1507 | nil t)) | ||
| 1508 | (dired-move-to-filename)) | ||
| 1509 | |||
| 1510 | (defun vc-create-repo (backend) | 1534 | (defun vc-create-repo (backend) |
| 1511 | "Create an empty repository in the current directory." | 1535 | "Create an empty repository in the current directory." |
| 1512 | (interactive | 1536 | (interactive |
| @@ -1546,7 +1570,7 @@ first backend that could register the file is used." | |||
| 1546 | (set-buffer-modified-p t)) | 1570 | (set-buffer-modified-p t)) |
| 1547 | (vc-buffer-sync) | 1571 | (vc-buffer-sync) |
| 1548 | 1572 | ||
| 1549 | (vc-start-entry buffer-file-name | 1573 | (vc-start-entry (list buffer-file-name) |
| 1550 | (if set-version | 1574 | (if set-version |
| 1551 | (read-string (format "Initial version level for %s: " | 1575 | (read-string (format "Initial version level for %s: " |
| 1552 | (buffer-name))) | 1576 | (buffer-name))) |
| @@ -1555,17 +1579,25 @@ first backend that could register the file is used." | |||
| 1555 | (or comment (not vc-initial-comment)) | 1579 | (or comment (not vc-initial-comment)) |
| 1556 | nil | 1580 | nil |
| 1557 | "Enter initial comment." | 1581 | "Enter initial comment." |
| 1558 | (lambda (file rev comment) | 1582 | (lambda (files rev comment) |
| 1559 | (message "Registering %s... " file) | 1583 | (dolist (file files) |
| 1560 | (let ((backend (vc-responsible-backend file t))) | 1584 | (message "Registering %s... " file) |
| 1561 | (vc-file-clearprops file) | 1585 | (let ((backend (vc-responsible-backend file t))) |
| 1562 | (vc-call-backend backend 'register (list file) rev comment) | 1586 | (vc-file-clearprops file) |
| 1563 | (vc-file-setprop file 'vc-backend backend) | 1587 | (vc-call-backend backend 'register (list file) rev comment) |
| 1564 | (unless vc-make-backup-files | 1588 | (vc-file-setprop file 'vc-backend backend) |
| 1565 | (make-local-variable 'backup-inhibited) | 1589 | (unless vc-make-backup-files |
| 1566 | (setq backup-inhibited t))) | 1590 | (make-local-variable 'backup-inhibited) |
| 1567 | (message "Registering %s... done" file)))) | 1591 | (setq backup-inhibited t))) |
| 1568 | 1592 | (message "Registering %s... done" file))))) | |
| 1593 | |||
| 1594 | (defun vc-register-with (backend) | ||
| 1595 | "Register the current file with a specified back end." | ||
| 1596 | (interactive "SBackend: ") | ||
| 1597 | (if (not (member backend vc-handled-backends)) | ||
| 1598 | (error "Unknown back end.")) | ||
| 1599 | (let ((vc-handled-backends (list backend))) | ||
| 1600 | (call-interactively 'vc-register))) | ||
| 1569 | 1601 | ||
| 1570 | (defun vc-resynch-window (file &optional keep noquery) | 1602 | (defun vc-resynch-window (file &optional keep noquery) |
| 1571 | "If FILE is in the current buffer, either revert or unvisit it. | 1603 | "If FILE is in the current buffer, either revert or unvisit it. |
| @@ -1602,8 +1634,8 @@ rather than user editing!" | |||
| 1602 | (vc-resynch-window file keep noquery))))) | 1634 | (vc-resynch-window file keep noquery))))) |
| 1603 | (vc-dired-resynch-file file)) | 1635 | (vc-dired-resynch-file file)) |
| 1604 | 1636 | ||
| 1605 | (defun vc-start-entry (file rev comment initial-contents msg action &optional after-hook) | 1637 | (defun vc-start-entry (files rev comment initial-contents msg action &optional after-hook) |
| 1606 | "Accept a comment for an operation on FILE revision REV. | 1638 | "Accept a comment for an operation on FILES revision REV. |
| 1607 | If COMMENT is nil, pop up a VC-log buffer, emit MSG, and set the | 1639 | If COMMENT is nil, pop up a VC-log buffer, emit MSG, and set the |
| 1608 | action on close to ACTION. If COMMENT is a string and | 1640 | action on close to ACTION. If COMMENT is a string and |
| 1609 | INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial | 1641 | INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial |
| @@ -1613,9 +1645,12 @@ entered COMMENT. If COMMENT is t, also do action immediately with an | |||
| 1613 | empty comment. Remember the file's buffer in `vc-parent-buffer' | 1645 | empty comment. Remember the file's buffer in `vc-parent-buffer' |
| 1614 | \(current one if no file). AFTER-HOOK specifies the local value | 1646 | \(current one if no file). AFTER-HOOK specifies the local value |
| 1615 | for vc-log-operation-hook." | 1647 | for vc-log-operation-hook." |
| 1616 | (let ((parent (or (and file (get-file-buffer file)) (current-buffer)))) | 1648 | (let ((parent |
| 1649 | (if (and files (equal (length files) 1)) | ||
| 1650 | (get-file-buffer (car files)) | ||
| 1651 | (current-buffer)))) | ||
| 1617 | (if vc-before-checkin-hook | 1652 | (if vc-before-checkin-hook |
| 1618 | (if file | 1653 | (if files |
| 1619 | (with-current-buffer parent | 1654 | (with-current-buffer parent |
| 1620 | (run-hooks 'vc-before-checkin-hook)) | 1655 | (run-hooks 'vc-before-checkin-hook)) |
| 1621 | (run-hooks 'vc-before-checkin-hook))) | 1656 | (run-hooks 'vc-before-checkin-hook))) |
| @@ -1625,8 +1660,8 @@ for vc-log-operation-hook." | |||
| 1625 | (set (make-local-variable 'vc-parent-buffer) parent) | 1660 | (set (make-local-variable 'vc-parent-buffer) parent) |
| 1626 | (set (make-local-variable 'vc-parent-buffer-name) | 1661 | (set (make-local-variable 'vc-parent-buffer-name) |
| 1627 | (concat " from " (buffer-name vc-parent-buffer))) | 1662 | (concat " from " (buffer-name vc-parent-buffer))) |
| 1628 | (if file (vc-mode-line file)) | 1663 | ;;(if file (vc-mode-line file)) |
| 1629 | (vc-log-edit file) | 1664 | (vc-log-edit files) |
| 1630 | (make-local-variable 'vc-log-after-operation-hook) | 1665 | (make-local-variable 'vc-log-after-operation-hook) |
| 1631 | (if after-hook | 1666 | (if after-hook |
| 1632 | (setq vc-log-after-operation-hook after-hook)) | 1667 | (setq vc-log-after-operation-hook after-hook)) |
| @@ -1651,7 +1686,7 @@ After check-out, runs the normal hook `vc-checkout-hook'." | |||
| 1651 | (vc-up-to-date-p file) | 1686 | (vc-up-to-date-p file) |
| 1652 | (vc-make-version-backup file)) | 1687 | (vc-make-version-backup file)) |
| 1653 | (with-vc-properties | 1688 | (with-vc-properties |
| 1654 | file | 1689 | (list file) |
| 1655 | (condition-case err | 1690 | (condition-case err |
| 1656 | (vc-call checkout file writable rev) | 1691 | (vc-call checkout file writable rev) |
| 1657 | (file-error | 1692 | (file-error |
| @@ -1681,7 +1716,7 @@ After check-out, runs the normal hook `vc-checkout-hook'." | |||
| 1681 | (error "Steal canceled")) | 1716 | (error "Steal canceled")) |
| 1682 | (message "Stealing lock on %s..." file) | 1717 | (message "Stealing lock on %s..." file) |
| 1683 | (with-vc-properties | 1718 | (with-vc-properties |
| 1684 | file | 1719 | (list file) |
| 1685 | (vc-call steal-lock file rev) | 1720 | (vc-call steal-lock file rev) |
| 1686 | `((vc-state . edited))) | 1721 | `((vc-state . edited))) |
| 1687 | (vc-resynch-buffer file t t) | 1722 | (vc-resynch-buffer file t t) |
| @@ -1697,8 +1732,8 @@ After check-out, runs the normal hook `vc-checkout-hook'." | |||
| 1697 | ".\n") | 1732 | ".\n") |
| 1698 | (message "Please explain why you stole the lock. Type C-c C-c when done."))) | 1733 | (message "Please explain why you stole the lock. Type C-c C-c when done."))) |
| 1699 | 1734 | ||
| 1700 | (defun vc-checkin (file &optional rev comment initial-contents) | 1735 | (defun vc-checkin (files &optional rev comment initial-contents) |
| 1701 | "Check in FILE. | 1736 | "Check in FILES. |
| 1702 | The optional argument REV may be a string specifying the new version | 1737 | The optional argument REV may be a string specifying the new version |
| 1703 | level (if nil increment the current level). COMMENT is a comment | 1738 | level (if nil increment the current level). COMMENT is a comment |
| 1704 | string; if omitted, a buffer is popped up to accept a comment. If | 1739 | string; if omitted, a buffer is popped up to accept a comment. If |
| @@ -1710,29 +1745,27 @@ that the version control system supports this mode of operation. | |||
| 1710 | 1745 | ||
| 1711 | Runs the normal hook `vc-checkin-hook'." | 1746 | Runs the normal hook `vc-checkin-hook'." |
| 1712 | (vc-start-entry | 1747 | (vc-start-entry |
| 1713 | file rev comment initial-contents | 1748 | files rev comment initial-contents |
| 1714 | "Enter a change comment." | 1749 | "Enter a change comment." |
| 1715 | (lambda (file rev comment) | 1750 | (lambda (files rev comment) |
| 1716 | (message "Checking in %s..." file) | 1751 | (message "Checking in %s..." (vc-delistify files)) |
| 1717 | ;; "This log message intentionally left almost blank". | 1752 | ;; "This log message intentionally left almost blank". |
| 1718 | ;; RCS 5.7 gripes about white-space-only comments too. | 1753 | ;; RCS 5.7 gripes about white-space-only comments too. |
| 1719 | (or (and comment (string-match "[^\t\n ]" comment)) | 1754 | (or (and comment (string-match "[^\t\n ]" comment)) |
| 1720 | (setq comment "*** empty log message ***")) | 1755 | (setq comment "*** empty log message ***")) |
| 1721 | (with-vc-properties | 1756 | (with-vc-properties |
| 1722 | file | 1757 | files |
| 1723 | ;; Change buffers to get local value of vc-checkin-switches. | 1758 | ;; We used to change buffers to get local value of vc-checkin-switches, |
| 1724 | (with-current-buffer (or (get-file-buffer file) (current-buffer)) | 1759 | ;; but 'the' local buffer is not a well-defined concept for filesets. |
| 1725 | (progn | 1760 | (progn |
| 1726 | (vc-call checkin (list file) rev comment) | 1761 | (vc-call checkin files rev comment) |
| 1727 | (vc-delete-automatic-version-backups file))) | 1762 | (mapc 'vc-delete-automatic-version-backups files)) |
| 1728 | `((vc-state . up-to-date) | 1763 | `((vc-state . up-to-date) |
| 1729 | (vc-checkout-time . ,(nth 5 (file-attributes file))) | 1764 | (vc-checkout-time . ,(nth 5 (file-attributes file))) |
| 1730 | (vc-workfile-version . nil))) | 1765 | (vc-workfile-version . nil))) |
| 1731 | (message "Checking in %s...done" file)) | 1766 | (message "Checking in %s...done" (vc-delistify files))) |
| 1732 | 'vc-checkin-hook)) | 1767 | 'vc-checkin-hook)) |
| 1733 | 1768 | ||
| 1734 | ;; Code for access to the comment ring | ||
| 1735 | |||
| 1736 | (defun vc-finish-logentry (&optional nocomment) | 1769 | (defun vc-finish-logentry (&optional nocomment) |
| 1737 | "Complete the operation implied by the current log entry. | 1770 | "Complete the operation implied by the current log entry. |
| 1738 | Use the contents of the current buffer as a check-in or registration | 1771 | Use the contents of the current buffer as a check-in or registration |
| @@ -1742,7 +1775,7 @@ the buffer contents as a comment." | |||
| 1742 | ;; Check and record the comment, if any. | 1775 | ;; Check and record the comment, if any. |
| 1743 | (unless nocomment | 1776 | (unless nocomment |
| 1744 | ;; Comment too long? | 1777 | ;; Comment too long? |
| 1745 | (vc-call-backend (or (and vc-log-file (vc-backend vc-log-file)) | 1778 | (vc-call-backend (or (and vc-log-fileset (vc-backend (car vc-log-fileset))) |
| 1746 | (vc-responsible-backend default-directory)) | 1779 | (vc-responsible-backend default-directory)) |
| 1747 | 'logentry-check) | 1780 | 'logentry-check) |
| 1748 | (run-hooks 'vc-logentry-check-hook)) | 1781 | (run-hooks 'vc-logentry-check-hook)) |
| @@ -1754,7 +1787,7 @@ the buffer contents as a comment." | |||
| 1754 | (error "No log operation is pending")) | 1787 | (error "No log operation is pending")) |
| 1755 | ;; save the parameters held in buffer-local variables | 1788 | ;; save the parameters held in buffer-local variables |
| 1756 | (let ((log-operation vc-log-operation) | 1789 | (let ((log-operation vc-log-operation) |
| 1757 | (log-file vc-log-file) | 1790 | (log-fileset vc-log-fileset) |
| 1758 | (log-version vc-log-version) | 1791 | (log-version vc-log-version) |
| 1759 | (log-entry (buffer-string)) | 1792 | (log-entry (buffer-string)) |
| 1760 | (after-hook vc-log-after-operation-hook) | 1793 | (after-hook vc-log-after-operation-hook) |
| @@ -1763,7 +1796,7 @@ the buffer contents as a comment." | |||
| 1763 | ;; OK, do it to it | 1796 | ;; OK, do it to it |
| 1764 | (save-excursion | 1797 | (save-excursion |
| 1765 | (funcall log-operation | 1798 | (funcall log-operation |
| 1766 | log-file | 1799 | log-fileset |
| 1767 | log-version | 1800 | log-version |
| 1768 | log-entry)) | 1801 | log-entry)) |
| 1769 | ;; Remove checkin window (after the checkin so that if that fails | 1802 | ;; Remove checkin window (after the checkin so that if that fails |
| @@ -1777,8 +1810,10 @@ the buffer contents as a comment." | |||
| 1777 | (bury-buffer) | 1810 | (bury-buffer) |
| 1778 | (pop-to-buffer tmp-vc-parent-buffer)))) | 1811 | (pop-to-buffer tmp-vc-parent-buffer)))) |
| 1779 | ;; Now make sure we see the expanded headers | 1812 | ;; Now make sure we see the expanded headers |
| 1780 | (if log-file | 1813 | (if log-fileset |
| 1781 | (vc-resynch-buffer log-file vc-keep-workfiles t)) | 1814 | (mapc |
| 1815 | (lambda (file) (vc-resynch-buffer file vc-keep-workfiles t)) | ||
| 1816 | log-fileset)) | ||
| 1782 | (if vc-dired-mode | 1817 | (if vc-dired-mode |
| 1783 | (dired-move-to-filename)) | 1818 | (dired-move-to-filename)) |
| 1784 | (run-hooks after-hook 'vc-finish-logentry-hook))) | 1819 | (run-hooks after-hook 'vc-finish-logentry-hook))) |
| @@ -1838,101 +1873,96 @@ The meaning of REV1 and REV2 is the same as for `vc-version-diff'." | |||
| 1838 | (defmacro vc-diff-switches-list (backend) `(vc-switches ',backend 'diff)) | 1873 | (defmacro vc-diff-switches-list (backend) `(vc-switches ',backend 'diff)) |
| 1839 | (make-obsolete 'vc-diff-switches-list 'vc-switches "22.1") | 1874 | (make-obsolete 'vc-diff-switches-list 'vc-switches "22.1") |
| 1840 | 1875 | ||
| 1841 | (defun vc-diff-internal (file rev1 rev2) | 1876 | (defun vc-diff-sentinel (verbose rev1-name rev2-name) |
| 1842 | "Run diff to compare FILE's revisions REV1 and REV2. | 1877 | ;; Did changes get generated into the buffer? |
| 1843 | Diff output goes to the *vc-diff* buffer. The exit status of the diff | 1878 | (if (not (zerop (buffer-size (get-buffer "*vc-diff*")))) |
| 1844 | command is returned. | 1879 | (progn |
| 1845 | 1880 | (pop-to-buffer "*vc-diff*") | |
| 1846 | This function takes care to set up a proper coding system for diff output. | 1881 | ;; Gnus-5.8.5 sets up an autoload for diff-mode, even if it's |
| 1847 | If both revisions are available as local files, then it also does not | 1882 | ;; not available. Work around that. |
| 1848 | actually call the backend, but performs a local diff." | 1883 | (if (require 'diff-mode nil t) (diff-mode)) |
| 1849 | (if (or (not rev1) (string-equal rev1 "")) | 1884 | (goto-char (point-max)) |
| 1850 | (setq rev1 (vc-workfile-version file))) | 1885 | (if verbose |
| 1851 | (if (string-equal rev2 "") | 1886 | (insert (format "\n\nDiffs between %s and %s end here." rev1-name rev2-name))) |
| 1852 | (setq rev2 nil)) | 1887 | (goto-char (point-min)) |
| 1853 | (let ((file-rev1 (vc-version-backup-file file rev1)) | 1888 | (if verbose |
| 1854 | (file-rev2 (if (not rev2) | 1889 | (insert (format "Diffs between %s and %s:\n\n" rev1-name rev2-name))) |
| 1855 | file | 1890 | (shrink-window-if-larger-than-buffer) |
| 1856 | (vc-version-backup-file file rev2))) | 1891 | t) |
| 1857 | (coding-system-for-read (vc-coding-system-for-diff file))) | 1892 | (progn |
| 1858 | (if (and file-rev1 file-rev2) | 1893 | (message "No changes between %s and %s" rev1-name rev2-name) |
| 1859 | (let ((status | 1894 | nil))) |
| 1860 | (if (eq vc-diff-knows-L 'no) | 1895 | |
| 1861 | (apply 'vc-do-command "*vc-diff*" 1 "diff" nil | 1896 | (defun vc-diff-internal (backend async files rev1 rev2 &optional verbose) |
| 1862 | (append (vc-switches nil 'diff) | 1897 | "Report diffs between two revisions of a fileset. |
| 1863 | (list (file-relative-name file-rev1) | 1898 | Diff output goes to the *vc-diff* buffer. The function |
| 1864 | (file-relative-name file-rev2)))) | 1899 | returns t if the buffer had changes, nil otherwise." |
| 1865 | (apply 'vc-do-command "*vc-diff*" 2 "diff" nil | 1900 | (let* ((filenames (vc-delistify files)) |
| 1866 | (append (vc-switches nil 'diff) | 1901 | (rev1-name (or rev1 "focus version")) |
| 1867 | ;; Provide explicit labels like RCS or | 1902 | (rev2-name (or rev2 "workfile")) |
| 1868 | ;; CVS would do so diff-mode refers to | 1903 | ;; Set coding system based on the first file. It's a kluge, |
| 1869 | ;; `file' rather than to `file-rev1' | 1904 | ;; but the only way to set it for each file included would |
| 1870 | ;; when trying to find/apply/undo | 1905 | ;; be to call the back end separately for each file. |
| 1871 | ;; hunks. | 1906 | (coding-system-for-read |
| 1872 | (list "-L" (vc-diff-label file file-rev1 rev1) | 1907 | (if files (vc-coding-system-for-diff (car files)) 'undecided))) |
| 1873 | "-L" (vc-diff-label file file-rev2 rev2) | 1908 | (vc-setup-buffer "*vc-diff*") |
| 1874 | (file-relative-name file-rev1) | 1909 | (message "Finding changes in..." filenames) |
| 1875 | (file-relative-name file-rev2))))))) | 1910 | ;; Many backends don't handle well the case of a file that has been |
| 1876 | (if (eq status 2) | 1911 | ;; added but not yet committed to the repo (notably CVS and Subversion). |
| 1877 | (if (not vc-diff-knows-L) | 1912 | ;; Do that work here so the backends don't have to futz with it. |
| 1878 | (setq vc-diff-knows-L 'no | 1913 | (let ((filtered '())) |
| 1879 | status (apply 'vc-do-command "*vc-diff*" 1 "diff" nil | 1914 | (dolist (file files) |
| 1880 | (append | 1915 | (cond ((and (not (file-directory-p file)) (string= (vc-workfile-version file) "0")) |
| 1881 | (vc-switches nil 'diff) | 1916 | (progn |
| 1882 | (list (file-relative-name file-rev1) | 1917 | ;; This file is added but not yet committed; |
| 1883 | (file-relative-name file-rev2))))) | 1918 | ;; there is no master file to diff against. |
| 1884 | (error "diff failed")) | 1919 | (if (or rev1 rev2) |
| 1885 | (if (not vc-diff-knows-L) (setq vc-diff-knows-L 'yes))) | 1920 | (error "No revisions of %s exist" file) |
| 1886 | status) | 1921 | ;; We regard this as "changed". |
| 1887 | (vc-call diff (list file) rev1 rev2 "*vc-diff*")))) | 1922 | ;; Diff it against /dev/null. |
| 1923 | (apply 'vc-do-command "*vc-diff*" | ||
| 1924 | 1 "diff" file | ||
| 1925 | (append (vc-switches nil 'diff) '("/dev/null")))))) | ||
| 1926 | (t | ||
| 1927 | (add-to-list 'filtered file t)))) | ||
| 1928 | (let ((vc-disable-async-diff (not async))) | ||
| 1929 | (vc-call-backend backend 'diff filtered rev1 rev2 "*vc-diff*"))) | ||
| 1930 | (set-buffer "*vc-diff*") | ||
| 1931 | ;; This odd-looking code is because in the non-async case we | ||
| 1932 | ;; actually want to pass the return value from vc-diff-sentinel | ||
| 1933 | ;; back to the caller. | ||
| 1934 | (if async | ||
| 1935 | (vc-exec-after `(vc-diff-sentinel ,verbose ,rev1-name ,rev2-name)) | ||
| 1936 | (vc-diff-sentinel verbose rev1-name rev2-name)))) | ||
| 1888 | 1937 | ||
| 1889 | ;;;###autoload | 1938 | ;;;###autoload |
| 1890 | (defun vc-diff (historic &optional not-urgent) | 1939 | (defun vc-history-diff (backend files rev1 rev2) |
| 1891 | "Display diffs between file versions. | 1940 | "Report diffs between revisions of the fileset in the repository history." |
| 1892 | Normally this compares the current file and buffer with the most | ||
| 1893 | recent checked in version of that file. This uses no arguments. With | ||
| 1894 | a prefix argument HISTORIC, it reads the file name to use and two | ||
| 1895 | version designators specifying which versions to compare. The | ||
| 1896 | optional argument NOT-URGENT non-nil means it is ok to say no to | ||
| 1897 | saving the buffer." | ||
| 1898 | (interactive (list current-prefix-arg t)) | ||
| 1899 | (if historic | ||
| 1900 | (call-interactively 'vc-version-diff) | ||
| 1901 | (vc-ensure-vc-buffer) | ||
| 1902 | (let ((file buffer-file-name)) | ||
| 1903 | (vc-buffer-sync not-urgent) | ||
| 1904 | (if (vc-workfile-unchanged-p buffer-file-name) | ||
| 1905 | (message "No changes to %s since latest version" file) | ||
| 1906 | (vc-version-diff file nil nil))))) | ||
| 1907 | |||
| 1908 | (defun vc-version-diff (file rev1 rev2) | ||
| 1909 | "List the differences between FILE's versions REV1 and REV2. | ||
| 1910 | If REV1 is empty or nil it means to use the focus version; | ||
| 1911 | REV2 empty or nil means the working-copy contents. FILE may also be | ||
| 1912 | a directory, in that case, generate diffs between the correponding | ||
| 1913 | versions of all registered files in or below it." | ||
| 1914 | (interactive | 1941 | (interactive |
| 1915 | (let* ((file (expand-file-name | 1942 | (let* ((files (vc-deduce-fileset t)) |
| 1916 | (read-file-name (if buffer-file-name | 1943 | (first (car files)) |
| 1917 | "File or dir to diff (default visited file): " | 1944 | (backend (vc-backend first)) |
| 1918 | "File or dir to diff: ") | 1945 | (completion-table |
| 1919 | default-directory buffer-file-name t))) | 1946 | (vc-call-backend backend 'revision-completion-table first)) |
| 1920 | (rev1-default nil) (rev2-default nil) | 1947 | (rev1-default nil) |
| 1921 | (completion-table (vc-call revision-completion-table file))) | 1948 | (rev2-default nil)) |
| 1922 | ;; compute default versions based on the file state | ||
| 1923 | (cond | 1949 | (cond |
| 1950 | ;; someday we may be able to do version completion on non-singleton | ||
| 1951 | ;; filesets, but not yet. | ||
| 1952 | ((/= (length files) 1) | ||
| 1953 | nil) | ||
| 1924 | ;; if it's a directory, don't supply any version default | 1954 | ;; if it's a directory, don't supply any version default |
| 1925 | ((file-directory-p file) | 1955 | ((file-directory-p first) |
| 1926 | nil) | 1956 | nil) |
| 1927 | ;; if the file is not up-to-date, use current version as older version | 1957 | ;; if the file is not up-to-date, use current version as older version |
| 1928 | ((not (vc-up-to-date-p file)) | 1958 | ((not (vc-up-to-date-p first)) |
| 1929 | (setq rev1-default (vc-workfile-version file))) | 1959 | (setq rev1-default (vc-workfile-version first))) |
| 1930 | ;; if the file is not locked, use last and previous version as default | 1960 | ;; if the file is not locked, use last and previous version as default |
| 1931 | (t | 1961 | (t |
| 1932 | (setq rev1-default (vc-call previous-version file | 1962 | (setq rev1-default (vc-call previous-version first |
| 1933 | (vc-workfile-version file))) | 1963 | (vc-workfile-version first))) |
| 1934 | (if (string= rev1-default "") (setq rev1-default nil)) | 1964 | (if (string= rev1-default "") (setq rev1-default nil)) |
| 1935 | (setq rev2-default (vc-workfile-version file)))) | 1965 | (setq rev2-default (vc-workfile-version first)))) |
| 1936 | ;; construct argument list | 1966 | ;; construct argument list |
| 1937 | (let* ((rev1-prompt (if rev1-default | 1967 | (let* ((rev1-prompt (if rev1-default |
| 1938 | (concat "Older version (default " | 1968 | (concat "Older version (default " |
| @@ -1942,60 +1972,37 @@ versions of all registered files in or below it." | |||
| 1942 | (or rev2-default "current source") "): ")) | 1972 | (or rev2-default "current source") "): ")) |
| 1943 | (rev1 (if completion-table | 1973 | (rev1 (if completion-table |
| 1944 | (completing-read rev1-prompt completion-table | 1974 | (completing-read rev1-prompt completion-table |
| 1945 | nil nil nil nil rev1-default) | 1975 | nil nil nil nil rev1-default) |
| 1946 | (read-string rev1-prompt nil nil rev1-default))) | 1976 | (read-string rev1-prompt nil nil rev1-default))) |
| 1947 | (rev2 (if completion-table | 1977 | (rev2 (if completion-table |
| 1948 | (completing-read rev2-prompt completion-table | 1978 | (completing-read rev2-prompt completion-table |
| 1949 | nil nil nil nil rev2-default) | 1979 | nil nil nil nil rev2-default) |
| 1950 | (read-string rev2-prompt nil nil rev2-default)))) | 1980 | (read-string rev2-prompt nil nil rev2-default)))) |
| 1951 | (list file rev1 rev2)))) | 1981 | (if (string= rev1 "") (setq rev1 nil)) |
| 1952 | (if (file-directory-p file) | 1982 | (if (string= rev2 "") (setq rev2 nil)) |
| 1953 | ;; recursive directory diff | 1983 | (list backend files rev1 rev2)))) |
| 1954 | (progn | 1984 | (if (and (not rev1) rev2) |
| 1955 | (vc-setup-buffer "*vc-diff*") | 1985 | (error "Not a valid revision range.")) |
| 1956 | (if (string-equal rev1 "") (setq rev1 nil)) | 1986 | (vc-diff-internal backend t files rev1 rev2 (interactive-p))) |
| 1957 | (if (string-equal rev2 "") (setq rev2 nil)) | 1987 | |
| 1958 | (let ((inhibit-read-only t)) | 1988 | ;;;###autoload |
| 1959 | (insert "Diffs between " | 1989 | (defun vc-diff (historic) |
| 1960 | (or rev1 "last version checked in") | 1990 | "Display diffs between file versions. |
| 1961 | " and " | 1991 | Normally this compares the current file and buffer with the most |
| 1962 | (or rev2 "working copy") | 1992 | recent checked in version of that file. This uses no arguments. With |
| 1963 | ":\n\n")) | 1993 | a prefix argument HISTORIC, it reads the file name to use and two |
| 1964 | (let ((dir (file-name-as-directory file))) | 1994 | version designators specifying which versions to compare." |
| 1965 | (vc-call-backend (vc-responsible-backend dir) | 1995 | (interactive "P") |
| 1966 | 'diff-tree dir rev1 rev2)) | 1996 | (if historic |
| 1967 | (vc-exec-after `(let ((inhibit-read-only t)) | 1997 | (call-interactively 'vc-history-diff) |
| 1968 | (insert "\nEnd of diffs.\n")))) | 1998 | (let* ((files (vc-deduce-fileset t)) |
| 1969 | ;; Single file diff. It is important that the vc-controlled buffer | 1999 | (first (car files)) |
| 1970 | ;; is still current at this time, because any local settings in that | 2000 | (backend |
| 1971 | ;; buffer should affect the diff command. | 2001 | (cond ((file-directory-p first) |
| 1972 | (vc-diff-internal file rev1 rev2)) | 2002 | (vc-responsible-backend first)) |
| 1973 | (set-buffer "*vc-diff*") | 2003 | (t |
| 1974 | (if (and (zerop (buffer-size)) | 2004 | (vc-backend first))))) |
| 1975 | (not (get-buffer-process (current-buffer)))) | 2005 | (vc-diff-internal backend t files nil nil (interactive-p))))) |
| 1976 | (progn | ||
| 1977 | (if rev1 | ||
| 1978 | (if rev2 | ||
| 1979 | (message "No changes to %s between %s and %s" file rev1 rev2) | ||
| 1980 | (message "No changes to %s since %s" file rev1)) | ||
| 1981 | (message "No changes to %s since latest version" file)) | ||
| 1982 | nil) | ||
| 1983 | (pop-to-buffer (current-buffer)) | ||
| 1984 | ;; Gnus-5.8.5 sets up an autoload for diff-mode, even if it's | ||
| 1985 | ;; not available. Work around that. | ||
| 1986 | (if (require 'diff-mode nil t) (diff-mode)) | ||
| 1987 | (vc-exec-after '(let ((inhibit-read-only t)) | ||
| 1988 | (if (eq (buffer-size) 0) | ||
| 1989 | (insert "No differences found.\n")) | ||
| 1990 | (goto-char (point-min)) | ||
| 1991 | (shrink-window-if-larger-than-buffer))) | ||
| 1992 | t)) | ||
| 1993 | |||
| 1994 | (defun vc-diff-label (file file-rev rev) | ||
| 1995 | (concat (file-relative-name file) | ||
| 1996 | (format-time-string "\t%d %b %Y %T %z\t" | ||
| 1997 | (nth 5 (file-attributes file-rev))) | ||
| 1998 | rev)) | ||
| 1999 | 2006 | ||
| 2000 | ;;;###autoload | 2007 | ;;;###autoload |
| 2001 | (defun vc-version-other-window (rev) | 2008 | (defun vc-version-other-window (rev) |
| @@ -2455,36 +2462,20 @@ allowed and simply skipped)." | |||
| 2455 | 2462 | ||
| 2456 | ;;;###autoload | 2463 | ;;;###autoload |
| 2457 | (defun vc-print-log (&optional focus-rev) | 2464 | (defun vc-print-log (&optional focus-rev) |
| 2458 | "List the change log of the current buffer in a window. | 2465 | "List the change log of the current fileset in a window. |
| 2459 | If FOCUS-REV is non-nil, leave the point at that revision." | 2466 | If FOCUS-REV is non-nil, leave the point at that revision." |
| 2460 | (interactive) | 2467 | (interactive) |
| 2461 | (vc-ensure-vc-buffer) | 2468 | (let* ((files (vc-deduce-fileset)) |
| 2462 | (let ((file buffer-file-name)) | 2469 | (backend (vc-backend (car files))) |
| 2463 | (or focus-rev (setq focus-rev (vc-workfile-version file))) | 2470 | (focus-rev (or focus-rev (vc-workfile-version (car files))))) |
| 2464 | ;; Don't switch to the output buffer before running the command, | 2471 | ;; Don't switch to the output buffer before running the command, |
| 2465 | ;; so that any buffer-local settings in the vc-controlled | 2472 | ;; so that any buffer-local settings in the vc-controlled |
| 2466 | ;; buffer can be accessed by the command. | 2473 | ;; buffer can be accessed by the command. |
| 2467 | (condition-case err | 2474 | (vc-call-backend backend 'print-log files "*vc-change-log*") |
| 2468 | (progn | 2475 | (pop-to-buffer "*vc-change-log*") |
| 2469 | (vc-call print-log (list file) "*vc-change-log*") | ||
| 2470 | (set-buffer "*vc-change-log*")) | ||
| 2471 | (wrong-number-of-arguments | ||
| 2472 | ;; If this error came from the above call to print-log, try again | ||
| 2473 | ;; without the optional buffer argument (for backward compatibility). | ||
| 2474 | ;; Otherwise, resignal. | ||
| 2475 | (if (or (not (eq (cadr err) | ||
| 2476 | (indirect-function | ||
| 2477 | (vc-find-backend-function (vc-backend file) | ||
| 2478 | 'print-log)))) | ||
| 2479 | (not (eq (caddr err) 2))) | ||
| 2480 | (signal (car err) (cdr err)) | ||
| 2481 | ;; for backward compatibility | ||
| 2482 | (vc-call print-log (list file)) | ||
| 2483 | (set-buffer "*vc*")))) | ||
| 2484 | (pop-to-buffer (current-buffer)) | ||
| 2485 | (vc-exec-after | 2476 | (vc-exec-after |
| 2486 | `(let ((inhibit-read-only t)) | 2477 | `(let ((inhibit-read-only t)) |
| 2487 | (vc-call-backend ',(vc-backend file) 'log-view-mode) | 2478 | (vc-call-backend ',backend 'log-view-mode) |
| 2488 | (goto-char (point-max)) (forward-line -1) | 2479 | (goto-char (point-max)) (forward-line -1) |
| 2489 | (while (looking-at "=*\n") | 2480 | (while (looking-at "=*\n") |
| 2490 | (delete-char (- (match-end 0) (match-beginning 0))) | 2481 | (delete-char (- (match-end 0) (match-beginning 0))) |
| @@ -2492,134 +2483,124 @@ If FOCUS-REV is non-nil, leave the point at that revision." | |||
| 2492 | (goto-char (point-min)) | 2483 | (goto-char (point-min)) |
| 2493 | (if (looking-at "[\b\t\n\v\f\r ]+") | 2484 | (if (looking-at "[\b\t\n\v\f\r ]+") |
| 2494 | (delete-char (- (match-end 0) (match-beginning 0)))) | 2485 | (delete-char (- (match-end 0) (match-beginning 0)))) |
| 2495 | ;; (shrink-window-if-larger-than-buffer) | 2486 | (shrink-window-if-larger-than-buffer) |
| 2496 | ;; move point to the log entry for the current version | 2487 | ;; move point to the log entry for the focus revision |
| 2497 | (vc-call-backend ',(vc-backend file) | 2488 | (vc-call-backend ',backend 'show-log-entry ',focus-rev) |
| 2498 | 'show-log-entry | ||
| 2499 | ',focus-rev) | ||
| 2500 | (setq vc-sentinel-movepoint (point)) | 2489 | (setq vc-sentinel-movepoint (point)) |
| 2501 | (set-buffer-modified-p nil))))) | 2490 | (set-buffer-modified-p nil))))) |
| 2502 | 2491 | ||
| 2503 | ;;;###autoload | 2492 | ;;;###autoload |
| 2504 | (defun vc-revert () | 2493 | (defun vc-revert () |
| 2505 | "Revert the current buffer's file to the version it was based on. | 2494 | "Revert working copies of the selected fileset to their repository contents. |
| 2506 | This asks for confirmation if the buffer contents are not identical | 2495 | This asks for confirmation if the buffer contents are not identical |
| 2507 | to that version. This function does not automatically pick up newer | 2496 | to the repository version (except for keyword expansion)." |
| 2508 | changes found in the master file; use \\[universal-argument] \\[vc-next-action] to do so." | ||
| 2509 | (interactive) | 2497 | (interactive) |
| 2510 | (vc-ensure-vc-buffer) | 2498 | (let* ((files (vc-deduce-fileset)) |
| 2511 | ;; Make sure buffer is saved. If the user says `no', abort since | 2499 | (backend (vc-backend (car files)))) |
| 2512 | ;; we cannot show the changes and ask for confirmation to discard them. | 2500 | ;; If any of the files is visited by the current buffer, make |
| 2513 | (vc-buffer-sync nil) | 2501 | ;; sure buffer is saved. If the user says `no', abort since |
| 2514 | (let ((file buffer-file-name) | 2502 | ;; we cannot show the changes and ask for confirmation to |
| 2515 | ;; This operation should always ask for confirmation. | 2503 | ;; discard them. |
| 2516 | (vc-suppress-confirm nil) | 2504 | (if (or (not files) (memq (buffer-file-name) files)) |
| 2517 | (obuf (current-buffer)) | 2505 | (vc-buffer-sync nil)) |
| 2518 | status) | 2506 | (dolist (file files) |
| 2519 | (if (vc-up-to-date-p file) | 2507 | (let (buf (get-file-buffer file)) |
| 2520 | (unless (yes-or-no-p "File seems up-to-date. Revert anyway? ") | 2508 | (if (and buf (buffer-modified-p buf)) |
| 2521 | (error "Revert canceled"))) | 2509 | (error "Please kill or save all modified buffers before reverting."))) |
| 2522 | (unless (vc-workfile-unchanged-p file) | 2510 | (if (vc-up-to-date-p file) |
| 2523 | (message "Finding changes...") | 2511 | (unless (yes-or-no-p (format "%s seems up-to-date. Revert anyway? " file)) |
| 2524 | ;; vc-diff selects the new window, which is not what we want: | 2512 | (error "Revert canceled")))) |
| 2525 | ;; if the new window is on another frame, that'd require the user | 2513 | (if (vc-diff-internal backend vc-allow-async-revert files nil nil) |
| 2526 | ;; moving her mouse to answer the yes-or-no-p question. | 2514 | (progn |
| 2527 | (let* ((vc-disable-async-diff (not vc-allow-async-revert)) | 2515 | (unless (yes-or-no-p (format "Discard changes in %s? " (vc-delistify files))) |
| 2528 | (win (save-selected-window | 2516 | (error "Revert canceled")) |
| 2529 | (setq status (vc-diff nil t)) (selected-window)))) | 2517 | (delete-windows-on "*vc-diff*") |
| 2530 | (vc-exec-after `(message nil)) | 2518 | (kill-buffer "*vc-diff*"))) |
| 2531 | (when status | 2519 | (dolist (file files) |
| 2532 | (unwind-protect | 2520 | (progn |
| 2533 | (unless (yes-or-no-p "Discard changes? ") | 2521 | (message "Reverting %s..." (vc-delistify files)) |
| 2534 | (error "Revert canceled")) | 2522 | (vc-revert-file file) |
| 2535 | (select-window win) | 2523 | (message "Reverting %s...done" (vc-delistify files)))))) |
| 2536 | (if (one-window-p t) | ||
| 2537 | (if (window-dedicated-p (selected-window)) | ||
| 2538 | (make-frame-invisible)) | ||
| 2539 | (delete-window)))))) | ||
| 2540 | (set-buffer obuf) | ||
| 2541 | ;; Do the reverting | ||
| 2542 | (message "Reverting %s..." file) | ||
| 2543 | (vc-revert-file file) | ||
| 2544 | (message "Reverting %s...done" file))) | ||
| 2545 | 2524 | ||
| 2546 | ;;;###autoload | 2525 | ;;;###autoload |
| 2547 | (defun vc-rollback (&optional norevert) | 2526 | (defun vc-rollback () |
| 2548 | "Get rid of most recently checked in version of this file. | 2527 | "Roll back (remove) the most recent changeset committed to the repository. |
| 2549 | A prefix argument NOREVERT means do not revert the buffer afterwards." | 2528 | This may be either a file-level or a repository-level operation, |
| 2550 | (interactive "P") | 2529 | depending on the underlying version-control system." |
| 2551 | (vc-ensure-vc-buffer) | 2530 | (interactive) |
| 2552 | (let* ((file buffer-file-name) | 2531 | (let* ((files (vc-deduce-fileset)) |
| 2553 | (backend (vc-backend file)) | 2532 | (backend (vc-backend (car files))) |
| 2554 | (target (vc-workfile-version file))) | 2533 | (granularity (vc-call-backend backend 'revision-granularity))) |
| 2555 | (cond | 2534 | (unless (vc-find-backend-function backend 'rollback) |
| 2556 | ((not (vc-find-backend-function backend 'rollback)) | 2535 | (error "Rollback is not supported in %s" backend)) |
| 2557 | (error "Sorry, canceling versions is not supported under %s" backend)) | 2536 | (if (and (not (eq granularity 'repository)) (/= (length files) 1)) |
| 2558 | ((not (vc-call latest-on-branch-p file)) | 2537 | (error "Rollback requires a singleton fileset or repository versioning")) |
| 2559 | (error "This is not the latest version; VC cannot cancel it")) | 2538 | (if (not (vc-call latest-on-branch-p (car files))) |
| 2560 | ((not (vc-up-to-date-p file)) | 2539 | (error "Rollback is only possible at the tip revision.")) |
| 2561 | (error "%s" (substitute-command-keys "File is not up to date; use \\[vc-revert] to discard changes")))) | 2540 | ;; If any of the files is visited by the current buffer, make |
| 2562 | (if (null (yes-or-no-p (format "Remove version %s from master? " target))) | 2541 | ;; sure buffer is saved. If the user says `no', abort since |
| 2563 | (error "Aborted") | 2542 | ;; we cannot show the changes and ask for confirmation to |
| 2564 | (setq norevert (or norevert (not | 2543 | ;; discard them. |
| 2565 | (yes-or-no-p "Revert buffer to most recent remaining version? ")))) | 2544 | (if (or (not files) (memq (buffer-file-name) files)) |
| 2566 | 2545 | (vc-buffer-sync nil)) | |
| 2567 | (message "Removing last change from %s..." file) | 2546 | (dolist (file files) |
| 2568 | (with-vc-properties | 2547 | (if (buffer-modified-p (get-file-buffer file)) |
| 2569 | file | 2548 | (error "Please kill or save all modified buffers before rollback.")) |
| 2570 | (vc-call rollback (list file)) | 2549 | (if (not (vc-up-to-date-p file)) |
| 2571 | `((vc-state . ,(if norevert 'edited 'up-to-date)) | 2550 | (error "Please revert all modified workfiles before rollback."))) |
| 2572 | (vc-checkout-time . ,(if norevert | 2551 | ;; Accumulate changes associated with the fileset |
| 2573 | 0 | 2552 | (vc-setup-buffer "*vc-diff*") |
| 2574 | (nth 5 (file-attributes file)))) | 2553 | (not-modified) |
| 2575 | (vc-workfile-version . nil))) | 2554 | (message "Finding changes...") |
| 2576 | (message "Removing last change from %s...done" file) | 2555 | (let* ((tip (vc-workfile-version (car files))) |
| 2577 | 2556 | (previous (vc-call previous-version (car files) tip))) | |
| 2578 | (cond | 2557 | (vc-diff-internal backend nil files previous tip)) |
| 2579 | (norevert ;; clear version headers and mark the buffer modified | 2558 | ;; Display changes |
| 2580 | (set-visited-file-name file) | 2559 | (unless (yes-or-no-p "Discard these revisions? ") |
| 2581 | (when (not vc-make-backup-files) | 2560 | (error "Rollback canceled")) |
| 2582 | ;; inhibit backup for this buffer | 2561 | (delete-windows-on "*vc-diff*") |
| 2583 | (make-local-variable 'backup-inhibited) | 2562 | (kill-buffer"*vc-diff*") |
| 2584 | (setq backup-inhibited t)) | 2563 | ;; Do the actual reversions |
| 2585 | (setq buffer-read-only nil) | 2564 | (message "Rolling back %s..." (vc-delistify files)) |
| 2586 | (vc-clear-headers) | 2565 | (with-vc-properties |
| 2587 | (vc-mode-line file) | 2566 | files |
| 2588 | (vc-dired-resynch-file file)) | 2567 | (vc-call-backend backend 'rollback files) |
| 2589 | (t ;; revert buffer to file on disk | 2568 | `((vc-state . ,'up-to-date) |
| 2590 | (vc-resynch-buffer file t t))) | 2569 | (vc-checkout-time . , (nth 5 (file-attributes file))) |
| 2591 | (message "Version %s has been removed from the master" target)))) | 2570 | (vc-workfile-version . nil))) |
| 2571 | (mapc (lambda (f) (vc-resynch-buffer f t t)) files) | ||
| 2572 | (message "Rolling back %s...done" (vc-delistify files)))) | ||
| 2592 | 2573 | ||
| 2593 | ;;;###autoload | 2574 | ;;;###autoload |
| 2594 | (define-obsolete-function-alias 'vc-revert-buffer 'vc-revert "23.1") | 2575 | (define-obsolete-function-alias 'vc-revert-buffer 'vc-revert "23.1") |
| 2595 | 2576 | ||
| 2596 | ;;;###autoload | 2577 | ;;;###autoload |
| 2597 | (defun vc-update () | 2578 | (defun vc-update () |
| 2598 | "Update the current buffer's file to the latest version on its branch. | 2579 | "Update the current fileset's files to their tip versions. |
| 2599 | If the file contains no changes, and is not locked, then this simply replaces | 2580 | For each one that contains no changes, and is not locked, then this simply |
| 2600 | the working file with the latest version on its branch. If the file contains | 2581 | replaces the work file with the latest version on its branch. If the file |
| 2601 | changes, and the backend supports merging news, then any recent changes from | 2582 | contains changes, and the backend supports merging news, then any recent |
| 2602 | the current branch are merged into the working file." | 2583 | changes from the current branch are merged into the working file." |
| 2603 | (interactive) | 2584 | (interactive) |
| 2604 | (vc-ensure-vc-buffer) | 2585 | (dolist (file (vc-deduce-fileset)) |
| 2605 | (vc-buffer-sync nil) | 2586 | (if (buffer-modified-p (get-file-buffer file)) |
| 2606 | (let ((file buffer-file-name)) | 2587 | (error "Please kill or save all modified buffers before updating.")) |
| 2607 | (if (vc-up-to-date-p file) | 2588 | (if (vc-up-to-date-p file) |
| 2608 | (vc-checkout file nil "") | 2589 | (vc-checkout file nil "") |
| 2609 | (if (eq (vc-checkout-model file) 'locking) | 2590 | (if (eq (vc-checkout-model file) 'locking) |
| 2610 | (if (eq (vc-state file) 'edited) | 2591 | (if (eq (vc-state file) 'edited) |
| 2611 | (error | 2592 | (error |
| 2612 | (substitute-command-keys | 2593 | (substitute-command-keys |
| 2613 | "File is locked--type \\[vc-revert] to discard changes")) | 2594 | "File is locked--type \\[vc-revert] to discard changes")) |
| 2614 | (error | 2595 | (error |
| 2615 | (substitute-command-keys | 2596 | (substitute-command-keys |
| 2616 | "Unexpected file state (%s)--type \\[vc-next-action] to correct") | 2597 | "Unexpected file state (%s)--type \\[vc-next-action] to correct") |
| 2617 | (vc-state file))) | 2598 | (vc-state file))) |
| 2618 | (if (not (vc-find-backend-function (vc-backend file) 'merge-news)) | 2599 | (if (not (vc-find-backend-function (vc-backend file) 'merge-news)) |
| 2619 | (error "Sorry, merging news is not implemented for %s" | 2600 | (error "Sorry, merging news is not implemented for %s" |
| 2620 | (vc-backend file)) | 2601 | (vc-backend file)) |
| 2621 | (vc-call merge-news file) | 2602 | (vc-call merge-news file) |
| 2622 | (vc-resynch-window file t t)))))) | 2603 | (vc-resynch-buffer file t t)))))) |
| 2623 | 2604 | ||
| 2624 | (defun vc-version-backup-file (file &optional rev) | 2605 | (defun vc-version-backup-file (file &optional rev) |
| 2625 | "Return name of backup file for revision REV of FILE. | 2606 | "Return name of backup file for revision REV of FILE. |
| @@ -2638,7 +2619,7 @@ its name; otherwise return nil." | |||
| 2638 | (defun vc-revert-file (file) | 2619 | (defun vc-revert-file (file) |
| 2639 | "Revert FILE back to the repository version it was based on." | 2620 | "Revert FILE back to the repository version it was based on." |
| 2640 | (with-vc-properties | 2621 | (with-vc-properties |
| 2641 | file | 2622 | (list file) |
| 2642 | (let ((backup-file (vc-version-backup-file file))) | 2623 | (let ((backup-file (vc-version-backup-file file))) |
| 2643 | (when backup-file | 2624 | (when backup-file |
| 2644 | (copy-file backup-file file 'ok-if-already-exists 'keep-date) | 2625 | (copy-file backup-file file 'ok-if-already-exists 'keep-date) |
| @@ -2662,32 +2643,25 @@ To get a prompt, use a prefix argument." | |||
| 2662 | (error "There is no version-controlled file in this buffer")) | 2643 | (error "There is no version-controlled file in this buffer")) |
| 2663 | (let ((backend (vc-backend buffer-file-name)) | 2644 | (let ((backend (vc-backend buffer-file-name)) |
| 2664 | (backends nil)) | 2645 | (backends nil)) |
| 2665 | (unwind-protect | 2646 | (unless backend |
| 2666 | (progn | 2647 | (error "File %s is not under version control" buffer-file-name)) |
| 2667 | (unless backend | 2648 | ;; Find the registered backends. |
| 2668 | (error "File %s is not under version control" buffer-file-name)) | 2649 | (dolist (backend vc-handled-backends) |
| 2669 | ;; Find the registered backends. | 2650 | (when (vc-call-backend backend 'registered buffer-file-name) |
| 2670 | (dolist (backend vc-handled-backends) | 2651 | (push backend backends))) |
| 2671 | (when (vc-call-backend backend 'registered buffer-file-name) | 2652 | ;; Find the next backend. |
| 2672 | (push backend backends))) | 2653 | (let ((def (car (delq backend (append (memq backend backends) backends)))) |
| 2673 | ;; Find the next backend. | 2654 | (others (delete backend backends))) |
| 2674 | (let ((def (car (delq backend | 2655 | (cond |
| 2675 | (append (memq backend backends) backends)))) | 2656 | ((null others) (error "No other backend to switch to")) |
| 2676 | (others (delete backend backends))) | 2657 | (current-prefix-arg |
| 2677 | (cond | 2658 | (intern |
| 2678 | ((null others) (error "No other backend to switch to")) | 2659 | (upcase |
| 2679 | (current-prefix-arg | 2660 | (completing-read |
| 2680 | (intern | 2661 | (format "Switch to backend [%s]: " def) |
| 2681 | (upcase | 2662 | (mapcar (lambda (b) (list (downcase (symbol-name b)))) backends) |
| 2682 | (completing-read | 2663 | nil t nil nil (downcase (symbol-name def)))))) |
| 2683 | (format "Switch to backend [%s]: " def) | 2664 | (t def)))))) |
| 2684 | (mapcar (lambda (b) (list (downcase (symbol-name b)))) backends) | ||
| 2685 | nil t nil nil (downcase (symbol-name def)))))) | ||
| 2686 | (t def)))) | ||
| 2687 | ;; Calling the `registered' method can mess up the file | ||
| 2688 | ;; properties, so we want to revert them to what they were. | ||
| 2689 | (if (and backend (delete backend backends)) | ||
| 2690 | (vc-call-backend backend 'registered buffer-file-name)))))) | ||
| 2691 | (unless (eq backend (vc-backend file)) | 2665 | (unless (eq backend (vc-backend file)) |
| 2692 | (vc-file-clearprops file) | 2666 | (vc-file-clearprops file) |
| 2693 | (vc-file-setprop file 'vc-backend backend) | 2667 | (vc-file-setprop file 'vc-backend backend) |
| @@ -2953,7 +2927,7 @@ editing non-current versions is not supported by default." | |||
| 2953 | (defalias 'vc-rcs-update-changelog 'vc-update-changelog-rcs2log) | 2927 | (defalias 'vc-rcs-update-changelog 'vc-update-changelog-rcs2log) |
| 2954 | ;; FIXME: This should probably be moved to vc-rcs.el and replaced in | 2928 | ;; FIXME: This should probably be moved to vc-rcs.el and replaced in |
| 2955 | ;; vc-cvs.el by code using cvs2cl. | 2929 | ;; vc-cvs.el by code using cvs2cl. |
| 2956 | (defun vc-update-changelog-rcs2log (files) | 2930 | (defun vc-update-changelog-rcs2log (backend files) |
| 2957 | "Default implementation of update-changelog. | 2931 | "Default implementation of update-changelog. |
| 2958 | Uses `rcs2log' which only works for RCS and CVS." | 2932 | Uses `rcs2log' which only works for RCS and CVS." |
| 2959 | ;; FIXME: We (c|sh)ould add support for cvs2cl | 2933 | ;; FIXME: We (c|sh)ould add support for cvs2cl |
| @@ -2994,7 +2968,7 @@ Uses `rcs2log' which only works for RCS and CVS." | |||
| 2994 | (mapcar | 2968 | (mapcar |
| 2995 | (lambda (f) | 2969 | (lambda (f) |
| 2996 | (file-relative-name | 2970 | (file-relative-name |
| 2997 | (expand-file-name f odefault))) | 2971 | (expand-file-name f odefault))) |
| 2998 | files))) | 2972 | files))) |
| 2999 | "done" | 2973 | "done" |
| 3000 | (pop-to-buffer (get-buffer-create "*vc*")) | 2974 | (pop-to-buffer (get-buffer-create "*vc*")) |
| @@ -3017,13 +2991,19 @@ to provide the `find-version' operation instead." | |||
| 3017 | (delete-file tmpfile)))) | 2991 | (delete-file tmpfile)))) |
| 3018 | 2992 | ||
| 3019 | (defun vc-default-dired-state-info (backend file) | 2993 | (defun vc-default-dired-state-info (backend file) |
| 3020 | (let ((state (vc-state file))) | 2994 | (let* ((state (vc-state file)) |
| 3021 | (cond | 2995 | (statestring |
| 3022 | ((stringp state) (concat "(" state ")")) | 2996 | (cond |
| 3023 | ((eq state 'edited) (concat "(" (vc-user-login-name file) ")")) | 2997 | ((stringp state) (concat "(" state ")")) |
| 3024 | ((eq state 'needs-merge) "(merge)") | 2998 | ((eq state 'edited) (concat "(" (vc-user-login-name file) ")")) |
| 3025 | ((eq state 'needs-patch) "(patch)") | 2999 | ((eq state 'needs-merge) "(merge)") |
| 3026 | ((eq state 'unlocked-changes) "(stale)")))) | 3000 | ((eq state 'needs-patch) "(patch)") |
| 3001 | ((eq state 'unlocked-changes) "(stale)"))) | ||
| 3002 | (buffer | ||
| 3003 | (get-file-buffer file)) | ||
| 3004 | (modflag | ||
| 3005 | (if (and buffer (buffer-modified-p buffer)) "+" ""))) | ||
| 3006 | (concat statestring modflag))) | ||
| 3027 | 3007 | ||
| 3028 | (defun vc-default-rename-file (backend old new) | 3008 | (defun vc-default-rename-file (backend old new) |
| 3029 | (condition-case nil | 3009 | (condition-case nil |
| @@ -3427,7 +3407,11 @@ versions after." | |||
| 3427 | (if (not prev-rev) | 3407 | (if (not prev-rev) |
| 3428 | (message "Cannot diff from any version prior to %s" rev-at-line) | 3408 | (message "Cannot diff from any version prior to %s" rev-at-line) |
| 3429 | (save-window-excursion | 3409 | (save-window-excursion |
| 3430 | (vc-version-diff vc-annotate-parent-file prev-rev rev-at-line)) | 3410 | (vc-diff-internal |
| 3411 | (vc-backend vc-annotate-parent-file) | ||
| 3412 | nil | ||
| 3413 | (list vc-annotate-parent-file) | ||
| 3414 | prev-rev rev-at-line)) | ||
| 3431 | (switch-to-buffer "*vc-diff*")))))) | 3415 | (switch-to-buffer "*vc-diff*")))))) |
| 3432 | 3416 | ||
| 3433 | (defun vc-annotate-warp-version (revspec) | 3417 | (defun vc-annotate-warp-version (revspec) |
| @@ -3548,18 +3532,12 @@ The annotations are relative to the current time, unless overridden by OFFSET." | |||
| 3548 | 3532 | ||
| 3549 | ;; Set up key bindings for use while editing log messages | 3533 | ;; Set up key bindings for use while editing log messages |
| 3550 | 3534 | ||
| 3551 | (defun vc-log-edit (file) | 3535 | (defun vc-log-edit (fileset) |
| 3552 | "Set up `log-edit' for use with VC on FILE." | 3536 | "Set up `log-edit' for use with VC on FILE." |
| 3553 | (setq default-directory | 3537 | (setq default-directory |
| 3554 | (if file (file-name-directory file) | 3538 | (with-current-buffer vc-parent-buffer default-directory)) |
| 3555 | (with-current-buffer vc-parent-buffer default-directory))) | 3539 | (log-edit 'vc-finish-logentry nil `(lambda () ',fileset)) |
| 3556 | (log-edit 'vc-finish-logentry nil | 3540 | (set (make-local-variable 'vc-log-fileset) fileset) |
| 3557 | (if file `(lambda () ',(list (file-name-nondirectory file))) | ||
| 3558 | ;; If FILE is nil, we were called from vc-dired. | ||
| 3559 | (lambda () | ||
| 3560 | (with-current-buffer vc-parent-buffer | ||
| 3561 | (dired-get-marked-files t))))) | ||
| 3562 | (set (make-local-variable 'vc-log-file) file) | ||
| 3563 | (make-local-variable 'vc-log-version) | 3541 | (make-local-variable 'vc-log-version) |
| 3564 | (set-buffer-modified-p nil) | 3542 | (set-buffer-modified-p nil) |
| 3565 | (setq buffer-file-name nil)) | 3543 | (setq buffer-file-name nil)) |