]> code.delx.au - gnu-emacs/blobdiff - lisp/vc/vc.el
; Fix breakage from previous commit
[gnu-emacs] / lisp / vc / vc.el
index 54b221428a58c6bc43e20a83210eccae81e53a42..af875e89907fa91674ccbae095f9ecb24b193db6 100644 (file)
@@ -1,6 +1,6 @@
 ;;; vc.el --- drive a version-control system from within Emacs  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1992-1998, 2000-2015 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
 ;;   argument, since on no system since RCS has setting the initial
 ;;   revision been even possible, let alone sane.
 ;;
-;;   INCOMPATIBLE CHANGE: In older versions of the API, vc-diff did
+;; - INCOMPATIBLE CHANGE: In older versions of the API, vc-diff did
 ;;   not take an async-mode flag as a fourth optional argument.  (This
 ;;   change eliminated a particularly ugly global.)
 ;;
 ;;   SVN.)
 ;;
 ;; - INCOMPATIBLE CHANGE: The old fourth 'default-state' argument of
-;;   vc-dir-status-files is gone; none of the back ends actually used it.
+;;   dir-status-files is gone; none of the back ends actually used it.
 ;;
-;; - vc-dir-status is no longer a public method; it has been replaced
-;;   by vc-dir-status-files.
+;; - dir-status is no longer a public method; it has been replaced by
+;;   dir-status-files.
 ;;
-;; - vc-state-heuristic is no longer a public method (the CVS backend
+;; - state-heuristic is no longer a public method (the CVS backend
 ;;   retains it as a private one).
 ;;
 ;; - the vc-mistrust-permissions configuration variable is gone; the
 ;;   only affected back ends were SCCS and RCS.
 ;;
 ;; - vc-stay-local-p and repository-hostname are no longer part
-;;   of the public API. The vc-stay-local configuration variable
-;;   remains but only affects the CVS back end.
+;;   of the public API. The vc-cvs-stay-local configuration variable
+;;   remains and only affects the CVS back end.
 ;;
 ;; - The init-revision function and the default-initial-revision
 ;;   variable are gone.  These have't made sense on anything shipped
@@ -780,6 +782,26 @@ not specific to any particular backend."
   :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.
@@ -829,9 +851,9 @@ See `run-hooks'."
 
 (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")
@@ -930,6 +952,7 @@ use."
        (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.
 
@@ -1003,9 +1026,6 @@ BEWARE: this function may change the current buffer."
       (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)
@@ -1021,6 +1041,9 @@ BEWARE: this function may change the current buffer."
       (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)))
@@ -1199,10 +1222,15 @@ For old-style locking-based version control systems, like RCS:
            (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
@@ -1401,8 +1429,13 @@ Argument BACKEND is the backend you are using."
 
 (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."
@@ -1496,11 +1529,13 @@ Type \\[vc-next-action] to check in changes.")
      ".\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
@@ -1523,7 +1558,7 @@ Runs the normal hooks `vc-before-checkin-hook' and `vc-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)))
@@ -2033,6 +2068,13 @@ changes from the current branch."
     (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)
 
@@ -2067,7 +2109,7 @@ changes from the current branch."
 (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))
@@ -2158,7 +2200,7 @@ Not all VC backends support short logs!")
 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))
@@ -2203,8 +2245,10 @@ earlier revisions.  Show up to LIMIT entries (non-nil means unlimited)."
        (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)))))
@@ -2242,8 +2286,9 @@ earlier revisions.  Show up to LIMIT entries (non-nil means unlimited)."
      (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)
@@ -2252,7 +2297,7 @@ earlier revisions.  Show up to LIMIT entries (non-nil means unlimited)."
    (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))))
 
@@ -2307,16 +2352,15 @@ When called interactively with a prefix argument, prompt for LIMIT."
      (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)
@@ -2423,7 +2467,8 @@ to the working revision (except for keyword expansion)."
 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
@@ -2461,6 +2506,25 @@ tip revision are merged into the working file."
 ;;;###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