;;; 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 <spiegel@gnu.org>
: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)
"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.
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.
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)
(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)))
(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))
;; 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
(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
(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
(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)))))
(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))
(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
(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