aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndré Spiegel1995-08-17 12:40:03 +0000
committerAndré Spiegel1995-08-17 12:40:03 +0000
commitc8de1d91120419d2cd185a7ed8c94693e70c7bd0 (patch)
treef053f88aa923d2c3e493fbb74d8522291f72e663
parent0671e80b5ed1fcc5a51e32a6f047ae228e4d7caa (diff)
downloademacs-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.el135
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))