aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndré Spiegel1995-08-25 18:30:11 +0000
committerAndré Spiegel1995-08-25 18:30:11 +0000
commitb0c9bc8c219872ae1533934ddd62c38e8a4d37b0 (patch)
tree1849df9aaa33fbc2095d994652669cde65ae6b5c
parentf042d383859e631c3f81bed06b7415a49f1db164 (diff)
downloademacs-b0c9bc8c219872ae1533934ddd62c38e8a4d37b0.tar.gz
emacs-b0c9bc8c219872ae1533934ddd62c38e8a4d37b0.zip
(vc-directory): Kill existing vc-dired buffers for this directory.
Provide a better header. Corrected the check whether any files were found at all (don't display a listing in this case). Under CVS, display cvs-status rather than vc-locking-user. (vc-next-action-on-file): When doing a check-in in vc-dired-mode, find the file in another window. (vc-next-action-dired): Update dired listing while processing the files. (vc-next-action): Check whether a check-in comment is really needed for this mass operation. (vc-checkout): Resynch the buffer, even if it's not current. (vc-dired-state-info, vc-dired-update-line): New functions. (vc-dired-prefix-map): Added local definition for `g' and `='. (vc-dired-reformat-line): Simplified. Erase the hardlink count from the listing, because it doesn't relate to version control. (vc-rcs-release, vc-cvs-release, vc-sccs-release): New variables, may be set by the user. (vc-backend-release, vc-release-greater-or-equal, vc-backend-release-p): New Functions. (vc-do-command): Allow FILE to be nil. (vc-backend-checkin): When creating a branch, don't bother to unlock the old version if this is RCS 5.6.2 or higher. (vc-next-action-on-file): Allow lock-stealing only if RCS 5.6.2 or higher. (vc-backend-admin, vc-backend-checkin): If available, use ci -i and -j. Updated Developer's Notes.
-rw-r--r--lisp/vc.el314
1 files changed, 231 insertions, 83 deletions
diff --git a/lisp/vc.el b/lisp/vc.el
index 7d2d6092576..eda2225c1bf 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -35,8 +35,11 @@
35;; in Jan-Feb 1994. 35;; in Jan-Feb 1994.
36;; 36;;
37;; Supported version-control systems presently include SCCS, RCS, and CVS. 37;; Supported version-control systems presently include SCCS, RCS, and CVS.
38;; The RCS lock-stealing code doesn't work right unless you use RCS 5.6.2 38;;
39;; or newer. Currently (January 1994) that is only a beta test release. 39;; Some features will not work with old RCS versions. Where
40;; appropriate, VC finds out which version you have, and allows or
41;; disallows those features (stealing locks, for example, works only
42;; from 5.6.2 onwards).
40;; Even initial checkins will fail if your RCS version is so old that ci 43;; Even initial checkins will fail if your RCS version is so old that ci
41;; doesn't understand -t-; this has been known to happen to people running 44;; doesn't understand -t-; this has been known to happen to people running
42;; NExTSTEP 3.0. 45;; NExTSTEP 3.0.
@@ -149,6 +152,18 @@ is sensitive to blank lines.")
149Verify that the file really is not locked 152Verify that the file really is not locked
150and that its contents match what the master file says.") 153and that its contents match what the master file says.")
151 154
155(defvar vc-rcs-release nil
156 "*The release number of your RCS installation, as a string.
157If nil, VC itself computes this value when it is first needed.")
158
159(defvar vc-sccs-release nil
160 "*The release number of your SCCS installation, as a string.
161If nil, VC itself computes this value when it is first needed.")
162
163(defvar vc-cvs-release nil
164 "*The release number of your SCCS installation, as a string.
165If nil, VC itself computes this value when it is first needed.")
166
152;; Variables the user doesn't need to know about. 167;; Variables the user doesn't need to know about.
153(defvar vc-log-entry-mode nil) 168(defvar vc-log-entry-mode nil)
154(defvar vc-log-operation nil) 169(defvar vc-log-operation nil)
@@ -193,6 +208,70 @@ and that its contents match what the master file says.")
193(if (not (fboundp 'file-regular-p)) 208(if (not (fboundp 'file-regular-p))
194 (fset 'file-regular-p 'file-regular-p-18)) 209 (fset 'file-regular-p 'file-regular-p-18))
195 210
211;;; Find and compare backend releases
212
213(defun vc-backend-release (backend)
214 ;; Returns which backend release is installed on this system.
215 (cond
216 ((eq backend 'RCS)
217 (or vc-rcs-release
218 (and (zerop (vc-do-command nil 2 "rcs" nil nil "-V"))
219 (save-excursion
220 (set-buffer (get-buffer "*vc*"))
221 (setq vc-rcs-release
222 (car (vc-parse-buffer
223 '(("^RCS version \\([0-9.]+ *.*\\)" 1)))))))
224 (setq vc-rcs-release 'unknown)))
225 ((eq backend 'CVS)
226 (or vc-cvs-release
227 (and (zerop (vc-do-command nil 1 "cvs" nil nil "-v"))
228 (save-excursion
229 (set-buffer (get-buffer "*vc*"))
230 (setq vc-cvs-release
231 (car (vc-parse-buffer
232 '(("^Concurrent Versions System (CVS) \\([0-9.]+\\)"
233 1)))))))
234 (setq vc-cvs-release 'unknown)))
235 ((eq backend 'SCCS)
236 vc-sccs-release)))
237
238(defun vc-release-greater-or-equal (r1 r2)
239 ;; Compare release numbers, represented as strings.
240 ;; Release components are assumed cardinal numbers, not decimal
241 ;; fractions (5.10 is a higher release than 5.9). Omitted fields
242 ;; are considered lower (5.6.7 is earlier than 5.6.7.1).
243 ;; Comparison runs till the end of the string is found, or a
244 ;; non-numeric component shows up (5.6.7 is earlier than "5.6.7 beta",
245 ;; which is probably not what you want in some cases).
246 ;; This code is suitable for existing RCS release numbers.
247 ;; CVS releases are handled reasonably, too (1.3 < 1.4* < 1.5).
248 (let (v1 v2 i1 i2)
249 (catch 'done
250 (or (and (string-match "^\\.?\\([0-9]+\\)" r1)
251 (setq i1 (match-end 0))
252 (setq v1 (string-to-number (match-string 1 r1)))
253 (or (and (string-match "^\\.?\\([0-9]+\\)" r2)
254 (setq i2 (match-end 0))
255 (setq v2 (string-to-number (match-string 1 r2)))
256 (if (> v1 v2) (throw 'done t)
257 (if (< v1 v2) (throw 'done nil)
258 (throw 'done
259 (vc-release-greater-or-equal
260 (substring r1 i1)
261 (substring r2 i2)))))))
262 (throw 'done t)))
263 (or (and (string-match "^\\.?\\([0-9]+\\)" r2)
264 (throw 'done nil))
265 (throw 'done t)))))
266
267(defun vc-backend-release-p (backend release)
268 ;; Return t if we have RELEASE of BACKEND or better
269 (let (i r (ri 0) (ii 0) is rs (installation (vc-backend-release backend)))
270 (if (not (eq installation 'unknown))
271 (cond
272 ((or (eq backend 'RCS) (eq backend 'CVS))
273 (vc-release-greater-or-equal installation release))))))
274
196;;; functions that operate on RCS revision numbers 275;;; functions that operate on RCS revision numbers
197 276
198(defun vc-trunk-p (rev) 277(defun vc-trunk-p (rev)
@@ -300,7 +379,7 @@ The command is successful if its exit status does not exceed OKSTATUS.
300The last argument of the command is the master name of FILE if LAST is 379The last argument of the command is the master name of FILE if LAST is
301`MASTER', or the workfile of FILE if LAST is `WORKFILE'; this is appended 380`MASTER', or the workfile of FILE if LAST is `WORKFILE'; this is appended
302to an optional list of FLAGS." 381to an optional list of FLAGS."
303 (setq file (expand-file-name file)) 382 (and file (setq file (expand-file-name file)))
304 (if (not buffer) (setq buffer "*vc*")) 383 (if (not buffer) (setq buffer "*vc*"))
305 (if vc-command-messages 384 (if vc-command-messages
306 (message "Running %s on %s..." command file)) 385 (message "Running %s on %s..." command file))
@@ -567,6 +646,9 @@ to an optional list of FLAGS."
567 (not (string-equal owner (user-login-name)))) 646 (not (string-equal owner (user-login-name))))
568 (if comment 647 (if comment
569 (error "Sorry, you can't steal the lock on %s this way" file)) 648 (error "Sorry, you can't steal the lock on %s this way" file))
649 (and (eq vc-type 'RCS)
650 (not (vc-backend-release-p 'RCS "5.6.2"))
651 (error "File is locked by %s." owner))
570 (vc-steal-lock 652 (vc-steal-lock
571 file 653 file
572 (if verbose (read-string "Version to steal: ") 654 (if verbose (read-string "Version to steal: ")
@@ -575,7 +657,9 @@ to an optional list of FLAGS."
575 657
576 ;; OK, user owns the lock on the file 658 ;; OK, user owns the lock on the file
577 (t 659 (t
578 (find-file file) 660 (if vc-dired-mode
661 (find-file-other-window file)
662 (find-file file))
579 663
580 ;; give luser a chance to save before checking in. 664 ;; give luser a chance to save before checking in.
581 (vc-buffer-sync) 665 (vc-buffer-sync)
@@ -602,18 +686,19 @@ to an optional list of FLAGS."
602 ))))) 686 )))))
603 687
604(defun vc-next-action-dired (file rev comment) 688(defun vc-next-action-dired (file rev comment)
605 ;; We've accepted a log comment, now do a vc-next-action using it on all 689 ;; Do a vc-next-action-on-file on all the marked files, possibly
606 ;; marked files. 690 ;; passing on the log comment we've just entered.
607 (let ((configuration (current-window-configuration))) 691 (let ((configuration (current-window-configuration))
692 (dired-buffer (current-buffer)))
608 (dired-map-over-marks 693 (dired-map-over-marks
609 (save-window-excursion 694 (let ((file (dired-get-filename)) p)
610 (let ((file (dired-get-filename))) 695 (message "Processing %s..." file)
611 (message "Processing %s..." file) 696 (vc-next-action-on-file file nil comment)
612 (vc-next-action-on-file file nil comment) 697 (set-buffer dired-buffer)
613 (message "Processing %s...done" file))) 698 (vc-dired-update-line file)
614 nil t) 699 (set-window-configuration configuration)
615 (set-window-configuration configuration)) 700 (message "Processing %s...done" file))
616 ) 701 nil t)))
617 702
618;; Here's the major entry point. 703;; Here's the major entry point.
619 704
@@ -662,9 +747,18 @@ merge in the changes into your working copy."
662 (let ((files (dired-get-marked-files))) 747 (let ((files (dired-get-marked-files)))
663 (if (= (length files) 1) 748 (if (= (length files) 1)
664 (find-file-other-window (car files)) 749 (find-file-other-window (car files))
665 (vc-start-entry nil nil nil 750 (if (string= ""
666 "Enter a change comment for the marked files." 751 (mapconcat
667 'vc-next-action-dired) 752 (function (lambda (f)
753 (if (eq (vc-backend f) 'CVS)
754 (if (eq (vc-cvs-status f) 'locally-modified)
755 "@" "")
756 (if (vc-locking-user f) "@" ""))))
757 files ""))
758 (vc-next-action-dired nil nil "dummy")
759 (vc-start-entry nil nil nil
760 "Enter a change comment for the marked files."
761 'vc-next-action-dired))
668 (throw 'nogo nil)))) 762 (throw 'nogo nil))))
669 (while vc-parent-buffer 763 (while vc-parent-buffer
670 (pop-to-buffer vc-parent-buffer)) 764 (pop-to-buffer vc-parent-buffer))
@@ -728,7 +822,7 @@ merge in the changes into your working copy."
728 (kill-buffer (current-buffer))))) 822 (kill-buffer (current-buffer)))))
729 823
730(defun vc-resynch-buffer (file &optional keep noquery) 824(defun vc-resynch-buffer (file &optional keep noquery)
731 ;; if FILE is currently visited, resynch it's buffer 825 ;; if FILE is currently visited, resynch its buffer
732 (let ((buffer (get-file-buffer file))) 826 (let ((buffer (get-file-buffer file)))
733 (if buffer 827 (if buffer
734 (save-excursion 828 (save-excursion
@@ -781,9 +875,7 @@ level to check it in under. COMMENT, if specified, is the checkin comment."
781 (if (and (string-match "^/[^/:]+:" file) (vc-find-binary "ftp")) 875 (if (and (string-match "^/[^/:]+:" file) (vc-find-binary "ftp"))
782 (error "Sorry, you can't check out files over FTP")) 876 (error "Sorry, you can't check out files over FTP"))
783 (vc-backend-checkout file writable rev) 877 (vc-backend-checkout file writable rev)
784 (if (string-equal file buffer-file-name) 878 (vc-resynch-buffer file t t))
785 (vc-resynch-window file t t))
786 )
787 879
788(defun vc-steal-lock (file rev &optional owner) 880(defun vc-steal-lock (file rev &optional owner)
789 "Steal the lock on the current workfile." 881 "Steal the lock on the current workfile."
@@ -1138,6 +1230,8 @@ the variable `vc-header-alist'."
1138 1230
1139(defvar vc-dired-prefix-map (make-sparse-keymap)) 1231(defvar vc-dired-prefix-map (make-sparse-keymap))
1140(define-key vc-dired-prefix-map "\C-xv" vc-prefix-map) 1232(define-key vc-dired-prefix-map "\C-xv" vc-prefix-map)
1233(define-key vc-dired-prefix-map "g" 'vc-directory)
1234(define-key vc-dired-prefix-map "=" 'vc-diff)
1141 1235
1142(or (not (boundp 'minor-mode-map-alist)) 1236(or (not (boundp 'minor-mode-map-alist))
1143 (assq 'vc-dired-mode minor-mode-map-alist) 1237 (assq 'vc-dired-mode minor-mode-map-alist)
@@ -1154,6 +1248,20 @@ on a buffer attached to the file named in the current Dired buffer line."
1154 (setq vc-dired-mode t) 1248 (setq vc-dired-mode t)
1155 (setq vc-mode " under VC")) 1249 (setq vc-mode " under VC"))
1156 1250
1251(defun vc-dired-state-info (file)
1252 ;; Return the string that indicates the version control status
1253 ;; on a VC dired line.
1254 (let ((cvs-state (and (eq (vc-backend file) 'CVS)
1255 (vc-cvs-status file))))
1256 (if cvs-state
1257 (cond ((eq cvs-state 'up-to-date) nil)
1258 ((eq cvs-state 'needs-checkout) "patch")
1259 ((eq cvs-state 'locally-modified) "modified")
1260 ((eq cvs-state 'needs-merge) "merge")
1261 ((eq cvs-state 'unresolved-conflict) "conflict")
1262 ((eq cvs-state 'locally-added) "added"))
1263 (vc-locking-user file))))
1264
1157(defun vc-dired-reformat-line (x) 1265(defun vc-dired-reformat-line (x)
1158 ;; Hack a directory-listing line, plugging in locking-user info in 1266 ;; Hack a directory-listing line, plugging in locking-user info in
1159 ;; place of the user and group info. Should have the beneficial 1267 ;; place of the user and group info. Should have the beneficial
@@ -1165,26 +1273,22 @@ on a buffer attached to the file named in the current Dired buffer line."
1165 ;; (insert (concat x "\t"))) 1273 ;; (insert (concat x "\t")))
1166 ;; 1274 ;;
1167 ;; This code, like dired, assumes UNIX -l format. 1275 ;; This code, like dired, assumes UNIX -l format.
1168 (forward-word 1) ;; skip over any extra field due to -ibs options
1169 (cond 1276 (cond
1170 ;; This hack is used by the CVS code. See vc-locking-user. 1277 ((re-search-forward
1171 ((numberp x) 1278 "\\([drwx-]+ \\) *[0-9]+ \\([^ ]+\\) +[0-9]+\\( .*\\)"
1172 (cond 1279 nil 0)
1173 ((re-search-forward "\\([0-9]+ \\)\\([^ ]+\\)\\( .*\\)" nil 0) 1280 (if (numberp x) (setq x (match-string 2)))
1174 (save-excursion
1175 (goto-char (match-beginning 2))
1176 (insert "(")
1177 (goto-char (1+ (match-end 2)))
1178 (insert ")")
1179 (delete-char (- 17 (- (match-end 2) (match-beginning 2))))
1180 (insert (substring " " 0
1181 (- 7 (- (match-end 2) (match-beginning 2)))))))))
1182 (t
1183 (if x (setq x (concat "(" x ")"))) 1281 (if x (setq x (concat "(" x ")")))
1184 (if (re-search-forward "\\([0-9]+ \\).................\\( .*\\)" nil 0) 1282 (let ((rep (substring (concat x " ") 0 10)))
1185 (let ((rep (substring (concat x " ") 0 10))) 1283 (replace-match (concat "\\1" rep "\\3"))))))
1186 (replace-match (concat "\\1" rep "\\2") t))) 1284
1187 ))) 1285(defun vc-dired-update-line (file)
1286 ;; Update the vc-dired listing line of file -- it is assumed
1287 ;; that point is already on this line.
1288 (dired-do-redisplay 1)
1289 (dired-previous-line 1)
1290 (beginning-of-line)
1291 (vc-dired-reformat-line (vc-dired-state-info file)))
1188 1292
1189;;; Note in Emacs 18 the following defun gets overridden 1293;;; Note in Emacs 18 the following defun gets overridden
1190;;; with the symbol 'vc-directory-18. See below. 1294;;; with the symbol 'vc-directory-18. See below.
@@ -1196,41 +1300,66 @@ in all these directories. With a prefix argument, it lists all files."
1196 (interactive "P") 1300 (interactive "P")
1197 (let (nonempty 1301 (let (nonempty
1198 (dl (length (expand-file-name default-directory))) 1302 (dl (length (expand-file-name default-directory)))
1199 (filelist nil) (userlist nil) 1303 (filelist nil) (statelist nil)
1200 dired-buf 1304 dired-buf
1201 dired-buf-mod-count) 1305 dired-buf-mod-count)
1202 (vc-file-tree-walk 1306 (vc-file-tree-walk
1203 (function (lambda (f) 1307 (function
1204 (if (vc-registered f) 1308 (lambda (f)
1205 (let ((user (vc-locking-user f))) 1309 (if (vc-registered f)
1206 (and (or verbose user) 1310 (let ((state (vc-dired-state-info f)))
1207 (setq filelist (cons (substring f dl) filelist)) 1311 (and (or verbose state)
1208 (setq userlist (cons user userlist)))))))) 1312 (setq filelist (cons (substring f dl) filelist))
1209 (save-excursion 1313 (setq statelist (cons state statelist))))))))
1210 ;; This uses a semi-documented feature of dired; giving a switch 1314 (save-window-excursion
1211 ;; argument forces the buffer to refresh each time. 1315 (save-excursion
1212 (dired 1316 ;; First, kill any existing vc-dired buffers of this directory.
1213 (cons default-directory (nreverse filelist)) 1317 ;; (Code much like dired-find-buffer-nocreate.)
1214 dired-listing-switches) 1318 (let ((buffers (buffer-list))
1215 (setq dired-buf (current-buffer)) 1319 (dir (expand-file-name default-directory)))
1216 (setq nonempty (not (zerop (buffer-size))))) 1320 (while buffers
1321 (if (buffer-name (car buffers))
1322 (progn (set-buffer (car buffers))
1323 (if (and (eq major-mode 'dired-mode)
1324 (string= dir
1325 (expand-file-name default-directory))
1326 vc-dired-mode)
1327 (kill-buffer (car buffers)))))
1328 (setq buffers (cdr buffers)))
1329 ;; This uses a semi-documented feature of dired; giving a switch
1330 ;; argument forces the buffer to refresh each time.
1331 (dired
1332 (cons dir (nreverse filelist))
1333 dired-listing-switches)
1334 (setq dired-buf (current-buffer))
1335 (setq nonempty (not (eq 2 (count-lines (point-min)
1336 (point-max))))))))
1217 (if nonempty 1337 (if nonempty
1218 (progn 1338 (progn
1219 (pop-to-buffer dired-buf) 1339 (switch-to-buffer dired-buf)
1220 (vc-dired-mode) 1340 (vc-dired-mode)
1221 (goto-char (point-min)) 1341 ;; Make a few aesthetical modifications to the header
1222 (setq buffer-read-only nil) 1342 (setq buffer-read-only nil)
1223 (forward-line 1) ;; Skip header line 1343 (goto-char (point-min))
1344 (insert "\n") ;; Insert a blank line
1345 (forward-line 1) ;; Skip header line
1346 (let ((start (point))) ;; Erase (but don't remove) the
1347 (end-of-line) ;; "wildcard" line.
1348 (delete-region start (point)))
1349 (beginning-of-line)
1350 ;; Now plug the version information into the individual lines
1224 (mapcar 1351 (mapcar
1225 (function 1352 (function
1226 (lambda (x) 1353 (lambda (x)
1227 (forward-char 2) ;; skip dired's mark area 1354 (forward-char 2) ;; skip dired's mark area
1228 (vc-dired-reformat-line x) 1355 (vc-dired-reformat-line x)
1229 (forward-line 1))) ;; go to next line 1356 (forward-line 1))) ;; go to next line
1230 (nreverse userlist)) 1357 (nreverse statelist))
1231 (setq buffer-read-only t) 1358 (setq buffer-read-only t)
1232 (goto-char (point-min)) 1359 (goto-char (point-min))
1360 (dired-next-line 3)
1233 ) 1361 )
1362 (kill-buffer dired-buf)
1234 (message "No files are currently %s under %s" 1363 (message "No files are currently %s under %s"
1235 (if verbose "registered" "locked") default-directory)) 1364 (if verbose "registered" "locked") default-directory))
1236 )) 1365 ))
@@ -1619,6 +1748,8 @@ From a program, any arguments are passed to the `rcs2log' script."
1619 (vc-do-command nil 0 "get" file 'MASTER))) 1748 (vc-do-command nil 0 "get" file 'MASTER)))
1620 ((eq backend 'RCS) 1749 ((eq backend 'RCS)
1621 (vc-do-command nil 0 "ci" file 'MASTER ;; RCS 1750 (vc-do-command nil 0 "ci" file 'MASTER ;; RCS
1751 ;; if available, use the secure registering option
1752 (and (vc-backend-release-p 'RCS "5.6.4") "-i")
1622 (concat (if vc-keep-workfiles "-u" "-r") rev) 1753 (concat (if vc-keep-workfiles "-u" "-r") rev)
1623 (and comment (concat "-t-" comment)) 1754 (and comment (concat "-t-" comment))
1624 file)) 1755 file))
@@ -1825,6 +1956,8 @@ From a program, any arguments are passed to the `rcs2log' script."
1825 ;; RCS 1956 ;; RCS
1826 (let ((old-version (vc-workfile-version file)) new-version) 1957 (let ((old-version (vc-workfile-version file)) new-version)
1827 (apply 'vc-do-command nil 0 "ci" file 'MASTER 1958 (apply 'vc-do-command nil 0 "ci" file 'MASTER
1959 ;; if available, use the secure check-in option
1960 (and (vc-backend-release-p 'RCS "5.6.4") "-j")
1828 (concat (if vc-keep-workfiles "-u" "-r") rev) 1961 (concat (if vc-keep-workfiles "-u" "-r") rev)
1829 (concat "-m" comment) 1962 (concat "-m" comment)
1830 vc-checkin-switches) 1963 vc-checkin-switches)
@@ -1843,8 +1976,7 @@ From a program, any arguments are passed to the `rcs2log' script."
1843 (vc-file-setprop file 'vc-workfile-version new-version))) 1976 (vc-file-setprop file 'vc-workfile-version new-version)))
1844 1977
1845 ;; if we got to a different branch, adjust the default 1978 ;; if we got to a different branch, adjust the default
1846 ;; branch accordingly, and remove any remaining 1979 ;; branch accordingly
1847 ;; lock on the old version.
1848 (cond 1980 (cond
1849 ((and old-version new-version 1981 ((and old-version new-version
1850 (not (string= (vc-branch-part old-version) 1982 (not (string= (vc-branch-part old-version)
@@ -1852,10 +1984,13 @@ From a program, any arguments are passed to the `rcs2log' script."
1852 (vc-do-command nil 0 "rcs" file 'MASTER 1984 (vc-do-command nil 0 "rcs" file 'MASTER
1853 (if (vc-trunk-p new-version) "-b" 1985 (if (vc-trunk-p new-version) "-b"
1854 (concat "-b" (vc-branch-part new-version)))) 1986 (concat "-b" (vc-branch-part new-version))))
1855 ;; exit status of 1 is also accepted. 1987 ;; If this is an old RCS release, we might have
1856 ;; It means that the lock was removed before. 1988 ;; to remove a remaining lock.
1857 (vc-do-command nil 1 "rcs" file 'MASTER 1989 (if (not (vc-backend-release-p 'RCS "5.6.2"))
1858 (concat "-u" old-version))))) 1990 ;; exit status of 1 is also accepted.
1991 ;; It means that the lock was removed before.
1992 (vc-do-command nil 1 "rcs" file 'MASTER
1993 (concat "-u" old-version))))))
1859 ;; CVS 1994 ;; CVS
1860 (progn 1995 (progn
1861 ;; explicit check-in to the trunk requires a 1996 ;; explicit check-in to the trunk requires a
@@ -1991,18 +2126,20 @@ From a program, any arguments are passed to the `rcs2log' script."
1991 (if cmp (cdr options) options)) 2126 (if cmp (cdr options) options))
1992 status))) 2127 status)))
1993 ;; CVS is different. 2128 ;; CVS is different.
1994 ;; cmp is not yet implemented -- we always do a full diff.
1995 ((eq backend 'CVS) 2129 ((eq backend 'CVS)
1996 (if (string= (vc-workfile-version file) "0") ;CVS 2130 (if (string= (vc-workfile-version file) "0") ;CVS
1997 ;; This file is added but not yet committed; there is no master file. 2131 ;; This file is added but not yet committed; there is no master file.
1998 ;; diff it against /dev/null.
1999 (if (or oldvers newvers) 2132 (if (or oldvers newvers)
2000 (error "No revisions of %s exists" file) 2133 (error "No revisions of %s exist" file)
2001 (apply 'vc-do-command 2134 (if cmp 1 ;; file is added but not committed,
2002 "*vc-diff*" 1 "diff" file 'WORKFILE "/dev/null" 2135 ;; we regard this as "changed".
2003 (if (listp diff-switches) 2136 ;; diff it against /dev/null.
2004 diff-switches 2137 (apply 'vc-do-command
2005 (list diff-switches)))) 2138 "*vc-diff*" 1 "diff" file 'WORKFILE
2139 (append (if (listp diff-switches)
2140 diff-switches
2141 (list diff-switches)) '("/dev/null")))))
2142 ;; cmp is not yet implemented -- we always do a full diff.
2006 (apply 'vc-do-command 2143 (apply 'vc-do-command
2007 "*vc-diff*" 1 "cvs" file 'WORKFILE "diff" 2144 "*vc-diff*" 1 "cvs" file 'WORKFILE "diff"
2008 (and oldvers (concat "-r" oldvers)) 2145 (and oldvers (concat "-r" oldvers))
@@ -2232,7 +2369,7 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2232;;; B 5 . 6 7 8 co -l get -e checkout 2369;;; B 5 . 6 7 8 co -l get -e checkout
2233;;; C 9 10 . 11 12 co -u unget; get revert 2370;;; C 9 10 . 11 12 co -u unget; get revert
2234;;; D 13 14 15 . 16 ci -u -m<comment> delta -y<comment>; get checkin 2371;;; D 13 14 15 . 16 ci -u -m<comment> delta -y<comment>; get checkin
2235;;; E 17 18 19 20 . rcs -u -M ; rcs -l unget -n ; get -g steal lock 2372;;; E 17 18 19 20 . rcs -u -M -l unget -n ; get -g steal lock
2236;;; 2373;;;
2237;;; All commands take the master file name as a last argument (not shown). 2374;;; All commands take the master file name as a last argument (not shown).
2238;;; 2375;;;
@@ -2290,7 +2427,9 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2290;;; Potential cause: someone else's admin during window P, with 2427;;; Potential cause: someone else's admin during window P, with
2291;;; caller's admin happening before their checkout. 2428;;; caller's admin happening before their checkout.
2292;;; 2429;;;
2293;;; RCS: ci will fail with a "no lock set by <user>" message. 2430;;; RCS: Prior to version 5.6.4, ci fails with message
2431;;; "no lock set by <user>". From 5.6.4 onwards, VC uses the new
2432;;; ci -i option and the message is "<file>,v: already exists".
2294;;; SCCS: admin will fail with error (ad19). 2433;;; SCCS: admin will fail with error (ad19).
2295;;; 2434;;;
2296;;; We can let these errors be passed up to the user. 2435;;; We can let these errors be passed up to the user.
@@ -2299,7 +2438,9 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2299;;; 2438;;;
2300;;; Potential cause: self-race during window P. 2439;;; Potential cause: self-race during window P.
2301;;; 2440;;;
2302;;; RCS: will revert the file to the last saved version and unlock it. 2441;;; RCS: Prior to version 5.6.4, reverts the file to the last saved
2442;;; version and unlocks it. From 5.6.4 onwards, VC uses the new
2443;;; ci -i option, failing with message "<file>,v: already exists".
2303;;; SCCS: will fail with error (ad19). 2444;;; SCCS: will fail with error (ad19).
2304;;; 2445;;;
2305;;; Either of these consequences is acceptable. 2446;;; Either of these consequences is acceptable.
@@ -2308,8 +2449,10 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2308;;; 2449;;;
2309;;; Potential cause: self-race during window P. 2450;;; Potential cause: self-race during window P.
2310;;; 2451;;;
2311;;; RCS: will register the caller's workfile as a delta with a 2452;;; RCS: Prior to version 5.6.4, VC registers the caller's workfile as
2312;;; null change comment (the -t- switch will be ignored). 2453;;; a delta with a null change comment (the -t- switch will be
2454;;; ignored). From 5.6.4 onwards, VC uses the new ci -i option,
2455;;; failing with message "<file>,v: already exists".
2313;;; SCCS: will fail with error (ad19). 2456;;; SCCS: will fail with error (ad19).
2314;;; 2457;;;
2315;;; 4. File looked unregistered but is locked by someone else. 2458;;; 4. File looked unregistered but is locked by someone else.
@@ -2317,7 +2460,10 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2317;;; Potential cause: someone else's admin during window P, with 2460;;; Potential cause: someone else's admin during window P, with
2318;;; caller's admin happening *after* their checkout. 2461;;; caller's admin happening *after* their checkout.
2319;;; 2462;;;
2320;;; RCS: will fail with a "no lock set by <user>" message. 2463;;; RCS: Prior to version 5.6.4, ci fails with a
2464;;; "no lock set by <user>" message. From 5.6.4 onwards,
2465;;; VC uses the new ci -i option, failing with message
2466;;; "<file>,v: already exists".
2321;;; SCCS: will fail with error (ad19). 2467;;; SCCS: will fail with error (ad19).
2322;;; 2468;;;
2323;;; We can let these errors be passed up to the user. 2469;;; We can let these errors be passed up to the user.
@@ -2405,11 +2551,13 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2405;;; 2551;;;
2406;;; Potential cause: master file got nuked during window P. 2552;;; Potential cause: master file got nuked during window P.
2407;;; 2553;;;
2408;;; RCS: Checks in the user's version as an initial delta. 2554;;; RCS: Prior to version 5.6.4, checks in the user's version as an
2555;;; initial delta. From 5.6.4 onwards, VC uses the new ci -j
2556;;; option, failing with message "no such file or directory".
2409;;; SCCS: will fail with error ut4. 2557;;; SCCS: will fail with error ut4.
2410;;; 2558;;;
2411;;; This case is kind of nasty. It means VC may fail to detect the 2559;;; This case is kind of nasty. Under RCS prior to version 5.6.4,
2412;;; loss of previous version information. 2560;;; VC may fail to detect the loss of previous version information.
2413;;; 2561;;;
2414;;; 14. File looks like it's locked by the calling user and changed, but it's 2562;;; 14. File looks like it's locked by the calling user and changed, but it's
2415;;; actually unlocked. 2563;;; actually unlocked.
@@ -2476,7 +2624,7 @@ Invoke FUNC f ARGS on each non-directory file f underneath it."
2476;;; 2624;;;
2477;;; In order of decreasing severity: 2625;;; In order of decreasing severity:
2478;;; 2626;;;
2479;;; Cases 11 and 15 under RCS are the only one that potentially lose work. 2627;;; Cases 11 and 15 are the only ones that potentially lose work.
2480;;; They would require a self-race for this to happen. 2628;;; They would require a self-race for this to happen.
2481;;; 2629;;;
2482;;; Case 13 in RCS loses information about previous deltas, retaining 2630;;; Case 13 in RCS loses information about previous deltas, retaining