;;; vc.el --- drive a version-control system from within Emacs -*- lexical-binding:t -*-
-;; Copyright (C) 1992-1998, 2000-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1992-1998, 2000-2016 Free Software Foundation, Inc.
;; Author: FSF (see below for full credits)
;; Maintainer: Andre Spiegel <spiegel@gnu.org>
;; Unregister FILE from this backend. This is only needed if this
;; backend may be used as a "more local" backend for temporary editing.
;;
-;; * checkin (files comment)
+;; * checkin (files comment &optional rev)
;;
;; Commit changes in FILES to this backend. COMMENT is used as a
;; check-in comment. The implementation should pass the value of
-;; vc-checkin-switches to the backend command. The revision argument
-;; of some older VC versions is no longer supported.
+;; vc-checkin-switches to the backend command. The optional REV
+;; revision argument is only supported with some older VCSes, like
+;; RCS and CVS, and is otherwise silently ignored.
;;
;; * find-revision (file rev buffer)
;;
;; BUFFER is nil. If ASYNC is non-nil, run asynchronously. If REV1
;; and REV2 are non-nil, report differences from REV1 to REV2. If
;; REV1 is nil, use the working revision (as found in the
-;; repository) as the older revision; if REV2 is nil, use the
+;; repository) as the older revision if REV2 is nil as well;
+;; otherwise, diff against an empty tree. If REV2 is nil, use the
;; current working-copy contents as the newer revision. This
;; function should pass the value of (vc-switches BACKEND 'diff) to
;; the backend command. It should return a status of either 0 (no
:group 'vc
:version "21.1")
+(defcustom vc-annotate-switches nil
+ "A string or list of strings specifying switches for annotate under VC.
+When running annotate under a given BACKEND, VC uses the first
+non-nil value of `vc-BACKEND-annotate-switches', `vc-annotate-switches',
+and `annotate-switches', in that order. Since nil means to check the
+next variable in the sequence, either of the first two may use
+the value t to mean no switches at all. `vc-annotate-switches'
+should contain switches that are specific to version control, but
+not specific to any particular backend.
+
+As very few switches (if any) are used across different VC tools,
+please consider using the specific `vc-BACKEND-annotate-switches'
+for the backend you use."
+ :type '(choice (const :tag "Unspecified" nil)
+ (const :tag "None" t)
+ (string :tag "Argument String")
+ (repeat :tag "Argument List" :value ("") string))
+ :group 'vc
+ :version "25.1")
+
(defcustom vc-log-show-limit 2000
"Limit the number of items shown by the VC log commands.
Zero means unlimited.
(defcustom vc-static-header-alist
'(("\\.c\\'" .
- "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n#endif /* lint */\n"))
+ "\n#ifndef lint\nstatic char vcid[] = \"%s\";\n#endif /* lint */\n"))
"Associate static header string templates with file types.
-A \%s in the template is replaced with the first string associated with
+A %s in the template is replaced with the first string associated with
the file's version control type in `vc-BACKEND-header'."
:type '(repeat (cons :format "%v"
(regexp :tag "File Type")
(vc-call-backend bk 'create-repo))
(throw 'found bk))))
+;;;###autoload
(defun vc-responsible-backend (file)
"Return the name of a backend system that is responsible for FILE.
(if observer
(vc-dired-deduce-fileset)
(error "State changing VC operations not supported in `dired-mode'")))
- ((and (derived-mode-p 'log-view-mode)
- (setq backend (vc-responsible-backend default-directory)))
- (list backend default-directory))
((setq backend (vc-backend buffer-file-name))
(if state-model-only-files
(list backend (list buffer-file-name)
(progn ;FIXME: Why not `with-current-buffer'? --Stef.
(set-buffer vc-parent-buffer)
(vc-deduce-fileset observer allow-unregistered state-model-only-files)))
+ ((and (derived-mode-p 'log-view-mode)
+ (setq backend (vc-responsible-backend default-directory)))
+ (list backend nil))
((not buffer-file-name)
(error "Buffer %s is not associated with a file" (buffer-name)))
((and allow-unregistered (not (vc-registered buffer-file-name)))
(message "No files remain to be committed")
(if (not verbose)
(vc-checkin ready-for-commit backend)
- (let ((new-backend (vc-read-backend "New backend: ")))
- (if new-backend
- (dolist (file files)
- (vc-transfer-file file new-backend))))))))
+ (let* ((revision (read-string "New revision or backend: "))
+ (revision-downcase (downcase revision)))
+ (if (member
+ revision-downcase
+ (mapcar (lambda (arg) (downcase (symbol-name arg)))
+ vc-handled-backends))
+ (let ((vsym (intern revision-downcase)))
+ (dolist (file files) (vc-transfer-file file vsym)))
+ (vc-checkin ready-for-commit backend nil nil revision)))))))
;; locked by somebody else (locking VCSes only)
((stringp state)
;; In the old days, we computed the revision once and used it on
(defun vc-default-ignore-completion-table (backend file)
"Return the list of ignored files under BACKEND."
- (vc--read-lines
- (vc-call-backend backend 'find-ignore-file file)))
+ (cl-delete-if
+ (lambda (str)
+ ;; Commented or empty lines.
+ (string-match-p "\\`\\(?:#\\|[ \t\r\n]*\\'\\)" str))
+ (let ((file (vc-call-backend backend 'find-ignore-file file)))
+ (and (file-exists-p file)
+ (vc--read-lines file)))))
(defun vc--read-lines (file)
"Return a list of lines of FILE."
".\n")
(message "Please explain why you stole the lock. Type C-c C-c when done.")))
-(defun vc-checkin (files backend &optional comment initial-contents)
+(defun vc-checkin (files backend &optional comment initial-contents rev)
"Check in FILES. COMMENT is a comment string; if omitted, a
buffer is popped up to accept a comment. If INITIAL-CONTENTS is
non-nil, then COMMENT is used as the initial contents of the log
entry buffer.
+The optional argument REV may be a string specifying the new revision
+level (only supported for some older VCSes, like RCS and CVS).
Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'."
(when vc-before-checkin-hook
;; vc-checkin-switches, but 'the' local buffer is
;; not a well-defined concept for filesets.
(progn
- (vc-call-backend backend 'checkin files comment)
+ (vc-call-backend backend 'checkin files comment rev)
(mapc 'vc-delete-automatic-version-backups files))
`((vc-state . up-to-date)
(vc-checkout-time . ,(nth 5 (file-attributes file)))
(smerge-mode 1)
(message "File contains conflicts.")))
+;;;###autoload
+(defun vc-message-unresolved-conflicts (filename)
+ "Display a message indicating unresolved conflicts in FILENAME."
+ ;; This enables all VC backends to give a standard, recognizable
+ ;; conflict message that indicates which file is conflicted.
+ (message "There are unresolved conflicts in %s" filename))
+
;;;###autoload
(defalias 'vc-resolve-conflicts 'smerge-ediff)
(defun vc-tag-precondition (dir)
"Scan the tree below DIR, looking for files not up-to-date.
If any file is not up-to-date, return the name of the first such file.
-\(This means, neither tag creation nor retrieval is allowed.\)
+\(This means, neither tag creation nor retrieval is allowed.)
If one or more of the files are currently visited, return `visited'.
Otherwise, return nil."
(let ((status nil))
In the new log, leave point at WORKING-REVISION (if non-nil).
LIMIT is the number of entries currently shown.
Does nothing if IS-START-REVISION is non-nil, or if LIMIT is nil,
-or if PL-RETURN is 'limit-unsupported."
+or if PL-RETURN is `limit-unsupported'."
(when (and limit (not (eq 'limit-unsupported pl-return))
(not is-start-revision))
(goto-char (point-max))
(lambda (_bk _files-arg ret)
(vc-print-log-setup-buttons working-revision
is-start-revision limit ret))
- (lambda (bk)
- (vc-call-backend bk 'show-log-entry working-revision))
+ ;; When it's nil, point really shouldn't move (bug#15322).
+ (when working-revision
+ (lambda (bk)
+ (vc-call-backend bk 'show-log-entry working-revision)))
(lambda (_ignore-auto _noconfirm)
(vc-print-log-internal backend files working-revision
is-start-revision limit)))))
(let ((inhibit-read-only t))
(funcall setup-buttons-func backend files retval)
(shrink-window-if-larger-than-buffer)
- (funcall goto-location-func backend)
- (setq vc-sentinel-movepoint (point))
+ (when goto-location-func
+ (funcall goto-location-func backend)
+ (setq vc-sentinel-movepoint (point)))
(set-buffer-modified-p nil)))))
(defun vc-incoming-outgoing-internal (backend remote-location buffer-name type)
(lambda (bk buf type-arg _files)
(vc-call-backend bk type-arg buf remote-location))
(lambda (_bk _files-arg _ret) nil)
- (lambda (_bk) (goto-char (point-min)))
+ nil ;; Don't move point.
(lambda (_ignore-auto _noconfirm)
(vc-incoming-outgoing-internal backend remote-location buffer-name type))))
(list (when (> vc-log-show-limit 0) vc-log-show-limit)))))
(let ((backend (vc-deduce-backend))
(default-directory default-directory)
- rootdir working-revision)
+ rootdir)
(if backend
(setq rootdir (vc-call-backend backend 'root default-directory))
(setq rootdir (read-directory-name "Directory for VC root-log: "))
(setq backend (vc-responsible-backend rootdir))
(unless backend
(error "Directory is not version controlled")))
- (setq working-revision (vc-working-revision rootdir)
- default-directory rootdir)
- (vc-print-log-internal backend (list rootdir) working-revision nil limit)))
+ (setq default-directory rootdir)
+ (vc-print-log-internal backend (list rootdir) nil nil limit)))
;;;###autoload
(defun vc-log-incoming (&optional remote-location)
You must be visiting a version controlled file, or in a `vc-dir' buffer.
On a distributed version control system, this runs a \"pull\"
operation to update the current branch, prompting for an argument
-list if required. Optional prefix ARG forces a prompt.
+list if required. Optional prefix ARG forces a prompt for the VCS
+command to run.
On a non-distributed version control system, update the current
fileset to the tip revisions. For each unchanged and unlocked
;;;###autoload
(defalias 'vc-update 'vc-pull)
+;;;###autoload
+(defun vc-push (&optional arg)
+ "Push the current branch.
+You must be visiting a version controlled file, or in a `vc-dir' buffer.
+On a distributed version control system, this runs a \"push\"
+operation on the current branch, prompting for the precise command
+if required. Optional prefix ARG non-nil forces a prompt for the
+VCS command to run.
+
+On a non-distributed version control system, this signals an error.
+It also signals an error in a Bazaar bound branch."
+ (interactive "P")
+ (let* ((vc-fileset (vc-deduce-fileset t))
+ (backend (car vc-fileset)))
+;;; (files (cadr vc-fileset)))
+ (if (vc-find-backend-function backend 'push)
+ (vc-call-backend backend 'push arg)
+ (user-error "VC push is unsupported for `%s'" backend))))
+
(defun vc-version-backup-file (file &optional rev)
"Return name of backup file for revision REV of FILE.
If version backups should be used for FILE, and there exists