X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/95a2cb24b0697558e6629460d8bc693b394f0138..1f5592572887fe15e5b660bc60e66a7ab7c624cd:/lisp/vc/vc-cvs.el diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index d803c16d7c..50198713b4 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -1,6 +1,6 @@ ;;; vc-cvs.el --- non-resident support for CVS version-control -*- lexical-binding: t -*- -;; Copyright (C) 1995, 1998-2015 Free Software Foundation, Inc. +;; Copyright (C) 1995, 1998-2016 Free Software Foundation, Inc. ;; Author: FSF (see vc.el for full credits) ;; Maintainer: Andre Spiegel @@ -27,6 +27,12 @@ (eval-when-compile (require 'vc)) +(declare-function vc-branch-p "vc" (rev)) +(declare-function vc-checkout "vc" (file &optional rev)) +(declare-function vc-expand-dirs "vc" (file-or-dir-list backend)) +(declare-function vc-read-revision "vc" + (prompt &optional files backend default initial-input)) + ;; Clear up the cache to force vc-call to check again and discover ;; new functions when we reload this file. (put 'CVS 'vc-functions nil) @@ -96,7 +102,18 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." :version "21.1" :group 'vc-cvs) -(defcustom vc-cvs-header '("\$Id\$") +(defcustom vc-cvs-annotate-switches nil + "String or list of strings specifying switches for cvs annotate under VC. +If nil, use the value of `vc-annotate-switches'. If t, use no +switches." + :type '(choice (const :tag "Unspecified" nil) + (const :tag "None" t) + (string :tag "Argument String") + (repeat :tag "Argument List" :value ("") string)) + :version "25.1" + :group 'vc-cvs) + +(defcustom vc-cvs-header '("$Id\ $") "Header keywords to be inserted by `vc-insert-headers'." :version "24.1" ; no longer consult the obsolete vc-header-alist :type '(repeat string) @@ -110,7 +127,7 @@ This is only meaningful if you don't use the implicit checkout model :version "21.1" :group 'vc-cvs) -(defcustom vc-stay-local 'only-file +(defcustom vc-cvs-stay-local 'only-file "Non-nil means use local operations when possible for remote repositories. This avoids slow queries over the network and instead uses heuristics and past information to determine the current status of a file. @@ -120,11 +137,11 @@ server, but heuristics will be used to determine the status for all other VC operations. The value can also be a regular expression or list of regular -expressions to match against the host name of a repository; then VC -only stays local for hosts that match it. Alternatively, the value -can be a list of regular expressions where the first element is the -symbol `except'; then VC always stays local except for hosts matched -by these regular expressions." +expressions to match against the host name of a repository; then +vc-cvs only stays local for hosts that match it. Alternatively, +the value can be a list of regular expressions where the first +element is the symbol `except'; then vc-cvs always stays local +except for hosts matched by these regular expressions." :type '(choice (const :tag "Always stay local" t) (const :tag "Only for file operations" only-file) (const :tag "Don't stay local" nil) @@ -150,7 +167,7 @@ Format is according to `format-time-string'. Only used if "Specify the mode-line display of sticky tags. Value t means default display, nil means no display at all. If the value is a function or macro, it is called with the sticky tag and -its' type as parameters, in that order. TYPE can have three different +its type as parameters, in that order. TYPE can have three different values: `symbolic-name' (TAG is a string), `revision-number' (TAG is a string) and `date' (TAG is a date as returned by `encode-time'). The return value of the function or macro will be displayed as a string. @@ -159,10 +176,10 @@ Here's an example that will display the formatted date for sticky dates and the word \"Sticky\" for sticky tag names and revisions. (lambda (tag type) - (cond ((eq type 'date) (format-time-string + (cond ((eq type \\='date) (format-time-string vc-cvs-sticky-date-format-string tag)) - ((eq type 'revision-number) \"Sticky\") - ((eq type 'symbolic-name) \"Sticky\"))) + ((eq type \\='revision-number) \"Sticky\") + ((eq type \\='symbolic-name) \"Sticky\"))) Here's an example that will abbreviate to the first character only, any text before the first occurrence of `-' for sticky symbolic tags. @@ -170,9 +187,9 @@ If the sticky tag is a revision number, the word \"Sticky\" is displayed. Date and time is displayed for sticky dates. (lambda (tag type) - (cond ((eq type 'date) (format-time-string \"%Y%m%d %H:%M\" tag)) - ((eq type 'revision-number) \"Sticky\") - ((eq type 'symbolic-name) + (cond ((eq type \\='date) (format-time-string \"%Y%m%d %H:%M\" tag)) + ((eq type \\='revision-number) \"Sticky\") + ((eq type \\='symbolic-name) (condition-case nil (progn (string-match \"\\\\([^-]*\\\\)\\\\(.*\\\\)\" tag) @@ -270,8 +287,8 @@ committed and support display of sticky tags." (propertize (if (zerop (length sticky-tag)) string - (setq help-echo (format "%s on the '%s' branch" - help-echo sticky-tag)) + (setq help-echo (format-message "%s on the `%s' branch" + help-echo sticky-tag)) (concat string "[" sticky-tag "]")) 'help-echo help-echo))) @@ -321,38 +338,20 @@ its parents." (directory-file-name dir)))) (eq dir t))) -;; vc-cvs-checkin used to take a 'rev' second argument that allowed -;; checking in onto a specified branch tip rather than the current -;; default branch, but nothing in the entire rest of VC exercised -;; this code. Removing it simplifies the backend interface for all -;; modes. -;; -;; Here's the setup code preserved in amber, in case the logic needs -;; to be broken out into a method someday; (if rev (concat "-r" rev)) -;; used to be part of the switches passed to vc-cvs-command. -;; -;; (unless (or (not rev) (vc-cvs-valid-revision-number-p rev)) -;; (if (not (vc-cvs-valid-symbolic-tag-name-p rev)) -;; (error "%s is not a valid symbolic tag name" rev) -;; ;; If the input revision is a valid symbolic tag name, we create it -;; ;; as a branch, commit and switch to it. -;; (apply 'vc-cvs-command nil 0 files "tag" "-b" (list rev)) -;; (apply 'vc-cvs-command nil 0 files "update" "-r" (list rev)) -;; (mapc (lambda (file) (vc-file-setprop file 'vc-cvs-sticky-tag rev)) -;; files))) -;; -;; The following postamble cleaned up after the branch change: -;; -;; ;; if this was an explicit check-in (does not include creation of -;; ;; a branch), remove the sticky tag. -;; (if (and rev (not (vc-cvs-valid-symbolic-tag-name-p rev))) -;; (vc-cvs-command nil 0 files "update" "-A")))) -;; files))) -;; -(defun vc-cvs-checkin (files comment) +(defun vc-cvs-checkin (files comment &optional rev) "CVS-specific version of `vc-backend-checkin'." + (unless (or (not rev) (vc-cvs-valid-revision-number-p rev)) + (if (not (vc-cvs-valid-symbolic-tag-name-p rev)) + (error "%s is not a valid symbolic tag name" rev) + ;; If the input revision is a valid symbolic tag name, we create it + ;; as a branch, commit and switch to it. + (apply 'vc-cvs-command nil 0 files "tag" "-b" (list rev)) + (apply 'vc-cvs-command nil 0 files "update" "-r" (list rev)) + (mapc (lambda (file) (vc-file-setprop file 'vc-cvs-sticky-tag rev)) + files))) (let ((status (apply 'vc-cvs-command nil 1 files - "ci" (concat "-m" comment) + "ci" (if rev (concat "-r" rev)) + (concat "-m" comment) (vc-switches 'CVS 'checkin)))) (set-buffer "*vc*") (goto-char (point-min)) @@ -383,7 +382,11 @@ its parents." ;; tell it from the permissions of the file (see ;; vc-cvs-checkout-model). (mapc (lambda (file) (vc-file-setprop file 'vc-checkout-model nil)) - files))) + files) + ;; if this was an explicit check-in (does not include creation of + ;; a branch), remove the sticky tag. + (if (and rev (not (vc-cvs-valid-symbolic-tag-name-p rev))) + (vc-cvs-command nil 0 files "update" "-A")))) (defun vc-cvs-find-revision (file rev buffer) (apply 'vc-cvs-command @@ -623,11 +626,12 @@ Remaining arguments are ignored." (defun vc-cvs-annotate-command (file buffer &optional revision) "Execute \"cvs annotate\" on FILE, inserting the contents in BUFFER. Optional arg REVISION is a revision to annotate from." - (vc-cvs-command buffer - (if (vc-cvs-stay-local-p file) - 'async 0) - file "annotate" - (if revision (concat "-r" revision))) + (apply #'vc-cvs-command buffer + (if (vc-cvs-stay-local-p file) + 'async 0) + file "annotate" + (append (vc-switches 'cvs 'annotate) + (if revision (list (concat "-r" revision))))) ;; Strip the leading few lines. (let ((proc (get-buffer-process buffer))) (if proc @@ -639,7 +643,7 @@ Optional arg REVISION is a revision to annotate from." (re-search-forward vc-cvs-annotate-first-line-re) (delete-region (point-min) (1- (point))))))) -(declare-function vc-annotate-convert-time "vc-annotate" (time)) +(declare-function vc-annotate-convert-time "vc-annotate" (&optional time)) (defun vc-cvs-annotate-current-time () "Return the current time, based at midnight of the current day, and @@ -791,8 +795,7 @@ If FILE is a list of files, return non-nil if any of them individually should stay local." (if (listp file) (delq nil (mapcar (lambda (arg) (vc-cvs-stay-local-p arg)) file)) - (let* ((sym (vc-make-backend-sym 'CVS 'stay-local)) - (stay-local (if (boundp sym) (symbol-value sym) vc-stay-local))) + (let ((stay-local vc-cvs-stay-local)) (if (symbolp stay-local) stay-local (let ((dirname (if (file-directory-p file) (directory-file-name file) @@ -884,11 +887,11 @@ For an empty string, nil is returned (invalid CVS root)." (setq host uhost)) ;; Remove empty HOST (and (equal host "") - (setq host)) + (setq host nil)) ;; Fix windows style CVS root `:local:C:\\project\\cvs\\some\\dir' (and host (equal method "local") - (setq root (concat host ":" root) host)) + (setq root (concat host ":" root) host nil)) ;; Normalize CVS root record (list method user host root))))) @@ -901,7 +904,7 @@ For an empty string, nil is returned (invalid CVS root)." (defun vc-cvs-parse-status (&optional full) "Parse output of \"cvs status\" command in the current buffer. Set file properties accordingly. Unless FULL is t, parse only -essential information. Note that this can never set the 'ignored +essential information. Note that this can never set the `ignored' state." (let (file status missing) (goto-char (point-min)) @@ -920,7 +923,7 @@ state." (when (and full (re-search-forward "\\(RCS Version\\|RCS Revision\\|Repository revision\\):\ -\[\t ]+\\([0-9.]+\\)" +[\t ]+\\([0-9.]+\\)" nil t)) (vc-file-setprop file 'vc-latest-revision (match-string 2))) (vc-file-setprop @@ -1076,7 +1079,7 @@ Query all files in DIR if files is nil." (if (and (not files) local (not (eq local 'only-file))) (vc-cvs-dir-status-heuristic dir update-function) (if (not files) (setq files (vc-expand-dirs (list dir) 'CVS))) - (vc-cvs-command (current-buffer) 'async dir "-f" "status" files) + (vc-cvs-command (current-buffer) 'async files "-f" "status") ;; Alternative implementation: use the "update" command instead of ;; the "status" command. ;; (vc-cvs-command (current-buffer) 'async