Mercurial > emacs
changeset 9249:909ae53a446d
(vc-backend-checkin): When CVS checks in a file, it is
immediately checked out again, so set vc-checkout-time.
(vc-fetch-properties): CVS 1.4A1 says "Repository revision".
(vc-locking-user): Do something sensible when the backend
is CVS. May return a numerical UID or a string when CVS is used.
(vc-dired-reformat-line): Handle numerical arguments.
(vc-backend-checkout): Don't extract CVS files twice.
(vc-next-action-on-file): Handle return value from
vc-backend-merge-news correctly.
(vc-rename-file): Fixed call to vc-backend-dispatch.
(vc-make-buffer-writable-hook): New hook, for CVS only.
(vc-header-alist): Added header for CVS.
(vc-next-action-on-file): Added support for CVS.
(vc-next-action, vc-checkin, vc-revert-buffer): Doc fixes.
(vc-rename-file): Disable if the backend is CVS.
(vc-log-info): New arguments: LAST and FLAGS, passed on to
vc-do-command. All callers updated.
(vc-fetch-properties): Implement support for CVS files.
(vc-backend-checkin): Args REV and COMMENT no longer optional.
Implement support for CVS.
(vc-backend-revert): Implement support for CVS.
(vc-backend-diff): Treat files which are added, but not yet committed,
specially (diff them against /dev/null).
(vc-backend-merge-news): New function.
(vc-log-mode): Talk a little about CVS in the comment.
(vc-log-info): Simplify code.
(vc-do-command): New argument LAST. All callers updated.
Legal values for LAST are 'MASTER and 'BASE.
(vc-backend-dispatch): New argument C, used by CVS. All callers
updated, but many just passes an (error "NYI") form.
(vc-backend-admin): Issue a "cvs add" (but not a "cvs commit").
(vc-backend-checkout, vc-backend-logentry-check, vc-backend-print-log,
vc-backend-assign-name, vc-backend-diff, vc-check-headers): Handle CVS.
(vc-backend-steal, vc-backend-uncheck): Give error if using CVS.
(vc-backend-diff): Fixed typo in SCCS code.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 03 Oct 1994 21:57:47 +0000 |
parents | 325cee61ab7f |
children | 7cf726dccf2e |
files | lisp/vc.el |
diffstat | 1 files changed, 327 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/vc.el Mon Oct 03 21:56:50 1994 +0000 +++ b/lisp/vc.el Mon Oct 03 21:57:47 1994 +0000 @@ -4,7 +4,7 @@ ;; Author: Eric S. Raymond <esr@snark.thyrsus.com> ;; Maintainer: eggert@twinsun.com -;; Version: 5.5 +;; Version: 5.5 + CVS hacks by ceder@lysator.liu.se made in Jan-Feb 1994. ;; This file is part of GNU Emacs. @@ -76,7 +76,9 @@ (defvar vc-suppress-confirm nil "*If non-nil, treat user as expert; suppress yes-no prompts on some things.") (defvar vc-keep-workfiles t - "*If non-nil, don't delete working files after registering changes.") + "*If non-nil, don't delete working files after registering changes. +If the back-end is CVS, workfiles are always kept, regardless of the +value of this flag.") (defvar vc-initial-comment nil "*Prompt for initial comment when a file is registered.") (defvar vc-command-messages nil @@ -101,10 +103,16 @@ (defvar vc-checkin-hook nil "*List of functions called after a checkin is done. See `run-hooks'.") +(defvar vc-make-buffer-writable-hook nil + "*List of functions called when a buffer is made writable. See `run-hooks.' +This hook is only used when the version control system is CVS. It +might be useful for sites who uses locking with CVS, or who uses link +farms to gold trees.") + ;; Header-insertion hair (defvar vc-header-alist - '((SCCS "\%W\%") (RCS "\$Id\$")) + '((SCCS "\%W\%") (RCS "\$Id\$") (CVS "\$Id\$")) "*Header keywords to be inserted when `vc-insert-headers' is executed.") (defvar vc-static-header-alist '(("\\.c$" . @@ -189,11 +197,12 @@ exec-path) nil))) -(defun vc-do-command (okstatus command file &rest flags) +(defun vc-do-command (okstatus command file last &rest flags) "Execute a version-control command, notifying user and checking for errors. The command is successful if its exit status does not exceed OKSTATUS. Output from COMMAND goes to buffer *vc*. The last argument of the command is -the master name of FILE; this is appended to an optional list of FLAGS." +the master name of FILE if LAST is 'MASTER, or the basename of FILE if LAST is +'BASE; this is appended to an optional list of FLAGS." (setq file (expand-file-name file)) (if vc-command-messages (message "Running %s on %s..." command file)) @@ -215,8 +224,10 @@ (mapcar (function (lambda (s) (and s (setq squeezed (append squeezed (list s)))))) flags) - (if vc-file + (if (and vc-file (eq last 'MASTER)) (setq squeezed (append squeezed (list vc-file)))) + (if (eq last 'BASE) + (setq squeezed (append squeezed (list (file-name-nondirectory file))))) (let ((default-directory (file-name-directory (or file "./"))) (exec-path (if vc-path (append exec-path vc-path) exec-path)) ;; Add vc-path to PATH for the execution of this command. @@ -367,7 +378,9 @@ (defun vc-next-action-on-file (file verbose &optional comment) ;;; If comment is specified, it will be used as an admin or checkin comment. - (let (owner version (vc-file (vc-name file))) + (let ((vc-file (vc-name file)) + (vc-type (vc-backend-deduce file)) + owner version) (cond ;; if there is no master file corresponding, create one @@ -375,7 +388,8 @@ (vc-register verbose comment)) ;; if there is no lock on the file, assert one and get it - ((not (setq owner (vc-locking-user file))) + ((and (not (eq vc-type 'CVS)) ;There are no locks in CVS. + (not (setq owner (vc-locking-user file)))) (if (and vc-checkout-carefully (not (vc-workfile-unchanged-p file t))) (if (save-window-excursion @@ -397,15 +411,51 @@ (vc-checkout-writable-buffer file))) ;; a checked-out version exists, but the user may not own the lock - ((not (string-equal owner (user-login-name))) + ((and (not (eq vc-type 'CVS)) ;There are no locks in CVS. + (not (string-equal owner (user-login-name)))) (if comment (error "Sorry, you can't steal the lock on %s this way" file)) (vc-steal-lock file (and verbose (read-string "Version to steal: ")) owner)) - - ;; OK, user owns the lock on the file + + ;; changes to the master file needs to be merged back into the + ;; working file + ((and (eq vc-type 'CVS) + ;; "0" means "added, but not yet committed" + (not (string= (vc-file-getprop file 'vc-your-latest-version) "0")) + (progn + (vc-fetch-properties file) + (not (string= (vc-file-getprop file 'vc-your-latest-version) + (vc-file-getprop file 'vc-latest-version))))) + (vc-buffer-sync) + (if (yes-or-no-p (format "%s is not up-to-date. Merge in changes now? " + (buffer-name))) + (progn + (if (and (buffer-modified-p) + (not (yes-or-no-p + "Buffer %s modified; merge file on disc anyhow? " + (buffer-name)))) + (error "Merge aborted")) + (if (not (zerop (vc-backend-merge-news file))) + ;; Overlaps detected - what now? Should use some + ;; fancy RCS conflict resolving package, or maybe + ;; emerge, but for now, simply warn the user with a + ;; message. + (message "Conflicts detected!")) + (vc-resynch-window file t (not (buffer-modified-p)))) + + (error "%s needs update" (buffer-name)))) + + ((and buffer-read-only (eq vc-type 'CVS)) + (toggle-read-only) + ;; Sites who make link farms to a read-only gold tree (or + ;; something similar) can use the hook below to break the + ;; sym-link. + (run-hooks 'vc-make-buffer-writable-hook)) + + ;; OK, user owns the lock on the file (or we are running CVS) (t (find-file file) @@ -417,12 +467,15 @@ ;; to saving it; in that case, don't revert, ;; because the user might intend to save ;; after finishing the log entry. - (if (and (vc-workfile-unchanged-p file) + (if (and (vc-workfile-unchanged-p file) (not (buffer-modified-p))) (progn - (vc-backend-revert file) - ;; DO NOT revert the file without asking the user! - (vc-resynch-window file t nil)) + (if (eq vc-type 'CVS) + (message "No changes to %s" file) + + (vc-backend-revert file) + ;; DO NOT revert the file without asking the user! + (vc-resynch-window file t nil))) ;; user may want to set nonstandard parameters (if verbose @@ -450,6 +503,8 @@ ;;;###autoload (defun vc-next-action (verbose) "Do the next logical checkin or checkout operation on the current file. + +For RCS and SCCS files: If the file is not already registered, this registers it for version control and then retrieves a writable, locked copy for editing. If the file is registered and not locked by anyone, this checks out @@ -464,6 +519,23 @@ read-only copy of the changed file is left in place afterwards. If the file is registered and locked by someone else, you are given the option to steal the lock. + +For CVS files: + If the file is not already registered, this registers it for version +control. This does a \"cvs add\", but no \"cvs commit\". + If the file is added but not committed, it is committed. + If the file has not been changed, neither in your working area or +in the repository, a message is printed and nothing is done. + If your working file is changed, but the repository file is +unchanged, this pops up a buffer for entry of a log message; when the +message has been entered, it checks in the resulting changes along +with the logmessage as change commentary. A writable file is retained. + If the repository file is changed, you are asked if you want to +merge in the changes into your working copy. + +The following is true regardless of which version control system you +are using: + If you call this from within a VC dired buffer with no files marked, it will operate on the file in the current line. If you call this from within a VC dired buffer, and one or more @@ -624,6 +696,7 @@ The optional argument REV may be a string specifying the new version level \(if nil increment the current level). The file is either retained with write permissions zeroed, or deleted (according to the value of `vc-keep-workfiles'). +If the back-end is CVS, a writable workfile is always kept. COMMENT is a comment string; if omitted, a buffer is popped up to accept a comment." (vc-start-entry file rev comment @@ -953,11 +1026,25 @@ ;; ;; This code, like dired, assumes UNIX -l format. (forward-word 1) ;; skip over any extra field due to -ibs options - (if x (setq x (concat "(" x ")"))) - (if (re-search-forward "\\([0-9]+ \\).................\\( .*\\)" nil 0) - (let ((rep (substring (concat x " ") 0 9))) - (replace-match (concat "\\1" rep "\\2") t))) - ) + (cond + ;; This hack is used by the CVS code. See vc-locking-user. + ((numberp x) + (cond + ((re-search-forward "\\([0-9]+ \\)\\([^ ]+\\)\\( .*\\)" nil 0) + (save-excursion + (goto-char (match-beginning 2)) + (insert "(") + (goto-char (1+ (match-end 2))) + (insert ")") + (delete-char (- 17 (- (match-end 2) (match-beginning 2)))) + (insert (substring " " 0 + (- 7 (- (match-end 2) (match-beginning 2))))))))) + (t + (if x (setq x (concat "(" x ")"))) + (if (re-search-forward "\\([0-9]+ \\).................\\( .*\\)" nil 0) + (let ((rep (substring (concat x " ") 0 9))) + (replace-match (concat "\\1" rep "\\2") t))) + ))) ;;; Note in Emacs 18 the following defun gets overridden ;;; with the symbol 'vc-directory-18. See below. @@ -1150,7 +1237,9 @@ (defun vc-revert-buffer () "Revert the current buffer's file back to the latest checked-in version. This asks for confirmation if the buffer contents are not identical -to that version." +to that version. +If the back-end is CVS, this will give you the most recent revision of +the file on the branch you are editing." (interactive) (if vc-dired-mode (find-file-other-window (dired-get-filename))) @@ -1198,6 +1287,14 @@ (defun vc-rename-file (old new) "Rename file OLD to NEW, and rename its master file likewise." (interactive "fVC rename file: \nFRename to: ") + ;; There are several ways of renaming files under CVS 1.3, but they all + ;; have serious disadvantages. See the FAQ (available from think.com in + ;; pub/cvs/). I'd rather send the user an error, than do something he might + ;; consider to be wrong. When the famous, long-awaited rename database is + ;; implemented things might change for the better. This is unlikely to occur + ;; until CVS 2.0 is released. --ceder 1994-01-23 21:27:51 + (if (eq (vc-backend-deduce old) 'CVS) + (error "Renaming files under CVS is dangerous and not supported in VC.")) (let ((oldbuf (get-file-buffer old))) (if (and oldbuf (buffer-modified-p oldbuf)) (error "Please save files before moving them")) @@ -1243,8 +1340,10 @@ (set-buffer-modified-p nil)))) ;; This had FILE, I changed it to OLD. -- rms. (vc-backend-dispatch old - (vc-record-rename old new) - nil) + (vc-record-rename old new) ;SCCS + nil ;RCS + nil ;CVS + ) ) ;;;###autoload @@ -1359,14 +1458,12 @@ ) ) -(defun vc-log-info (command file patterns &optional properties) +(defun vc-log-info (command file last flags patterns &optional properties) ;; Search for information in log program output (if (and file (file-exists-p file)) (save-excursion - (let ((buf)) - (setq buf (get-buffer-create "*vc*")) - (set-buffer buf)) - (apply 'vc-do-command 0 command file nil) + (set-buffer (get-buffer-create "*vc*")) + (apply 'vc-do-command 0 command file last flags) (set-buffer-modified-p nil) (prog1 (vc-parse-buffer patterns file properties) @@ -1382,32 +1479,59 @@ (defun vc-locking-user (file) "Return the name of the person currently holding a lock on FILE. -Return nil if there is no such person." - (setq file (expand-file-name file)) ;; ??? Work around bug in 19.0.4 - (if (or (not vc-keep-workfiles) - (eq vc-mistrust-permissions 't) - (and vc-mistrust-permissions - (funcall vc-mistrust-permissions (vc-backend-subdirectory-name file)))) - (vc-true-locking-user file) - ;; This implementation assumes that any file which is under version - ;; control and has -rw-r--r-- is locked by its owner. This is true - ;; for both RCS and SCCS, which keep unlocked files at -r--r--r--. - ;; We have to be careful not to exclude files with execute bits on; - ;; scripts can be under version control too. Also, we must ignore - ;; the group-read and other-read bits, since paranoid users turn them off. - ;; This hack wins because calls to the very expensive vc-fetch-properties - ;; function only have to be made if (a) the file is locked by someone - ;; other than the current user, or (b) some untoward manipulation - ;; behind vc's back has changed the owner or the `group' or `other' - ;; write bits. - (let ((attributes (file-attributes file))) - (cond ((string-match ".r-..-..-." (nth 8 attributes)) - nil) - ((and (= (nth 2 attributes) (user-uid)) - (string-match ".rw..-..-." (nth 8 attributes))) - (user-login-name)) - (t - (vc-true-locking-user file)))))) +Return nil if there is no such person. +Under CVS, a file is considered locked if it has been modified since it +was checked out. Under CVS, this will sometimes return the uid of +the owner of the file (as a number) instead of a string." + (setq file (expand-file-name file));; ??? Work around bug in 19.0.4 + (cond + ((eq (vc-backend-deduce file) 'CVS) + (if (vc-workfile-unchanged-p file t) + nil + ;; The expression below should return the username of the owner + ;; of the file. It doesn't. It returns the username if it is + ;; you, or otherwise the UID of the owner of the file. The + ;; return value from this function is only used by + ;; vc-dired-reformat-line, and it does the proper thing if a UID + ;; is returned. + ;; + ;; The *proper* way to fix this would be to implement a built-in + ;; function in Emacs, say, (username UID), that returns the + ;; username of a given UID. + ;; + ;; The result of this hack is that vc-directory will print the + ;; name of the owner of the file for any files that are + ;; modified. + (let ((uid (nth 2 (file-attributes file)))) + (if (= uid (user-uid)) + (user-login-name) + uid)))) + (t + (if (or (not vc-keep-workfiles) + (eq vc-mistrust-permissions 't) + (and vc-mistrust-permissions + (funcall vc-mistrust-permissions (vc-backend-subdirectory-name + file)))) + (vc-true-locking-user file) + ;; This implementation assumes that any file which is under version + ;; control and has -rw-r--r-- is locked by its owner. This is true + ;; for both RCS and SCCS, which keep unlocked files at -r--r--r--. + ;; We have to be careful not to exclude files with execute bits on; + ;; scripts can be under version control too. Also, we must ignore + ;; the group-read and other-read bits, since paranoid users turn them off. + ;; This hack wins because calls to the very expensive vc-fetch-properties + ;; function only have to be made if (a) the file is locked by someone + ;; other than the current user, or (b) some untoward manipulation + ;; behind vc's back has changed the owner or the `group' or `other' + ;; write bits. + (let ((attributes (file-attributes file))) + (cond ((string-match ".r-..-..-." (nth 8 attributes)) + nil) + ((and (= (nth 2 attributes) (user-uid)) + (string-match ".rw..-..-." (nth 8 attributes))) + (user-login-name)) + (t + (vc-true-locking-user file)))))))) (defun vc-true-locking-user (file) ;; The slow but reliable version @@ -1431,12 +1555,16 @@ ;; vc-backend-dispatch macro and fill it in in each call. The variable ;; vc-master-templates in vc-hooks.el will also have to change. -(defmacro vc-backend-dispatch (f s r) - "Execute FORM1 or FORM2 depending on whether we're using SCCS or RCS." +(defmacro vc-backend-dispatch (f s r c) + "Execute FORM1, FORM2 or FORM3 depending whether we're using SCCS, RCS or CVS. +If FORM3 is RCS, use FORM2 even if we are using CVS. (CVS shares some code +with RCS)." (list 'let (list (list 'type (list 'vc-backend-deduce f))) (list 'cond (list (list 'eq 'type (quote 'SCCS)) s) ;; SCCS (list (list 'eq 'type (quote 'RCS)) r) ;; RCS + (list (list 'eq 'type (quote 'CVS)) ;; CVS + (if (eq c 'RCS) r c)) ))) (defun vc-lock-file (file) @@ -1478,7 +1606,7 @@ '(vc-latest-version vc-your-latest-version)) ) ;; RCS - (vc-log-info "rlog" file + (vc-log-info "rlog" file 'MASTER nil (list "^locks: strict\n\t\\([^:]+\\)" "^locks: strict\n\t[^:]+: \\(.+\\)" @@ -1489,6 +1617,18 @@ ";")) '(vc-locking-user vc-locked-version vc-latest-version vc-your-latest-version)) + ;; CVS + ;; Don't fetch vc-locking-user and vc-locked-version here, since they + ;; should always be nil anyhow. Don't fetch vc-your-latest-version, since + ;; that is done in vc-find-cvs-master. + (vc-log-info + "cvs" file 'BASE '("status") + ;; CVS 1.3 says "RCS Version:", other releases "RCS Revision:", + ;; and CVS 1.4a1 says "Repository revision:". The regexp below + ;; matches much more, but because of the way vc-log-info is + ;; implemented it is impossible to use additional groups. + '("R[eC][pS][ositry]* [VRr]e[rv][si][is]i?on:[\t ]+\\([0-9.]+\\)") + '(vc-latest-version)) )) (defun vc-backend-subdirectory-name (&optional file) @@ -1513,9 +1653,10 @@ ((file-exists-p (vc-backend-subdirectory-name)) vc-default-back-end) ((file-exists-p "RCS") 'RCS) ((file-exists-p "SCCS") 'SCCS) + ((file-exists-p "CVS") 'CVS) (t vc-default-back-end)))) (cond ((eq backend 'SCCS) - (vc-do-command 0 "admin" file ;; SCCS + (vc-do-command 0 "admin" file 'MASTER ;; SCCS (and rev (concat "-r" rev)) "-fb" (concat "-i" file) @@ -1526,12 +1667,17 @@ (file-name-nondirectory file))) (delete-file file) (if vc-keep-workfiles - (vc-do-command 0 "get" file))) + (vc-do-command 0 "get" file 'MASTER))) ((eq backend 'RCS) - (vc-do-command 0 "ci" file ;; RCS + (vc-do-command 0 "ci" file 'MASTER ;; RCS (concat (if vc-keep-workfiles "-u" "-r") rev) (and comment (concat "-t-" comment)) - file) + file)) + ((eq backend 'CVS) + (vc-do-command 0 "cvs" file 'BASE ;; CVS + "add" + (and comment (not (string= comment "")) + (concat "-m" comment))) ))) (message "Registering %s...done" file) ) @@ -1552,7 +1698,7 @@ (unwind-protect (progn (vc-do-command - 0 "/bin/sh" file "-c" + 0 "/bin/sh" file 'MASTER "-c" ;; Some shells make the "" dummy argument into $0 ;; while others use the shell's name as $0 and ;; use the "" as $1. The if-statement @@ -1568,7 +1714,7 @@ "-p" (and rev (concat "-r" (vc-lookup-triple file rev)))) (setq failed nil)) (and failed (file-exists-p filename) (delete-file filename)))) - (vc-do-command 0 "get" file ;; SCCS + (vc-do-command 0 "get" file 'MASTER ;; SCCS (if writable "-e") (and rev (concat "-r" (vc-lookup-triple file rev))))) (if workfile ;; RCS @@ -1580,7 +1726,7 @@ (unwind-protect (progn (vc-do-command - 0 "/bin/sh" file "-c" + 0 "/bin/sh" file 'MASTER "-c" ;; See the SCCS case, above, regarding the if-statement. (format "if [ x\"$1\" = x ]; then shift; fi; \ umask %o; exec >\"$1\" || exit; \ @@ -1593,9 +1739,26 @@ (concat "-p" rev)) (setq failed nil)) (and failed (file-exists-p filename) (delete-file filename)))) - (vc-do-command 0 "co" file + (vc-do-command 0 "co" file 'MASTER (if writable "-l") (and rev (concat "-r" rev)))) + (if workfile ;; CVS + ;; CVS is much like RCS + (let ((failed t)) + (unwind-protect + (progn + (vc-do-command + 0 "/bin/sh" file 'BASE "-c" + "exec >\"$1\" || exit; shift; exec cvs update \"$@\"" + "" ; dummy argument for shell's $0 + workfile + (concat "-r" rev) + "-p") + (setq failed nil)) + (and failed (file-exists-p filename) (delete-file filename)))) + (vc-do-command 0 "cvs" file 'BASE + (and rev (concat "-r" rev)) + file)) ) (or workfile (vc-file-setprop file 'vc-checkout-time (nth 5 (file-attributes file)))) @@ -1609,10 +1772,11 @@ (goto-char 512) (error "Log must be less than 512 characters; point is now at pos 512"))) - nil) + nil ;; RCS + nil) ;; CVS ) -(defun vc-backend-checkin (file &optional rev comment) +(defun vc-backend-checkin (file rev comment) ;; Register changes to FILE as level REV with explanatory COMMENT. ;; Automatically retrieves a read-only version of the file with ;; keywords expanded if vc-keep-workfiles is non-nil, otherwise @@ -1623,17 +1787,23 @@ (set-buffer (or (get-file-buffer file) (current-buffer))) (vc-backend-dispatch file (progn - (apply 'vc-do-command 0 "delta" file + (apply 'vc-do-command 0 "delta" file 'MASTER (if rev (concat "-r" rev)) (concat "-y" comment) vc-checkin-switches) (if vc-keep-workfiles - (vc-do-command 0 "get" file)) + (vc-do-command 0 "get" file 'MASTER)) ) - (apply 'vc-do-command 0 "ci" file + (apply 'vc-do-command 0 "ci" file 'MASTER (concat (if vc-keep-workfiles "-u" "-r") rev) (concat "-m" comment) vc-checkin-switches) + (progn + (apply 'vc-do-command 0 "cvs" file 'BASE + "ci" "-m" comment + vc-checkin-switches) + (vc-file-setprop file 'vc-checkout-time + (nth 5 (file-attributes file)))) )) (vc-file-setprop file 'vc-locking-user nil) (message "Checking in %s...done" file) @@ -1645,9 +1815,14 @@ (vc-backend-dispatch file (progn ;; SCCS - (vc-do-command 0 "unget" file nil) - (vc-do-command 0 "get" file nil)) - (vc-do-command 0 "co" file "-f" "-u")) ;; RCS. This deletes the work file. + (vc-do-command 0 "unget" file 'MASTER nil) + (vc-do-command 0 "get" file 'MASTER nil)) + (vc-do-command 0 "co" file 'MASTER ;; RCS. This deletes the work file. + "-f" "-u") + (progn ;; CVS + (delete-file file) + (vc-do-command 0 "cvs" file 'BASE "update")) + ) (vc-file-setprop file 'vc-locking-user nil) (message "Reverting %s...done" file) ) @@ -1656,11 +1831,14 @@ ;; Steal the lock on the current workfile. Needs RCS 5.6.2 or later for -M. (message "Stealing lock on %s..." file) (vc-backend-dispatch file - (progn - (vc-do-command 0 "unget" file "-n" (if rev (concat "-r" rev))) - (vc-do-command 0 "get" file "-g" (if rev (concat "-r" rev))) + (progn ;SCCS + (vc-do-command 0 "unget" file 'MASTER "-n" (if rev (concat "-r" rev))) + (vc-do-command 0 "get" file 'MASTER "-g" (if rev (concat "-r" rev))) ) - (vc-do-command 0 "rcs" file "-M" (concat "-u" rev) (concat "-l" rev))) + (vc-do-command 0 "rcs" file 'MASTER ;RCS + "-M" (concat "-u" rev) (concat "-l" rev)) + (error "You cannot steal a CVS lock; there are no CVS locks to steal.") ;CVS + ) (vc-file-setprop file 'vc-locking-user (user-login-name)) (message "Stealing lock on %s...done" file) ) @@ -1670,48 +1848,89 @@ ;; smarter when we support multiple branches. (message "Removing last change from %s..." file) (vc-backend-dispatch file - (vc-do-command 0 "rmdel" file (concat "-r" target)) - (vc-do-command 0 "rcs" file (concat "-o" target)) + (vc-do-command 0 "rmdel" file 'MASTER (concat "-r" target)) + (vc-do-command 0 "rcs" file 'MASTER (concat "-o" target)) + (error "Unchecking files under CVS is dangerous and not supported in VC.") ) (message "Removing last change from %s...done" file) ) (defun vc-backend-print-log (file) ;; Print change log associated with FILE to buffer *vc*. - (vc-do-command 0 - (vc-backend-dispatch file "prs" "rlog") - file) - ) + (vc-backend-dispatch + file + (vc-do-command 0 "prs" file 'MASTER) + (vc-do-command 0 "rlog" file 'MASTER) + (vc-do-command 0 "cvs" file 'BASE "rlog"))) (defun vc-backend-assign-name (file name) ;; Assign to a FILE's latest version a given NAME. (vc-backend-dispatch file - (vc-add-triple name file (vc-latest-version file)) ;; SCCS - (vc-do-command 0 "rcs" file (concat "-n" name ":")) ;; RCS + (vc-add-triple name file (vc-latest-version file)) ;; SCCS + (vc-do-command 0 "rcs" file 'MASTER (concat "-n" name ":")) ;; RCS + (vc-do-command 0 "cvs" file 'BASE "tag" name) ;; CVS ) ) (defun vc-backend-diff (file &optional oldvers newvers cmp) ;; Get a difference report between two versions of FILE. ;; Get only a brief comparison report if CMP, a difference report otherwise. - (if (eq (vc-backend-deduce file) 'SCCS) + (let ((backend (vc-backend-deduce file))) + (cond + ((eq backend 'SCCS) (setq oldvers (vc-lookup-triple file oldvers)) - (setq newvers (vc-lookup-triple file newvers))) - (let* ((command (or (vc-backend-dispatch file "vcdiff" "rcsdiff") - (vc-registration-error file))) - (options (append (list (and cmp "--brief") - "-q" - (and oldvers (concat "-r" oldvers)) - (and newvers (concat "-r" newvers))) - (and (not cmp) - (if (listp diff-switches) - diff-switches - (list diff-switches))))) - (status (apply 'vc-do-command 2 command file options))) - ;; Some RCS versions don't understand "--brief"; work around this. - (if (eq status 2) - (apply 'vc-do-command 1 command file (if cmp (cdr options) options)) - status))) + (setq newvers (vc-lookup-triple file newvers)))) + (cond + ;; SCCS and RCS shares a lot of code. + ((or (eq backend 'SCCS) (eq backend 'RCS)) + (let* ((command (if (eq backend 'SCCS) + "vcdiff" + "rcsdiff")) + (options (append (list (and cmp "--brief") + "-q" + (and oldvers (concat "-r" oldvers)) + (and newvers (concat "-r" newvers))) + (and (not cmp) + (if (listp diff-switches) + diff-switches + (list diff-switches))))) + (status (apply 'vc-do-command 2 command file options))) + ;; Some RCS versions don't understand "--brief"; work around this. + (if (eq status 2) + (apply 'vc-do-command 1 command file 'MASTER + (if cmp (cdr options) options)) + status))) + ;; CVS is different. + ;; cmp is not yet implemented -- we always do a full diff. + ((eq backend 'CVS) + (if (string= (vc-file-getprop file 'vc-your-latest-version) "0") ;CVS + ;; This file is added but not yet committed; there is no master file. + ;; diff it against /dev/null. + (if (or oldvers newvers) + (error "No revisions of %s exists" file) + (apply 'vc-do-command + 1 "diff" file 'BASE "/dev/null" + (if (listp diff-switches) + diff-switches + (list diff-switches)))) + (apply 'vc-do-command + 1 "cvs" file 'BASE "diff" + (and oldvers (concat "-r" oldvers)) + (and newvers (concat "-r" newvers)) + (if (listp diff-switches) + diff-switches + (list diff-switches))))) + (t + (vc-registration-error file))))) + +(defun vc-backend-merge-news (file) + ;; Merge in any new changes made to FILE. + (vc-backend-dispatch + file + (error "vc-backend-merge-news not meaningful for SCCS files") ;SCCS + (error "vc-backend-merge-news not meaningful for RCS files") ;RCS + (vc-do-command 1 "cvs" file 'BASE "update") ;CVS + )) (defun vc-check-headers () "Check if the current file has any headers in it." @@ -1721,6 +1940,7 @@ (vc-backend-dispatch buffer-file-name (re-search-forward "%[MIRLBSDHTEGUYFPQCZWA]%" nil t) ;; SCCS (re-search-forward "\\$[A-Za-z\300-\326\330-\366\370-\377]+\\(: [\t -#%-\176\240-\377]*\\)?\\$" nil t) ;; RCS + 'RCS ;; CVS works like RCS in this regard. ) )) @@ -1771,13 +1991,14 @@ vc-header-alist Which keywords to insert when adding headers with \\[vc-insert-headers]. Defaults to - '(\"\%\W\%\") under SCCS, '(\"\$Id\$\") under RCS. + '(\"\%\W\%\") under SCCS, '(\"\$Id\$\") under + RCS and CVS. vc-static-header-alist By default, version headers inserted in C files get stuffed in a static string area so that - ident(RCS) or what(SCCS) can see them in the - compiled object code. You can override this - by setting this variable to nil, or change + ident(RCS/CVS) or what(SCCS) can see them in + the compiled object code. You can override + this by setting this variable to nil, or change the header template by changing it. vc-command-messages if non-nil, display run messages from the