diff options
| author | André Spiegel | 1995-08-17 12:40:03 +0000 |
|---|---|---|
| committer | André Spiegel | 1995-08-17 12:40:03 +0000 |
| commit | c8de1d91120419d2cd185a7ed8c94693e70c7bd0 (patch) | |
| tree | f053f88aa923d2c3e493fbb74d8522291f72e663 | |
| parent | 0671e80b5ed1fcc5a51e32a6f047ae228e4d7caa (diff) | |
| download | emacs-c8de1d91120419d2cd185a7ed8c94693e70c7bd0.tar.gz emacs-c8de1d91120419d2cd185a7ed8c94693e70c7bd0.zip | |
(vc-revert-buffer1): Split part of the function into vc-buffer-context
and vc-restore-buffer-context, so we can use it also in other
circumstances.
(vc-buffer-context, vc-restore-buffer-context): New functions.
(vc-clear-headers): New function, uses the above.
(vc-cancel-version): When `norevert', locks the most recent remaining
version. Also, refuse to work on anything but the latest version of
a branch. Removed the check whether the version is the user's,
because that is difficult to decide, now that multiple branches are
possible.
(vc-latest-on-branch-p): New function.
(vc-head-version): New access function to the already existing
property.
(vc-trunk-p, vc-branch-part): Functions moved before first use.
| -rw-r--r-- | lisp/vc.el | 135 |
1 files changed, 101 insertions, 34 deletions
diff --git a/lisp/vc.el b/lisp/vc.el index 902367e5ac4..b22cd6fcdb6 100644 --- a/lisp/vc.el +++ b/lisp/vc.el | |||
| @@ -193,6 +193,16 @@ and that its contents match what the master file says.") | |||
| 193 | (if (not (boundp 'file-regular-p)) | 193 | (if (not (boundp 'file-regular-p)) |
| 194 | (fset 'file-regular-p 'file-regular-p-18)) | 194 | (fset 'file-regular-p 'file-regular-p-18)) |
| 195 | 195 | ||
| 196 | ;;; functions that operate on RCS revision numbers | ||
| 197 | |||
| 198 | (defun vc-trunk-p (rev) | ||
| 199 | ;; return t if REV is a revision on the trunk | ||
| 200 | (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev)))) | ||
| 201 | |||
| 202 | (defun vc-branch-part (rev) | ||
| 203 | ;; return the branch part of a revision number REV | ||
| 204 | (substring rev 0 (string-match "\\.[0-9]+\\'" rev))) | ||
| 205 | |||
| 196 | ;; File property caching | 206 | ;; File property caching |
| 197 | 207 | ||
| 198 | (defun vc-clear-context () | 208 | (defun vc-clear-context () |
| @@ -219,18 +229,44 @@ and that its contents match what the master file says.") | |||
| 219 | (progn | 229 | (progn |
| 220 | (vc-file-setprop file 'vc-cvs-status nil)))) | 230 | (vc-file-setprop file 'vc-cvs-status nil)))) |
| 221 | 231 | ||
| 222 | ;;; functions that operate on RCS revision numbers | 232 | (defun vc-head-version (file) |
| 223 | 233 | ;; Return the RCS head version of FILE | |
| 224 | (defun vc-trunk-p (rev) | 234 | (cond ((vc-file-getprop file 'vc-head-version)) |
| 225 | ;; return t if REV is a revision on the trunk | 235 | (t (vc-fetch-master-properties file) |
| 226 | (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev)))) | 236 | (vc-file-getprop file 'vc-head-version)))) |
| 227 | |||
| 228 | (defun vc-branch-part (rev) | ||
| 229 | ;; return the branch part of a revision number REV | ||
| 230 | (substring rev 0 (string-match "\\.[0-9]+\\'" rev))) | ||
| 231 | 237 | ||
| 232 | ;; Random helper functions | 238 | ;; Random helper functions |
| 233 | 239 | ||
| 240 | (defun vc-latest-on-branch-p (file) | ||
| 241 | ;; return t iff the current workfile version of FILE is | ||
| 242 | ;; the latest on its branch. | ||
| 243 | (vc-backend-dispatch file | ||
| 244 | ;; SCCS | ||
| 245 | (string= (vc-workfile-version file) (vc-latest-version file)) | ||
| 246 | ;; RCS | ||
| 247 | (let ((workfile-version (vc-workfile-version file)) tip-version) | ||
| 248 | (if (vc-trunk-p workfile-version) | ||
| 249 | (progn | ||
| 250 | ;; Re-fetch the head version number. This is to make | ||
| 251 | ;; sure that no-one has checked in a new version behind | ||
| 252 | ;; our back. | ||
| 253 | (vc-fetch-master-properties file) | ||
| 254 | (string= (vc-file-getprop file 'vc-head-version) | ||
| 255 | workfile-version)) | ||
| 256 | ;; If we are not on the trunk, we need to examine the | ||
| 257 | ;; whole current branch. (vc-top-version is not what we need.) | ||
| 258 | (save-excursion | ||
| 259 | (set-buffer (get-buffer-create "*vc-info*")) | ||
| 260 | (vc-insert-file (vc-name file) "^desc") | ||
| 261 | (setq tip-version (car (vc-parse-buffer (list (list | ||
| 262 | (concat "^\\(" (regexp-quote (vc-branch-part workfile-version)) | ||
| 263 | "\\.[0-9]+\\)\ndate[ \t]+\\([0-9.]+\\);") 1 2))))) | ||
| 264 | (if (get-buffer "*vc-info*") | ||
| 265 | (kill-buffer (get-buffer "*vc-info*"))) | ||
| 266 | (string= tip-version workfile-version)))) | ||
| 267 | ;; CVS | ||
| 268 | (error "vc-latest-on-branch-p is not defined for CVS files"))) | ||
| 269 | |||
| 234 | (defun vc-registration-error (file) | 270 | (defun vc-registration-error (file) |
| 235 | (if file | 271 | (if file |
| 236 | (error "File %s is not under version control" file) | 272 | (error "File %s is not under version control" file) |
| @@ -322,6 +358,7 @@ to an optional list of FLAGS." | |||
| 322 | ;;; Save a bit of the text around POSN in the current buffer, to help | 358 | ;;; Save a bit of the text around POSN in the current buffer, to help |
| 323 | ;;; us find the corresponding position again later. This works even | 359 | ;;; us find the corresponding position again later. This works even |
| 324 | ;;; if all markers are destroyed or corrupted. | 360 | ;;; if all markers are destroyed or corrupted. |
| 361 | ;;; A lot of this was shamelessly lifted from Sebastian Kremer's rcs.el mode. | ||
| 325 | (defun vc-position-context (posn) | 362 | (defun vc-position-context (posn) |
| 326 | (list posn | 363 | (list posn |
| 327 | (buffer-size) | 364 | (buffer-size) |
| @@ -348,13 +385,9 @@ to an optional list of FLAGS." | |||
| 348 | ;; to beginning of OSTRING | 385 | ;; to beginning of OSTRING |
| 349 | (- (point) (length context-string)))))))) | 386 | (- (point) (length context-string)))))))) |
| 350 | 387 | ||
| 351 | (defun vc-revert-buffer1 (&optional arg no-confirm) | 388 | (defun vc-buffer-context () |
| 352 | ;; Most of this was shamelessly lifted from Sebastian Kremer's rcs.el mode. | 389 | ;; Return a list '(point-context mark-context reparse); from which |
| 353 | ;; Revert buffer, try to keep point and mark where user expects them in spite | 390 | ;; vc-restore-buffer-context can later restore the context. |
| 354 | ;; of changes because of expanded version-control key words. | ||
| 355 | ;; This is quite important since otherwise typeahead won't work as expected. | ||
| 356 | (interactive "P") | ||
| 357 | (widen) | ||
| 358 | (let ((point-context (vc-position-context (point))) | 391 | (let ((point-context (vc-position-context (point))) |
| 359 | ;; Use mark-marker to avoid confusion in transient-mark-mode. | 392 | ;; Use mark-marker to avoid confusion in transient-mark-mode. |
| 360 | (mark-context (if (eq (marker-buffer (mark-marker)) (current-buffer)) | 393 | (mark-context (if (eq (marker-buffer (mark-marker)) (current-buffer)) |
| @@ -385,9 +418,14 @@ to an optional list of FLAGS." | |||
| 385 | (setq errors (cdr errors))) | 418 | (setq errors (cdr errors))) |
| 386 | (if buffer-error-marked-p buffer)))) | 419 | (if buffer-error-marked-p buffer)))) |
| 387 | (buffer-list))))))) | 420 | (buffer-list))))))) |
| 388 | 421 | (list point-context mark-context reparse))) | |
| 389 | (revert-buffer arg no-confirm) | 422 | |
| 390 | 423 | (defun vc-restore-buffer-context (context) | |
| 424 | ;; Restore point/mark, and reparse any affected compilation buffers. | ||
| 425 | ;; CONTEXT is that which vc-buffer-context returns. | ||
| 426 | (let ((point-context (nth 0 context)) | ||
| 427 | (mark-context (nth 1 context)) | ||
| 428 | (reparse (nth 2 context))) | ||
| 391 | ;; Reparse affected compilation buffers. | 429 | ;; Reparse affected compilation buffers. |
| 392 | (while reparse | 430 | (while reparse |
| 393 | (if (car reparse) | 431 | (if (car reparse) |
| @@ -414,6 +452,16 @@ to an optional list of FLAGS." | |||
| 414 | (let ((new-mark (vc-find-position-by-context mark-context))) | 452 | (let ((new-mark (vc-find-position-by-context mark-context))) |
| 415 | (if new-mark (set-mark new-mark)))))) | 453 | (if new-mark (set-mark new-mark)))))) |
| 416 | 454 | ||
| 455 | (defun vc-revert-buffer1 (&optional arg no-confirm) | ||
| 456 | ;; Revert buffer, try to keep point and mark where user expects them in spite | ||
| 457 | ;; of changes because of expanded version-control key words. | ||
| 458 | ;; This is quite important since otherwise typeahead won't work as expected. | ||
| 459 | (interactive "P") | ||
| 460 | (widen) | ||
| 461 | (let ((context (vc-buffer-context))) | ||
| 462 | (revert-buffer arg no-confirm) | ||
| 463 | (vc-restore-buffer-context context))) | ||
| 464 | |||
| 417 | 465 | ||
| 418 | (defun vc-buffer-sync (&optional not-urgent) | 466 | (defun vc-buffer-sync (&optional not-urgent) |
| 419 | ;; Make sure the current buffer and its working file are in sync | 467 | ;; Make sure the current buffer and its working file are in sync |
| @@ -1089,6 +1137,16 @@ the variable `vc-header-alist'." | |||
| 1089 | ) | 1137 | ) |
| 1090 | ))))) | 1138 | ))))) |
| 1091 | 1139 | ||
| 1140 | (defun vc-clear-headers () | ||
| 1141 | ;; Clear all version headers in the current buffer, i.e. reset them | ||
| 1142 | ;; to the nonexpanded form. Only implemented for RCS, yet. | ||
| 1143 | ;; Don't lose point and mark during this. | ||
| 1144 | (let ((context (vc-buffer-context))) | ||
| 1145 | (goto-char (point-min)) | ||
| 1146 | (while (re-search-forward "\\$\\([A-Za-z]+\\): [^\\$]+\\$" nil t) | ||
| 1147 | (replace-match "$\\1$")) | ||
| 1148 | (vc-restore-buffer-context context))) | ||
| 1149 | |||
| 1092 | ;; The VC directory submode. Coopt Dired for this. | 1150 | ;; The VC directory submode. Coopt Dired for this. |
| 1093 | ;; All VC commands get mapped into logical equivalents. | 1151 | ;; All VC commands get mapped into logical equivalents. |
| 1094 | 1152 | ||
| @@ -1397,21 +1455,31 @@ A prefix argument means do not revert the buffer afterwards." | |||
| 1397 | (find-file-other-window (dired-get-filename))) | 1455 | (find-file-other-window (dired-get-filename))) |
| 1398 | (while vc-parent-buffer | 1456 | (while vc-parent-buffer |
| 1399 | (pop-to-buffer vc-parent-buffer)) | 1457 | (pop-to-buffer vc-parent-buffer)) |
| 1400 | (if (eq (vc-backend (buffer-file-name)) 'CVS) | 1458 | (cond |
| 1401 | (error "Unchecking files under CVS is dangerous and not supported in VC")) | 1459 | ((eq (vc-backend (buffer-file-name)) 'CVS) |
| 1402 | (let* ((target (concat (vc-latest-version (buffer-file-name)))) | 1460 | (error "Unchecking files under CVS is dangerous and not supported in VC")) |
| 1403 | (yours (concat (vc-your-latest-version (buffer-file-name)))) | 1461 | ((vc-locking-user (buffer-file-name)) |
| 1404 | (prompt (if (string-equal yours target) | 1462 | (error "This version is locked. Use vc-revert-buffer to discard changes.")) |
| 1405 | "Remove your version %s from master? " | 1463 | ((not (vc-latest-on-branch-p (buffer-file-name))) |
| 1406 | "Version %s was not your change. Remove it anyway? "))) | 1464 | (error "This is not the latest version. VC cannot cancel it."))) |
| 1407 | (if (null (yes-or-no-p (format prompt target))) | 1465 | (let ((target (vc-workfile-version (buffer-file-name)))) |
| 1466 | (if (null (yes-or-no-p "Remove this version from master? ")) | ||
| 1408 | nil | 1467 | nil |
| 1468 | (setq norevert (or norevert (not | ||
| 1469 | (yes-or-no-p "Revert buffer to most recent remaining version? ")))) | ||
| 1409 | (vc-backend-uncheck (buffer-file-name) target) | 1470 | (vc-backend-uncheck (buffer-file-name) target) |
| 1410 | (if (or norevert | 1471 | (if (not norevert) |
| 1411 | (not (yes-or-no-p "Revert buffer to most recent remaining version? "))) | 1472 | (vc-checkout (buffer-file-name) nil) |
| 1412 | (vc-mode-line (buffer-file-name)) | 1473 | ;; If norevert, lock the most recent remaining version, |
| 1413 | (vc-checkout (buffer-file-name) nil))) | 1474 | ;; and mark the buffer modified. |
| 1414 | )) | 1475 | (if (eq (vc-backend (buffer-file-name)) 'RCS) |
| 1476 | (progn (setq buffer-read-only nil) | ||
| 1477 | (vc-clear-headers))) | ||
| 1478 | (vc-backend-checkout (buffer-file-name) t (vc-branch-part target)) | ||
| 1479 | (set-visited-file-name (buffer-file-name)) | ||
| 1480 | (vc-mode-line (buffer-file-name))) | ||
| 1481 | (message "Version %s has been removed from the master." target) | ||
| 1482 | ))) | ||
| 1415 | 1483 | ||
| 1416 | ;;;###autoload | 1484 | ;;;###autoload |
| 1417 | (defun vc-rename-file (old new) | 1485 | (defun vc-rename-file (old new) |
| @@ -1841,8 +1909,7 @@ From a program, any arguments are passed to the `rcs2log' script." | |||
| 1841 | ) | 1909 | ) |
| 1842 | 1910 | ||
| 1843 | (defun vc-backend-uncheck (file target) | 1911 | (defun vc-backend-uncheck (file target) |
| 1844 | ;; Undo the latest checkin. Note: this code will have to get a lot | 1912 | ;; Undo the latest checkin. |
| 1845 | ;; smarter when we support multiple branches. | ||
| 1846 | (message "Removing last change from %s..." file) | 1913 | (message "Removing last change from %s..." file) |
| 1847 | (vc-backend-dispatch file | 1914 | (vc-backend-dispatch file |
| 1848 | (vc-do-command nil 0 "rmdel" file 'MASTER (concat "-r" target)) | 1915 | (vc-do-command nil 0 "rmdel" file 'MASTER (concat "-r" target)) |