]> code.delx.au - gnu-emacs/blobdiff - lisp/vc-svn.el
(pop-up-frame-function): Remove choice nil since it
[gnu-emacs] / lisp / vc-svn.el
index 854e66e3d1d9d659ae14874f571b0531270f6e8b..6eeb8985bfd125c094ad34a82baa9d5b19a511fe 100644 (file)
@@ -1,6 +1,7 @@
 ;;; vc-svn.el --- non-resident support for Subversion version-control
 
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+;;   Free Software Foundation, Inc.
 
 ;; Author:      FSF (see vc.el for full credits)
 ;; Maintainer:  Stefan Monnier <monnier@gnu.org>
 ;;; Customization options
 ;;;
 
+;; FIXME there is also svnadmin.
+(defcustom vc-svn-program "svn"
+  "Name of the SVN executable."
+  :type 'string
+  :group 'vc)
+
 (defcustom vc-svn-global-switches nil
-  "*Global switches to pass to any SVN command."
+  "Global switches to pass to any SVN command."
   :type '(choice (const :tag "None" nil)
                 (string :tag "Argument String")
                 (repeat :tag "Argument List"
   :group 'vc)
 
 (defcustom vc-svn-register-switches nil
-  "*Extra switches for registering a file into SVN.
+  "Switches for registering a file into SVN.
 A string or list of strings passed to the checkin program by
-\\[vc-register]."
-  :type '(choice (const :tag "None" nil)
+\\[vc-register].  If nil, use the value of `vc-register-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))
+                (repeat :tag "Argument List" :value ("") string))
   :version "22.1"
   :group 'vc)
 
 (defcustom vc-svn-diff-switches
   t                       ;`svn' doesn't support common args like -c or -b.
   "String or list of strings specifying extra switches for svn diff under VC.
-If nil, use the value of `vc-diff-switches'.
-If you want to force an empty list of arguments, use t."
+If nil, use the value of `vc-diff-switches' (or `diff-switches'),
+together with \"-x --diff-cmd=diff\" (since svn diff does not
+support the default \"-c\" value of `diff-switches').  If you
+want to force an empty list of arguments, use t."
   :type '(choice (const :tag "Unspecified" nil)
                 (const :tag "None" t)
                 (string :tag "Argument String")
@@ -71,7 +80,7 @@ If you want to force an empty list of arguments, use t."
   :group 'vc)
 
 (defcustom vc-svn-header (or (cdr (assoc 'SVN vc-header-alist)) '("\$Id\$"))
-  "*Header keywords to be inserted by `vc-insert-headers'."
+  "Header keywords to be inserted by `vc-insert-headers'."
   :version "22.1"
   :type '(repeat string)
   :group 'vc)
@@ -110,9 +119,6 @@ If you want to force an empty list of arguments, use t."
 ;;;###autoload       (load "vc-svn")
 ;;;###autoload       (vc-svn-registered f))))
 
-;;;###autoload
-(add-to-list 'completion-ignored-extensions ".svn/")
-
 (defun vc-svn-registered (file)
   "Check if FILE is SVN registered."
   (when (file-readable-p (expand-file-name (concat vc-svn-admin-directory
@@ -146,7 +152,9 @@ If you want to force an empty list of arguments, use t."
   "SVN-specific state heuristic."
   (vc-svn-state file 'local))
 
-(defun vc-svn-after-dir-status (callback)
+;; FIXME it would be better not to have the "remote" argument,
+;; but to distinguish the two output formats based on content.
+(defun vc-svn-after-dir-status (callback &optional remote)
   (let ((state-map '((?A . added)
                      (?C . conflict)
                      (?D . removed)
@@ -156,12 +164,19 @@ If you want to force an empty list of arguments, use t."
                      (?? . unregistered)
                      ;; This is what vc-svn-parse-status does.
                      (?~ . edited)))
+       (re (if remote "^\\(.\\)..... \\([ *]\\) +\\(?:[-0-9]+\\)?   \\(.*\\)$"
+             ;; Subexp 2 is a dummy in this case, so the numbers match.
+             "^\\(.\\)....\\(.\\) \\(.*\\)$"))
        result)
     (goto-char (point-min))
-    (while (re-search-forward "^\\(.\\)..... \\(.*\\)$" nil t)
+    (while (re-search-forward re nil t)
       (let ((state (cdr (assq (aref (match-string 1) 0) state-map)))
-           (filename (match-string 2)))
-       (when state
+           (filename (match-string 3)))
+       (and remote (string-equal (match-string 2) "*")
+            ;; FIXME are there other possible combinations?
+            (cond ((eq state 'edited) (setq state 'needs-merge))
+                  ((not state) (setq state 'needs-update))))
+       (when (and state (not (string= "." filename)))
          (setq result (cons (list filename state) result)))))
     (funcall callback result)))
 
@@ -169,11 +184,24 @@ If you want to force an empty list of arguments, use t."
   "Run 'svn status' for DIR and update BUFFER via CALLBACK.
 CALLBACK is called as (CALLBACK RESULT BUFFER), where
 RESULT is a list of conses (FILE . STATE) for directory DIR."
-  (vc-svn-command (current-buffer) 'async nil "status")
+  ;; FIXME should this rather be all the files in dir?
+  ;; FIXME: the vc-stay-local-p logic below is disabled, it ends up
+  ;; calling synchronously (vc-svn-registered DIR) => calling svn status -v DIR
+  ;; which is VERY SLOW for big trees and it makes emacs
+  ;; completely unresponsive during that time.
+  (let* ((local (and nil (vc-stay-local-p dir)))
+        (remote (or t (not local) (eq local 'only-file))))
+    (vc-svn-command (current-buffer) 'async nil "status"
+                   (if remote "-u"))
+  (vc-exec-after
+     `(vc-svn-after-dir-status (quote ,callback) ,remote))))
+
+(defun vc-svn-dir-status-files (dir files default-state callback)
+  (apply 'vc-svn-command (current-buffer) 'async nil "status" files)
   (vc-exec-after
    `(vc-svn-after-dir-status (quote ,callback))))
 
-(defun vc-svn-status-extra-headers (dir)
+(defun vc-svn-dir-extra-headers (dir)
   "Generate extra status headers for a Subversion working copy."
   (vc-svn-command "*vc*" 0 nil "info")
   (let ((repo
@@ -226,15 +254,14 @@ RESULT is a list of conses (FILE . STATE) for directory DIR."
 (defun vc-svn-create-repo ()
   "Create a new SVN repository."
   (vc-do-command "*vc*" 0 "svnadmin" '("create" "SVN"))
-  (vc-do-command "*vc*" 0 "svn" '(".")
+  (vc-do-command "*vc*" 0 vc-svn-program '(".")
                 "checkout" (concat "file://" default-directory "SVN")))
 
 (defun vc-svn-register (files &optional rev comment)
   "Register FILES into the SVN version-control system.
 The COMMENT argument is ignored  This does an add but not a commit.
-
-`vc-register-switches' and `vc-svn-register-switches' are passed to
-the SVN command (in that order)."
+Passes either `vc-svn-register-switches' or `vc-register-switches'
+to the SVN command."
   (apply 'vc-svn-command nil 0 files "add" (vc-switches 'SVN 'register)))
 
 (defun vc-svn-responsible-p (file)
@@ -384,12 +411,12 @@ The changes are between FIRST-VERSION and SECOND-VERSION."
 (defun vc-svn-modify-change-comment (files rev comment)
   "Modify the change comments for a specified REV.
 You must have ssh access to the repository host, and the directory Emacs
-uses locally for temp files must also be writeable by you on that host.
+uses locally for temp files must also be writable by you on that host.
 This is only supported if the repository access method is either file://
 or svn+ssh://."
   (let (tempfile host remotefile directory fileurl-p)
     (with-temp-buffer
-      (vc-do-command (current-buffer) 0 "svn" nil "info")
+      (vc-do-command (current-buffer) 0 vc-svn-program nil "info")
       (goto-char (point-min))
       (unless (re-search-forward "Repository Root: \\(file://\\(/.*\\)\\)\\|\\(svn\\+ssh://\\([^/]+\\)\\(/.*\\)\\)" nil t)
        (error "Repository information is unavailable"))
@@ -457,6 +484,8 @@ or svn+ssh://."
 (defun vc-svn-diff (files &optional oldvers newvers buffer)
   "Get a difference report using SVN between two revisions of fileset FILES."
   (and oldvers
+       (not newvers)
+       files
        (catch 'no
         (dolist (f files)
           (or (equal oldvers (vc-working-revision f))
@@ -470,7 +499,8 @@ or svn+ssh://."
   (let* ((switches
            (if vc-svn-diff-switches
                (vc-switches 'SVN 'diff)
-             (list "-x" (mapconcat 'identity (vc-switches nil 'diff) " "))))
+             (list "--diff-cmd=diff" "-x"
+                   (mapconcat 'identity (vc-switches nil 'diff) " "))))
           (async (and (not vc-disable-async-diff)
                        (vc-stay-local-p files)
                       (or oldvers newvers)))) ; Svn diffs those locally.
@@ -528,14 +558,6 @@ NAME is assumed to be a URL."
 ;;; Internal functions
 ;;;
 
-(defcustom vc-svn-program "svn"
-  "Name of the SVN executable."
-  :type 'string
-  :group 'vc)
-
-(defun vc-svn-root (dir)
-  (vc-find-root dir vc-svn-admin-directory t))
-
 (defun vc-svn-command (buffer okstatus file-or-list &rest flags)
   "A wrapper around `vc-do-command' for use in vc-svn.el.
 The difference to vc-do-command is that this function always invokes `svn',