Be more tolerant to fonts named "Foobar-12"
[emacs.git] / lisp / vc / vc-svn.el
Commit [+]AuthorDateLineData
9c750eba Stefan Monnier2013-09-04 17:09:42 -04001;;; vc-svn.el --- non-resident support for Subversion version-control -*- lexical-binding:t -*-
1fd3454a Stefan Monnier2003-05-05 15:42:27 +00002
7e09ef09 Paul Eggert2015-01-01 14:26:41 -08003;; Copyright (C) 2003-2015 Free Software Foundation, Inc.
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +00004
5;; Author: FSF (see vc.el for full credits)
6;; Maintainer: Stefan Monnier <monnier@gnu.org>
bd78fa1d Chong Yidong2010-08-29 12:17:13 -04007;; Package: vc
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +00008
9;; This file is part of GNU Emacs.
10
eb3fa2cf Glenn Morris2008-05-06 08:06:51 +000011;; GNU Emacs is free software: you can redistribute it and/or modify
ab882ed2 Glenn Morris2014-12-01 16:32:04 -050012;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
Glenn Morris2008-05-06 08:06:51 +000013;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000015
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
eb3fa2cf Glenn Morris2008-05-06 08:06:51 +000022;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000023
24;;; Commentary:
25
f9914e54
ER
Eric S. Raymond2007-10-09 16:54:40 +000026;; Sync'd with Subversion's vc-svn.el as of revision 5801. but this version
27;; has been extensively modified since to handle filesets.
1fd3454a Stefan Monnier2003-05-05 15:42:27 +000028
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000029;;; Code:
30
31(eval-when-compile
32 (require 'vc))
33
8228a275
MH
Mark A. Hershberger2010-02-05 14:20:17 -050034;; Clear up the cache to force vc-call to check again and discover
35;; new functions when we reload this file.
36(put 'SVN 'vc-functions nil)
37
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000038;;;
39;;; Customization options
40;;;
41
67b0de11
CY
Chong Yidong2012-02-25 12:29:09 +080042(defgroup vc-svn nil
43 "VC Subversion (svn) backend."
44 :version "24.1"
45 :group 'vc)
46
f9d5dc48
GM
Glenn Morris2008-11-22 03:27:18 +000047;; FIXME there is also svnadmin.
48(defcustom vc-svn-program "svn"
49 "Name of the SVN executable."
50 :type 'string
67b0de11 Chong Yidong2012-02-25 12:29:09 +080051 :group 'vc-svn)
f9d5dc48 Glenn Morris2008-11-22 03:27:18 +000052
31db8c31
GM
Glenn Morris2013-02-10 17:07:05 -080053;; Might be nice if svn defaulted to non-interactive if stdin not tty.
54;; http://svn.haxx.se/dev/archive-2008-05/0762.shtml
55;; http://svn.haxx.se/dev/archive-2009-04/0094.shtml
56;; Maybe newer ones do?
57(defcustom vc-svn-global-switches (unless (eq system-type 'darwin) ; bug#13513
58 '("--non-interactive"))
59 "Global switches to pass to any SVN command.
60The option \"--non-interactive\" is often needed to prevent SVN
61hanging while prompting for authorization."
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000062 :type '(choice (const :tag "None" nil)
63 (string :tag "Argument String")
64 (repeat :tag "Argument List"
65 :value ("")
66 string))
31db8c31 Glenn Morris2013-02-10 17:07:05 -080067 :version "24.4"
67b0de11 Chong Yidong2012-02-25 12:29:09 +080068 :group 'vc-svn)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000069
70(defcustom vc-svn-register-switches nil
c8d6b4bc Glenn Morris2008-12-04 07:03:53 +000071 "Switches for registering a file into SVN.
1fd3454a Stefan Monnier2003-05-05 15:42:27 +000072A string or list of strings passed to the checkin program by
c8d6b4bc
GM
Glenn Morris2008-12-04 07:03:53 +000073\\[vc-register]. If nil, use the value of `vc-register-switches'.
74If t, use no switches."
75 :type '(choice (const :tag "Unspecified" nil)
76 (const :tag "None" t)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +000077 (string :tag "Argument String")
c8d6b4bc Glenn Morris2008-12-04 07:03:53 +000078 (repeat :tag "Argument List" :value ("") string))
bf247b6e Kim F. Storm2005-02-09 15:50:47 +000079 :version "22.1"
67b0de11 Chong Yidong2012-02-25 12:29:09 +080080 :group 'vc-svn)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +000081
8462aca5
SM
Stefan Monnier2003-07-23 15:34:14 +000082(defcustom vc-svn-diff-switches
83 t ;`svn' doesn't support common args like -c or -b.
84 "String or list of strings specifying extra switches for svn diff under VC.
9751169a Glenn Morris2008-11-30 01:58:06 +000085If nil, use the value of `vc-diff-switches' (or `diff-switches'),
ed68f651
SS
Sam Steingold2011-01-25 11:01:53 -050086together with \"-x --diff-cmd=\"`diff-command' (since 'svn diff'
87does not support the default \"-c\" value of `diff-switches').
88If you want to force an empty list of arguments, use t."
8462aca5
SM
Stefan Monnier2003-07-23 15:34:14 +000089 :type '(choice (const :tag "Unspecified" nil)
90 (const :tag "None" t)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +000091 (string :tag "Argument String")
92 (repeat :tag "Argument List"
93 :value ("")
94 string))
bf247b6e Kim F. Storm2005-02-09 15:50:47 +000095 :version "22.1"
67b0de11 Chong Yidong2012-02-25 12:29:09 +080096 :group 'vc-svn)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +000097
b5a0603e
OF
Oscar Fuentes2015-02-26 15:46:12 +010098(defcustom vc-svn-annotate-switches nil
99 "String or list of strings specifying switches for svn annotate under VC.
100If nil, use the value of `vc-annotate-switches'. If t, use no
101switches."
102 :type '(choice (const :tag "Unspecified" nil)
103 (const :tag "None" t)
104 (string :tag "Argument String")
105 (repeat :tag "Argument List" :value ("") string))
106 :version "25.1"
107 :group 'vc-svn)
108
67141a37 Glenn Morris2010-10-03 14:05:47 -0700109(defcustom vc-svn-header '("\$Id\$")
f9d5dc48 Glenn Morris2008-11-22 03:27:18 +0000110 "Header keywords to be inserted by `vc-insert-headers'."
67141a37 Glenn Morris2010-10-03 14:05:47 -0700111 :version "24.1" ; no longer consult the obsolete vc-header-alist
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000112 :type '(repeat string)
67b0de11 Chong Yidong2012-02-25 12:29:09 +0800113 :group 'vc-svn)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000114
fc2fb30c
SM
Stefan Monnier2007-02-19 19:42:10 +0000115;; We want to autoload it for use by the autoloaded version of
116;; vc-svn-registered, but we want the value to be compiled at startup, not
117;; at dump time.
118;; ;;;###autoload
119(defconst vc-svn-admin-directory
120 (cond ((and (memq system-type '(cygwin windows-nt ms-dos))
ace2fad9
CY
Chong Yidong2006-11-09 03:34:17 +0000121 (getenv "SVN_ASP_DOT_NET_HACK"))
122 "_svn")
123 (t ".svn"))
124 "The name of the \".svn\" subdirectory or its equivalent.")
125
8cdd17b4
ER
Eric S. Raymond2007-07-18 16:32:40 +0000126;;; Properties of the backend
127
70e2f6c7 Eric S. Raymond2008-05-02 17:47:25 +0000128(defun vc-svn-revision-granularity () 'repository)
9c750eba Stefan Monnier2013-09-04 17:09:42 -0400129(defun vc-svn-checkout-model (_files) 'implicit)
70e2f6c7 Eric S. Raymond2008-05-02 17:47:25 +0000130
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000131;;;
132;;; State-querying functions
133;;;
134
ace2fad9
CY
Chong Yidong2006-11-09 03:34:17 +0000135;;; vc-svn-admin-directory is generally not defined when the
136;;; autoloaded function is called.
137
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000138;;;###autoload (defun vc-svn-registered (f)
ace2fad9 Chong Yidong2006-11-09 03:34:17 +0000139;;;###autoload (let ((admin-dir (cond ((and (eq system-type 'windows-nt)
fc2fb30c
SM
Stefan Monnier2007-02-19 19:42:10 +0000140;;;###autoload (getenv "SVN_ASP_DOT_NET_HACK"))
141;;;###autoload "_svn")
142;;;###autoload (t ".svn"))))
b5a53795 Karl Pflästerer2011-02-11 20:12:53 -0500143;;;###autoload (when (vc-find-root f admin-dir)
af314ba0 Christopher Schmidt2013-02-01 18:19:24 +0100144;;;###autoload (load "vc-svn" nil t)
ace2fad9 Chong Yidong2006-11-09 03:34:17 +0000145;;;###autoload (vc-svn-registered f))))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000146
147(defun vc-svn-registered (file)
148 "Check if FILE is SVN registered."
7d043d59 Michael Albinus2014-12-05 21:36:47 +0100149 (setq file (expand-file-name file))
b5a53795 Karl Pflästerer2011-02-11 20:12:53 -0500150 (when (vc-svn-root file)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000151 (with-temp-buffer
152 (cd (file-name-directory file))
04473f67
MA
Michael Albinus2009-08-25 09:05:07 +0000153 (let* (process-file-side-effects
154 (status
df4da7f4
SM
Stefan Monnier2005-12-13 22:25:24 +0000155 (condition-case nil
156 ;; Ignore all errors.
157 (vc-svn-command t t file "status" "-v")
158 ;; Some problem happened. E.g. We can't find an `svn'
159 ;; executable. We used to only catch `file-error' but when
160 ;; the process is run on a remote host via Tramp, the error
161 ;; is only reported via the exit status which is turned into
162 ;; an `error' by vc-do-command.
163 (error nil))))
164 (when (eq 0 status)
b5e791bd
DN
Dan Nicolaescu2008-01-20 19:56:43 +0000165 (let ((parsed (vc-svn-parse-status file)))
166 (and parsed (not (memq parsed '(ignored unregistered))))))))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000167
b3298507 Karl Fogel2014-12-03 14:23:26 -0600168(defun vc-svn-state (file)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000169 "SVN-specific version of `vc-state'."
04473f67 Michael Albinus2009-08-25 09:05:07 +0000170 (let (process-file-side-effects)
04473f67
MA
Michael Albinus2009-08-25 09:05:07 +0000171 (with-temp-buffer
172 (cd (file-name-directory file))
b3298507 Karl Fogel2014-12-03 14:23:26 -0600173 (vc-svn-command t 0 file "status" "-v")
04473f67 Michael Albinus2009-08-25 09:05:07 +0000174 (vc-svn-parse-status file))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000175
a80a6b03
GM
Glenn Morris2008-10-04 20:24:24 +0000176;; FIXME it would be better not to have the "remote" argument,
177;; but to distinguish the two output formats based on content.
255d2a5a Dmitry Gutov2015-01-16 06:24:09 +0300178;; FIXME: the local format isn't used by the (sole) caller anymore.
a80a6b03 Glenn Morris2008-10-04 20:24:24 +0000179(defun vc-svn-after-dir-status (callback &optional remote)
c222c25f Dan Nicolaescu2008-01-19 16:32:23 +0000180 (let ((state-map '((?A . added)
b2ee56c9 Stefan Monnier2008-04-11 15:59:22 +0000181 (?C . conflict)
b2ee56c9
SM
Stefan Monnier2008-04-11 15:59:22 +0000182 (?I . ignored)
183 (?M . edited)
e6c01f09 Stefan Monnier2009-05-05 04:17:27 +0000184 (?D . removed)
b2ee56c9
SM
Stefan Monnier2008-04-11 15:59:22 +0000185 (?R . removed)
186 (?? . unregistered)
187 ;; This is what vc-svn-parse-status does.
188 (?~ . edited)))
5dd4f3f7
GM
Glenn Morris2011-01-18 19:49:00 -0800189 (re (if remote "^\\(.\\)\\(.\\).....? \\([ *]\\) +\\(?:[-0-9]+\\)? \\(.*\\)$"
190 ;; Subexp 3 is a dummy in this case, so the numbers match.
f0db3488 Stefan Monnier2014-10-02 20:42:28 -0400191 "^\\(.\\)\\(.\\)...\\(.\\).? \\(.*\\)$"))
c222c25f
DN
Dan Nicolaescu2008-01-19 16:32:23 +0000192 result)
193 (goto-char (point-min))
a80a6b03 Glenn Morris2008-10-04 20:24:24 +0000194 (while (re-search-forward re nil t)
c222c25f Dan Nicolaescu2008-01-19 16:32:23 +0000195 (let ((state (cdr (assq (aref (match-string 1) 0) state-map)))
5dd4f3f7 Glenn Morris2011-01-18 19:49:00 -0800196 (propstat (cdr (assq (aref (match-string 2) 0) state-map)))
614b85f8
VJ
Vagn Johansen2011-03-02 23:27:52 -0800197 (filename (if (memq system-type '(windows-nt ms-dos))
198 (replace-regexp-in-string "\\\\" "/" (match-string 4))
199 (match-string 4))))
dbfb414e
GM
Glenn Morris2011-01-19 23:17:22 -0800200 (and (memq propstat '(conflict edited))
201 (not (eq state 'conflict)) ; conflict always wins
202 (setq state propstat))
5dd4f3f7 Glenn Morris2011-01-18 19:49:00 -0800203 (and remote (string-equal (match-string 3) "*")
a80a6b03
GM
Glenn Morris2008-10-04 20:24:24 +0000204 ;; FIXME are there other possible combinations?
205 (cond ((eq state 'edited) (setq state 'needs-merge))
206 ((not state) (setq state 'needs-update))))
524a655d Dan Nicolaescu2009-04-15 00:32:47 +0000207 (when (and state (not (string= "." filename)))
1b3f2d4e Dan Nicolaescu2008-03-31 15:36:56 +0000208 (setq result (cons (list filename state) result)))))
b2ee56c9 Stefan Monnier2008-04-11 15:59:22 +0000209 (funcall callback result)))
c222c25f Dan Nicolaescu2008-01-19 16:32:23 +0000210
b1a765b3
ER
Eric S. Raymond2014-12-02 10:10:55 -0500211;; dir-status-files called from vc-dir, which loads vc,
212;; which loads vc-dispatcher.
e658d75c
GM
Glenn Morris2013-05-28 00:01:59 -0700213(declare-function vc-exec-after "vc-dispatcher" (code))
214
b1a765b3
ER
Eric S. Raymond2014-12-02 10:10:55 -0500215(autoload 'vc-expand-dirs "vc")
216
af1040b3 Dmitry Gutov2014-12-18 15:47:11 +0200217(defun vc-svn-dir-status-files (_dir files callback)
c222c25f
DN
Dan Nicolaescu2008-01-19 16:32:23 +0000218 "Run 'svn status' for DIR and update BUFFER via CALLBACK.
219CALLBACK is called as (CALLBACK RESULT BUFFER), where
220RESULT is a list of conses (FILE . STATE) for directory DIR."
687ae680 Dmitry Gutov2014-12-18 15:51:34 +0200221 ;; FIXME shouldn't this rather default to all the files in dir?
af1040b3 Dmitry Gutov2014-12-18 15:47:11 +0200222 (apply #'vc-svn-command (current-buffer) 'async nil "status" "-u" files)
255d2a5a Dmitry Gutov2015-01-16 06:24:09 +0300223 (vc-run-delayed (vc-svn-after-dir-status callback t)))
f8e89f19 Dan Nicolaescu2008-01-18 23:45:04 +0000224
be94d713 Glenn Morris2013-09-11 23:53:57 -0700225(defun vc-svn-dir-extra-headers (_dir)
2ec0d864 Eric S. Raymond2008-05-16 18:15:26 +0000226 "Generate extra status headers for a Subversion working copy."
04473f67
MA
Michael Albinus2009-08-25 09:05:07 +0000227 (let (process-file-side-effects)
228 (vc-svn-command "*vc*" 0 nil "info"))
2ec0d864 Eric S. Raymond2008-05-16 18:15:26 +0000229 (let ((repo
def61be2 Juanma Barranquero2008-06-16 08:55:56 +0000230 (save-excursion
2ec0d864
ER
Eric S. Raymond2008-05-16 18:15:26 +0000231 (and (progn
232 (set-buffer "*vc*")
233 (goto-char (point-min))
234 (re-search-forward "Repository Root: *\\(.*\\)" nil t))
235 (match-string 1)))))
236 (concat
237 (cond (repo
238 (concat
239 (propertize "Repository : " 'face 'font-lock-type-face)
240 (propertize repo 'face 'font-lock-variable-name-face)))
241 (t "")))))
242
ac3f4c6f
ER
Eric S. Raymond2007-10-10 18:52:45 +0000243(defun vc-svn-working-revision (file)
244 "SVN-specific version of `vc-working-revision'."
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000245 ;; There is no need to consult RCS headers under SVN, because we
246 ;; get the workfile version for free when we recognize that a file
247 ;; is registered in SVN.
248 (vc-svn-registered file)
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000249 (vc-file-getprop file 'vc-working-revision))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000250
5cc7cb96
SM
Stefan Monnier2003-07-04 22:21:45 +0000251;; vc-svn-mode-line-string doesn't exist because the default implementation
252;; works just fine.
253
9c750eba Stefan Monnier2013-09-04 17:09:42 -0400254(defun vc-svn-previous-revision (_file rev)
cbbd2cd3
TTN
Thien-Thi Nguyen2006-02-06 15:58:38 +0000255 (let ((newrev (1- (string-to-number rev))))
256 (when (< 0 newrev)
257 (number-to-string newrev))))
258
5b5afd50 Eric S. Raymond2007-10-10 19:39:23 +0000259(defun vc-svn-next-revision (file rev)
cbbd2cd3 Thien-Thi Nguyen2006-02-06 15:58:38 +0000260 (let ((newrev (1+ (string-to-number rev))))
5b5afd50 Eric S. Raymond2007-10-10 19:39:23 +0000261 ;; The "working revision" is an uneasy conceptual fit under Subversion;
cbbd2cd3
TTN
Thien-Thi Nguyen2006-02-06 15:58:38 +0000262 ;; we use it as the upper bound until a better idea comes along. If the
263 ;; workfile version W coincides with the tree's latest revision R, then
264 ;; this check prevents a "no such revision: R+1" error. Otherwise, it
265 ;; inhibits showing of W+1 through R, which could be considered anywhere
266 ;; from gracious to impolite.
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000267 (unless (< (string-to-number (vc-file-getprop file 'vc-working-revision))
cbbd2cd3
TTN
Thien-Thi Nguyen2006-02-06 15:58:38 +0000268 newrev)
269 (number-to-string newrev))))
270
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000271
272;;;
273;;; State-changing functions
274;;;
275
8cdd17b4
ER
Eric S. Raymond2007-07-18 16:32:40 +0000276(defun vc-svn-create-repo ()
277 "Create a new SVN repository."
2888a97e Eric S. Raymond2008-05-10 13:27:16 +0000278 (vc-do-command "*vc*" 0 "svnadmin" '("create" "SVN"))
14afa541
GM
Glenn Morris2013-10-09 14:49:32 -0400279 ;; Expand default-directory because svn gets confused by eg
280 ;; file://~/path/to/file. (Bug#15446).
9a4de110 Glenn Morris2011-11-09 21:36:48 -0500281 (vc-svn-command "*vc*" 0 "." "checkout"
7baae811
EZ
Eli Zaretskii2015-06-27 14:27:23 +0300282 (let ((defdir (expand-file-name default-directory)))
283 (concat (if (and (stringp defdir)
284 (eq (aref defdir 0) ?/))
285 "file://"
286 ;; MS-Windows files d:/foo/bar need to
287 ;; begin with 3 leading slashes.
288 "file:///")
289 defdir
290 "SVN"))))
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000291
e658d75c
GM
Glenn Morris2013-05-28 00:01:59 -0700292(autoload 'vc-switches "vc")
293
9e9e3432 Eric S. Raymond2014-12-01 07:08:40 -0500294(defun vc-svn-register (files &optional _comment)
8cdd17b4
ER
Eric S. Raymond2007-07-18 16:32:40 +0000295 "Register FILES into the SVN version-control system.
296The COMMENT argument is ignored This does an add but not a commit.
c8d6b4bc
GM
Glenn Morris2008-12-04 07:03:53 +0000297Passes either `vc-svn-register-switches' or `vc-register-switches'
298to the SVN command."
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000299 (apply 'vc-svn-command nil 0 files "add" (vc-switches 'SVN 'register)))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000300
b5a53795
KP
Karl Pflästerer2011-02-11 20:12:53 -0500301(defun vc-svn-root (file)
302 (vc-find-root file vc-svn-admin-directory))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000303
b5a53795
KP
Karl Pflästerer2011-02-11 20:12:53 -0500304(defalias 'vc-svn-responsible-p 'vc-svn-root)
305
f83109f0 Eric S. Raymond2014-11-20 02:37:06 -0500306(defun vc-svn-checkin (files comment &optional _extra-args-ignored)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000307 "SVN-specific version of `vc-backend-checkin'."
5129f10c Karl Fogel2004-06-04 04:37:10 +0000308 (let ((status (apply
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000309 'vc-svn-command nil 1 files "ci"
5129f10c Karl Fogel2004-06-04 04:37:10 +0000310 (nconc (list "-m" comment) (vc-switches 'SVN 'checkin)))))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000311 (set-buffer "*vc*")
312 (goto-char (point-min))
313 (unless (equal status 0)
314 ;; Check checkin problem.
315 (cond
fd140743 Stefan Monnier2003-05-08 18:31:21 +0000316 ((search-forward "Transaction is out of date" nil t)
8cdd17b4
ER
Eric S. Raymond2007-07-18 16:32:40 +0000317 (mapc (lambda (file) (vc-file-setprop file 'vc-state 'needs-merge))
318 files)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000319 (error (substitute-command-keys
320 (concat "Up-to-date check failed: "
321 "type \\[vc-next-action] to merge in changes"))))
322 (t
323 (pop-to-buffer (current-buffer))
324 (goto-char (point-min))
325 (shrink-window-if-larger-than-buffer)
326 (error "Check-in failed"))))
327 ;; Update file properties
328 ;; (vc-file-setprop
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000329 ;; file 'vc-working-revision
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000330 ;; (vc-parse-buffer "^\\(new\\|initial\\) revision: \\([0-9.]+\\)" 2))
331 ))
332
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000333(defun vc-svn-find-revision (file rev buffer)
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000334 "SVN-specific retrieval of a specified version into a buffer."
04473f67
MA
Michael Albinus2009-08-25 09:05:07 +0000335 (let (process-file-side-effects)
336 (apply 'vc-svn-command
337 buffer 0 file
338 "cat"
339 (and rev (not (string= rev ""))
340 (concat "-r" rev))
341 (vc-switches 'SVN 'checkout))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000342
c799337f Dmitry Gutov2014-10-03 17:15:05 +0400343(defun vc-svn-ignore (file &optional directory remove)
ab419665 Xue Fuqiao2013-08-04 10:55:45 +0800344 "Ignore FILE under Subversion.
63191d9f Xue Fuqiao2013-09-04 08:31:13 +0800345FILE is a file wildcard, relative to the root directory of DIRECTORY."
c799337f
DG
Dmitry Gutov2014-10-03 17:15:05 +0400346 (let* ((ignores (vc-svn-ignore-completion-table directory))
347 (file (file-relative-name file directory))
348 (ignores (if remove
349 (delete file ignores)
350 (push file ignores))))
351 (vc-svn-command nil 0 nil nil "propset" "svn:ignore"
352 (mapconcat #'identity ignores "\n")
353 (expand-file-name directory))))
354
355(defun vc-svn-ignore-completion-table (directory)
356 "Return the list of ignored files in DIRECTORY."
357 (with-temp-buffer
358 (vc-svn-command t t nil "propget" "svn:ignore" (expand-file-name directory))
359 (split-string (buffer-string))))
ab419665 Xue Fuqiao2013-08-04 10:55:45 +0800360
34ca0f4c
XF
Xue Fuqiao2013-10-05 07:47:00 +0800361(defun vc-svn-find-admin-dir (file)
362 "Return the administrative directory of FILE."
363 (expand-file-name vc-svn-admin-directory (vc-svn-root file)))
364
e7e9dbcc Eric S. Raymond2014-11-20 03:52:24 -0500365(defun vc-svn-checkout (file &optional rev)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000366 (message "Checking out %s..." file)
367 (with-current-buffer (or (get-file-buffer file) (current-buffer))
e7e9dbcc Eric S. Raymond2014-11-20 03:52:24 -0500368 (vc-svn-update file rev (vc-switches 'SVN 'checkout)))
77bf3f54 Dan Nicolaescu2009-06-23 06:35:40 +0000369 (vc-mode-line file 'SVN)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000370 (message "Checking out %s...done" file))
371
e7e9dbcc Eric S. Raymond2014-11-20 03:52:24 -0500372(defun vc-svn-update (file rev switches)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000373 (if (and (file-exists-p file) (not rev))
fc2fb30c
SM
Stefan Monnier2007-02-19 19:42:10 +0000374 ;; If no revision was specified, there's nothing to do.
375 nil
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000376 ;; Check out a particular version (or recreate the file).
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000377 (vc-file-setprop file 'vc-working-revision nil)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000378 (apply 'vc-svn-command nil 0 file
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000379 "update"
5cc7cb96
SM
Stefan Monnier2003-07-04 22:21:45 +0000380 (cond
381 ((null rev) "-rBASE")
382 ((or (eq rev t) (equal rev "")) nil)
383 (t (concat "-r" rev)))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000384 switches)))
385
3bdc13e4
SM
Stefan Monnier2003-05-14 19:38:39 +0000386(defun vc-svn-delete-file (file)
387 (vc-svn-command nil 0 file "remove"))
388
2766aaaf
SM
Stefan Monnier2003-05-09 14:13:40 +0000389(defun vc-svn-rename-file (old new)
390 (vc-svn-command nil 0 new "move" (file-relative-name old)))
391
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000392(defun vc-svn-revert (file &optional contents-done)
393 "Revert FILE to the version it was based on."
394 (unless contents-done
fc2fb30c Stefan Monnier2007-02-19 19:42:10 +0000395 (vc-svn-command nil 0 file "revert")))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000396
d17bae90
ER
Eric S. Raymond2014-12-01 11:41:45 -0500397(defun vc-svn-merge-file (file)
398 "Accept a file merge request, prompting for revisions."
399 (let* ((first-revision
400 (vc-read-revision
401 (concat "Merge " file
402 " from SVN revision "
403 "(default news on current branch): ")
404 (list file)
405 'SVN))
406 second-revision
407 status)
408 (cond
409 ((string= first-revision "")
410 (setq status (vc-svn-merge-news file)))
411 (t
412 (setq second-revision
413 (vc-read-revision
414 "Second SVN revision: "
415 (list file) 'SVN nil
416 first-revision))
417 (setq status (vc-svn-merge file first-revision second-revision))))
418 status))
419
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000420(defun vc-svn-merge (file first-version &optional second-version)
421 "Merge changes into current working copy of FILE.
422The changes are between FIRST-VERSION and SECOND-VERSION."
423 (vc-svn-command nil 0 file
c217cb04 Stefan Monnier2003-05-05 16:13:04 +0000424 "merge"
02610d0e Stefan Monnier2003-05-05 16:13:39 +0000425 "-r" (if second-version
c217cb04
SM
Stefan Monnier2003-05-05 16:13:04 +0000426 (concat first-version ":" second-version)
427 first-version))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000428 (vc-file-setprop file 'vc-state 'edited)
429 (with-current-buffer (get-buffer "*vc*")
430 (goto-char (point-min))
c217cb04
SM
Stefan Monnier2003-05-05 16:13:04 +0000431 (if (looking-at "C ")
432 1 ; signal conflict
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000433 0))) ; signal success
434
435(defun vc-svn-merge-news (file)
436 "Merge in any new changes made to FILE."
437 (message "Merging changes into %s..." file)
ac3f4c6f Eric S. Raymond2007-10-10 18:52:45 +0000438 ;; (vc-file-setprop file 'vc-working-revision nil)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000439 (vc-file-setprop file 'vc-checkout-time 0)
9a4de110 Glenn Morris2011-11-09 21:36:48 -0500440 (vc-svn-command nil 0 file "update")
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000441 ;; Analyze the merge result reported by SVN, and set
442 ;; file properties accordingly.
443 (with-current-buffer (get-buffer "*vc*")
444 (goto-char (point-min))
5b5afd50 Eric S. Raymond2007-10-10 19:39:23 +0000445 ;; get new working revision
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000446 (if (re-search-forward
1468d754 Stefan Monnier2003-05-05 16:06:10 +0000447 "^\\(Updated to\\|At\\) revision \\([0-9]+\\)" nil t)
ac3f4c6f
ER
Eric S. Raymond2007-10-10 18:52:45 +0000448 (vc-file-setprop file 'vc-working-revision (match-string 2))
449 (vc-file-setprop file 'vc-working-revision nil))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000450 ;; get file status
1468d754 Stefan Monnier2003-05-05 16:06:10 +0000451 (goto-char (point-min))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000452 (prog1
1468d754 Stefan Monnier2003-05-05 16:06:10 +0000453 (if (looking-at "At revision")
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000454 0 ;; there were no news; indicate success
455 (if (re-search-forward
459b1fe4
SM
Stefan Monnier2007-02-07 23:02:12 +0000456 ;; Newer SVN clients have 3 columns of chars (one for the
457 ;; file's contents, then second for its properties, and the
458 ;; third for lock-grabbing info), before the 2 spaces.
459 ;; We also used to match the filename in column 0 without any
460 ;; meta-info before it, but I believe this can never happen.
461 (concat "^\\(\\([ACGDU]\\)\\(.[B ]\\)? \\)"
c2d07557 Chong Yidong2012-11-17 15:06:57 +0800462 (regexp-quote (file-relative-name file)))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000463 nil t)
464 (cond
465 ;; Merge successful, we are in sync with repository now
459b1fe4 Stefan Monnier2007-02-07 23:02:12 +0000466 ((string= (match-string 2) "U")
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000467 (vc-file-setprop file 'vc-state 'up-to-date)
468 (vc-file-setprop file 'vc-checkout-time
469 (nth 5 (file-attributes file)))
470 0);; indicate success to the caller
471 ;; Merge successful, but our own changes are still in the file
459b1fe4 Stefan Monnier2007-02-07 23:02:12 +0000472 ((string= (match-string 2) "G")
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000473 (vc-file-setprop file 'vc-state 'edited)
474 0);; indicate success to the caller
475 ;; Conflicts detected!
476 (t
477 (vc-file-setprop file 'vc-state 'edited)
478 1);; signal the error to the caller
479 )
480 (pop-to-buffer "*vc*")
481 (error "Couldn't analyze svn update result")))
482 (message "Merging changes into %s...done" file))))
483
9c750eba Stefan Monnier2013-09-04 17:09:42 -0400484(defun vc-svn-modify-change-comment (_files rev comment)
42a0a135
ER
Eric S. Raymond2008-01-02 00:42:37 +0000485 "Modify the change comments for a specified REV.
486You must have ssh access to the repository host, and the directory Emacs
e09deae9 Chong Yidong2008-12-03 03:25:15 +0000487uses locally for temp files must also be writable by you on that host.
fd064451
DN
Dan Nicolaescu2008-04-09 03:38:39 +0000488This is only supported if the repository access method is either file://
489or svn+ssh://."
490 (let (tempfile host remotefile directory fileurl-p)
42a0a135 Eric S. Raymond2008-01-02 00:42:37 +0000491 (with-temp-buffer
9a4de110 Glenn Morris2011-11-09 21:36:48 -0500492 (vc-svn-command (current-buffer) 0 nil "info")
fd064451
DN
Dan Nicolaescu2008-04-09 03:38:39 +0000493 (goto-char (point-min))
494 (unless (re-search-forward "Repository Root: \\(file://\\(/.*\\)\\)\\|\\(svn\\+ssh://\\([^/]+\\)\\(/.*\\)\\)" nil t)
495 (error "Repository information is unavailable"))
496 (if (match-string 1)
497 (progn
498 (setq fileurl-p t)
499 (setq directory (match-string 2)))
500 (setq host (match-string 4))
501 (setq directory (match-string 5))
502 (setq remotefile (concat host ":" tempfile))))
503 (with-temp-file (setq tempfile (make-temp-file user-mail-address))
504 (insert comment))
505 (if fileurl-p
506 ;; Repository Root is a local file.
507 (progn
508 (unless (vc-do-command
2888a97e Eric S. Raymond2008-05-10 13:27:16 +0000509 "*vc*" 0 "svnadmin" nil
def61be2 Juanma Barranquero2008-06-16 08:55:56 +0000510 "setlog" "--bypass-hooks" directory
fd064451
DN
Dan Nicolaescu2008-04-09 03:38:39 +0000511 "-r" rev (format "%s" tempfile))
512 (error "Log edit failed"))
513 (delete-file tempfile))
514
515 ;; Remote repository, using svn+ssh.
2888a97e Eric S. Raymond2008-05-10 13:27:16 +0000516 (unless (vc-do-command "*vc*" 0 "scp" nil "-q" tempfile remotefile)
fd064451
DN
Dan Nicolaescu2008-04-09 03:38:39 +0000517 (error "Copy of comment to %s failed" remotefile))
518 (unless (vc-do-command
2888a97e Eric S. Raymond2008-05-10 13:27:16 +0000519 "*vc*" 0 "ssh" nil "-q" host
fd064451
DN
Dan Nicolaescu2008-04-09 03:38:39 +0000520 (format "svnadmin setlog --bypass-hooks %s -r %s %s; rm %s"
521 directory rev tempfile tempfile))
522 (error "Log edit failed")))))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000523
524;;;
525;;; History functions
526;;;
527
def61be2
JB
Juanma Barranquero2008-06-16 08:55:56 +0000528(defvar log-view-per-file-logs)
529
6653c6b7
DN
Dan Nicolaescu2008-06-15 14:58:24 +0000530(define-derived-mode vc-svn-log-view-mode log-view-mode "SVN-Log-View"
531 (require 'add-log)
532 (set (make-local-variable 'log-view-per-file-logs) nil))
533
e658d75c
GM
Glenn Morris2013-05-28 00:01:59 -0700534(autoload 'vc-setup-buffer "vc-dispatcher")
535
9c750eba Stefan Monnier2013-09-04 17:09:42 -0400536(defun vc-svn-print-log (files buffer &optional _shortlog start-revision limit)
bb7cdf58
GM
Glenn Morris2013-04-24 00:52:00 -0700537 "Print commit log associated with FILES into specified BUFFER.
538SHORTLOG is ignored.
539If START-REVISION is non-nil, it is the newest revision to show.
540If LIMIT is non-nil, show no more than this many entries."
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000541 (save-current-buffer
b349012b Juanma Barranquero2004-04-20 16:49:26 +0000542 (vc-setup-buffer buffer)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000543 (let ((inhibit-read-only t))
544 (goto-char (point-min))
13b56025
ER
Eric S. Raymond2007-12-27 03:10:52 +0000545 (if files
546 (dolist (file files)
547 (insert "Working file: " file "\n")
6616006b
DN
Dan Nicolaescu2009-11-15 20:28:58 +0000548 (apply
549 'vc-svn-command
13b56025
ER
Eric S. Raymond2007-12-27 03:10:52 +0000550 buffer
551 'async
13b56025
ER
Eric S. Raymond2007-12-27 03:10:52 +0000552 (list file)
553 "log"
662c5698
DN
Dan Nicolaescu2009-12-07 09:02:11 +0000554 (append
555 (list
556 (if start-revision
90b4237a Glenn Morris2013-04-24 00:59:29 -0700557 (format "-r%s:1" start-revision)
662c5698
DN
Dan Nicolaescu2009-12-07 09:02:11 +0000558 ;; By default Subversion only shows the log up to the
559 ;; working revision, whereas we also want the log of the
560 ;; subsequent commits. At least that's what the
561 ;; vc-cvs.el code does.
562 "-rHEAD:0"))
1db3226b Glenn Morris2010-01-14 19:54:36 -0800563 (when limit (list "--limit" (format "%s" limit))))))
13b56025 Eric S. Raymond2007-12-27 03:10:52 +0000564 ;; Dump log for the entire directory.
662c5698
DN
Dan Nicolaescu2009-12-07 09:02:11 +0000565 (apply 'vc-svn-command buffer 0 nil "log"
566 (append
567 (list
568 (if start-revision (format "-r%s" start-revision) "-rHEAD:0"))
1db3226b Glenn Morris2010-01-14 19:54:36 -0800569 (when limit (list "--limit" (format "%s" limit)))))))))
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000570
01b97f9d Dmitry Gutov2014-12-14 12:49:08 +0200571(defun vc-svn-diff (files &optional oldvers newvers buffer async)
5b5afd50 Eric S. Raymond2007-10-10 19:39:23 +0000572 "Get a difference report using SVN between two revisions of fileset FILES."
22b5692c
NR
Nick Roberts2009-02-04 10:49:04 +0000573 (and oldvers
574 (not newvers)
575 files
576 (catch 'no
577 (dolist (f files)
578 (or (equal oldvers (vc-working-revision f))
579 (throw 'no nil)))
580 t)
581 ;; Use nil rather than the current revision because svn handles
582 ;; it better (i.e. locally). Note that if _any_ of the files
583 ;; has a different revision, we fetch the lot, which is
584 ;; obviously sub-optimal.
585 (setq oldvers nil))
3c07d7f0 Eric S. Raymond2014-12-13 06:15:33 -0500586 (setq async (and async (or oldvers newvers))) ; Svn diffs those locally.
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000587 (let* ((switches
f9d1f3be
SM
Stefan Monnier2004-08-23 18:23:52 +0000588 (if vc-svn-diff-switches
589 (vc-switches 'SVN 'diff)
ed68f651 Sam Steingold2011-01-25 11:01:53 -0500590 (list (concat "--diff-cmd=" diff-command) "-x"
3c07d7f0 Eric S. Raymond2014-12-13 06:15:33 -0500591 (mapconcat 'identity (vc-switches nil 'diff) " ")))))
b349012b Juanma Barranquero2004-04-20 16:49:26 +0000592 (apply 'vc-svn-command buffer
2766aaaf Stefan Monnier2003-05-09 14:13:40 +0000593 (if async 'async 0)
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000594 files "diff"
2766aaaf Stefan Monnier2003-05-09 14:13:40 +0000595 (append
f9d1f3be Stefan Monnier2004-08-23 18:23:52 +0000596 switches
2766aaaf
SM
Stefan Monnier2003-05-09 14:13:40 +0000597 (when oldvers
598 (list "-r" (if newvers (concat oldvers ":" newvers)
599 oldvers)))))
fd140743
SM
Stefan Monnier2003-05-08 18:31:21 +0000600 (if async 1 ; async diff => pessimistic assumption
601 ;; For some reason `svn diff' does not return a useful
602 ;; status w.r.t whether the diff was empty or not.
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000603 (buffer-size (get-buffer buffer)))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000604
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000605;;;
370fded4 Eric S. Raymond2008-05-15 17:38:50 +0000606;;; Tag system
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000607;;;
608
370fded4 Eric S. Raymond2008-05-15 17:38:50 +0000609(defun vc-svn-create-tag (dir name branchp)
5b5afd50 Eric S. Raymond2007-10-10 19:39:23 +0000610 "Assign to DIR's current revision a given NAME.
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000611If BRANCHP is non-nil, the name is created as a branch (and the current
5cc7cb96
SM
Stefan Monnier2003-07-04 22:21:45 +0000612workspace is immediately moved to that new branch).
613NAME is assumed to be a URL."
614 (vc-svn-command nil 0 dir "copy" name)
370fded4 Eric S. Raymond2008-05-15 17:38:50 +0000615 (when branchp (vc-svn-retrieve-tag dir name nil)))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000616
aa30fa6f Glenn Morris2013-09-11 23:55:15 -0700617(defun vc-svn-retrieve-tag (dir name _update)
370fded4
ER
Eric S. Raymond2008-05-15 17:38:50 +0000618 "Retrieve a tag at and below DIR.
619NAME is the name of the tag; if it is empty, do a `svn update'.
5cc7cb96
SM
Stefan Monnier2003-07-04 22:21:45 +0000620If UPDATE is non-nil, then update (resynch) any affected buffers.
621NAME is assumed to be a URL."
622 (vc-svn-command nil 0 dir "switch" name)
623 ;; FIXME: parse the output and obey `update'.
624 )
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000625
626;;;
627;;; Miscellaneous
628;;;
629
630;; Subversion makes backups for us, so don't bother.
77bf3f54
DN
Dan Nicolaescu2009-06-23 06:35:40 +0000631;; (defun vc-svn-make-version-backups-p (file)
632;; "Return non-nil if version backups should be made for FILE."
2a81c5d9 Eric S. Raymond2014-12-01 10:11:42 -0500633;; nil)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000634
635(defun vc-svn-check-headers ()
636 "Check if the current file has any headers in it."
637 (save-excursion
638 (goto-char (point-min))
639 (re-search-forward "\\$[A-Za-z\300-\326\330-\366\370-\377]+\
640\\(: [\t -#%-\176\240-\377]*\\)?\\$" nil t)))
641
642
643;;;
644;;; Internal functions
645;;;
646
8cdd17b4 Eric S. Raymond2007-07-18 16:32:40 +0000647(defun vc-svn-command (buffer okstatus file-or-list &rest flags)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000648 "A wrapper around `vc-do-command' for use in vc-svn.el.
649The difference to vc-do-command is that this function always invokes `svn',
31db8c31 Glenn Morris2013-02-10 17:07:05 -0800650and that it passes `vc-svn-global-switches' to it before FLAGS."
9a4de110 Glenn Morris2011-11-09 21:36:48 -0500651 (apply 'vc-do-command (or buffer "*vc*") okstatus vc-svn-program file-or-list
31db8c31
GM
Glenn Morris2013-02-10 17:07:05 -0800652 (if (stringp vc-svn-global-switches)
653 (cons vc-svn-global-switches flags)
654 (append vc-svn-global-switches flags))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000655
1c67a814
SM
Stefan Monnier2007-09-28 18:45:43 +0000656(defun vc-svn-resolve-when-done ()
657 "Call \"svn resolved\" if the conflict markers have been removed."
658 (save-excursion
659 (goto-char (point-min))
54648b5c
DN
Dan Nicolaescu2008-01-15 04:37:20 +0000660 (unless (re-search-forward "^<<<<<<< " nil t)
661 (vc-svn-command nil 0 buffer-file-name "resolved")
662 ;; Remove the hook so that it is not called multiple times.
663 (remove-hook 'after-save-hook 'vc-svn-resolve-when-done t))))
1c67a814
SM
Stefan Monnier2007-09-28 18:45:43 +0000664
665;; Inspired by vc-arch-find-file-hook.
666(defun vc-svn-find-file-hook ()
667 (when (eq ?C (vc-file-getprop buffer-file-name 'vc-svn-status))
668 ;; If the file is marked as "conflicted", then we should try and call
669 ;; "svn resolved" when applicable.
670 (if (save-excursion
671 (goto-char (point-min))
672 (re-search-forward "^<<<<<<< " nil t))
673 ;; There are conflict markers.
674 (progn
28e4e2b4 Dan Nicolaescu2008-01-16 06:22:59 +0000675 (smerge-start-session)
1c67a814
SM
Stefan Monnier2007-09-28 18:45:43 +0000676 (add-hook 'after-save-hook 'vc-svn-resolve-when-done nil t))
677 ;; There are no conflict markers. This is problematic: maybe it means
678 ;; the conflict has been resolved and we should immediately call "svn
679 ;; resolved", or it means that the file's type does not allow Svn to
680 ;; use conflict markers in which case we don't really know what to do.
681 ;; So let's just punt for now.
682 nil)
683 (message "There are unresolved conflicts in this file")))
684
bc8c1bb4 Stefan Monnier2006-10-20 07:56:20 +0000685(defun vc-svn-parse-status (&optional filename)
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000686 "Parse output of \"svn status\" command in the current buffer.
a6ae021f
GM
Glenn Morris2013-09-11 23:21:33 -0700687Set file properties accordingly. If FILENAME is non-nil, return its status."
688 (let (multifile file status propstat)
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000689 (goto-char (point-min))
690 (while (re-search-forward
484c1b1f Eric S. Raymond2007-12-29 13:20:49 +0000691 ;; Ignore the files with status X.
245cacf1 Dan Nicolaescu2008-08-06 16:49:23 +0000692 "^\\(?:\\?\\|[ ACDGIMR!~][ MC][ L][ +][ S]..\\([ *]\\) +\\([-0-9]+\\) +\\([0-9?]+\\) +\\([^ ]+\\)\\) +" nil t)
c45b3be3
SM
Stefan Monnier2007-01-14 14:49:28 +0000693 ;; If the username contains spaces, the output format is ambiguous,
694 ;; so don't trust the output's filename unless we have to.
a6ae021f Glenn Morris2013-09-11 23:21:33 -0700695 (setq file (or (unless multifile filename)
c45b3be3 Stefan Monnier2007-01-14 14:49:28 +0000696 (expand-file-name
a6ae021f
GM
Glenn Morris2013-09-11 23:21:33 -0700697 (buffer-substring (point) (line-end-position))))
698 ;; If we are parsing the result of running status on a directory,
699 ;; there could be multiple files in the output.
700 ;; We assume that filename, if supplied, applies to the first
701 ;; listed file (ie, the directory). Bug#15322.
702 multifile t
703 status (char-after (line-beginning-position))
5dd4f3f7
GM
Glenn Morris2011-01-18 19:49:00 -0800704 ;; Status of the item's properties ([ MC]).
705 propstat (char-after (1+ (line-beginning-position))))
484c1b1f Eric S. Raymond2007-12-29 13:20:49 +0000706 (if (eq status ??)
4f07b9f2 Eric S. Raymond2008-01-01 18:40:42 +0000707 (vc-file-setprop file 'vc-state 'unregistered)
fd140743
SM
Stefan Monnier2003-05-08 18:31:21 +0000708 ;; Use the last-modified revision, so that searching in vc-print-log
709 ;; output works.
4f07b9f2 Eric S. Raymond2008-01-01 18:40:42 +0000710 (vc-file-setprop file 'vc-working-revision (match-string 3))
1c67a814 Stefan Monnier2007-09-28 18:45:43 +0000711 ;; Remember Svn's own status.
4f07b9f2
ER
Eric S. Raymond2008-01-01 18:40:42 +0000712 (vc-file-setprop file 'vc-svn-status status)
713 (vc-file-setprop
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000714 file 'vc-state
715 (cond
5dd4f3f7 Glenn Morris2011-01-18 19:49:00 -0800716 ((and (eq status ?\ ) (eq propstat ?\ ))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000717 (if (eq (char-after (match-beginning 1)) ?*)
3702367b Eric S. Raymond2008-05-01 19:13:16 +0000718 'needs-update
4f07b9f2 Eric S. Raymond2008-01-01 18:40:42 +0000719 (vc-file-setprop file 'vc-checkout-time
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000720 (nth 5 (file-attributes file)))
721 'up-to-date))
722 ((eq status ?A)
fd140743 Stefan Monnier2003-05-08 18:31:21 +0000723 ;; If the file was actually copied, (match-string 2) is "-".
4f07b9f2
ER
Eric S. Raymond2008-01-01 18:40:42 +0000724 (vc-file-setprop file 'vc-working-revision "0")
725 (vc-file-setprop file 'vc-checkout-time 0)
484c1b1f Eric S. Raymond2007-12-29 13:20:49 +0000726 'added)
5dd4f3f7
GM
Glenn Morris2011-01-18 19:49:00 -0800727 ;; Conflict in contents or properties.
728 ((or (eq status ?C) (eq propstat ?C))
7fbb4797 Dan Nicolaescu2008-04-10 07:32:25 +0000729 (vc-file-setprop file 'vc-state 'conflict))
5dd4f3f7
GM
Glenn Morris2011-01-18 19:49:00 -0800730 ;; Modified contents or properties.
731 ((or (eq status ?M) (eq propstat ?M))
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000732 (if (eq (char-after (match-beginning 1)) ?*)
733 'needs-merge
734 'edited))
722f037f Eric S. Raymond2007-12-28 18:16:55 +0000735 ((eq status ?I)
4f07b9f2 Eric S. Raymond2008-01-01 18:40:42 +0000736 (vc-file-setprop file 'vc-state 'ignored))
e6c01f09 Stefan Monnier2009-05-05 04:17:27 +0000737 ((memq status '(?D ?R))
4f07b9f2 Eric S. Raymond2008-01-01 18:40:42 +0000738 (vc-file-setprop file 'vc-state 'removed))
bc8c1bb4 Stefan Monnier2006-10-20 07:56:20 +0000739 (t 'edited)))))
245cacf1 Dan Nicolaescu2008-08-06 16:49:23 +0000740 (when filename (vc-file-getprop filename 'vc-state))))
1fd3454a Stefan Monnier2003-05-05 15:42:27 +0000741
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000742(defun vc-svn-valid-symbolic-tag-name-p (tag)
743 "Return non-nil if TAG is a valid symbolic tag name."
744 ;; According to the SVN manual, a valid symbolic tag must start with
745 ;; an uppercase or lowercase letter and can contain uppercase and
746 ;; lowercase letters, digits, `-', and `_'.
747 (and (string-match "^[a-zA-Z]" tag)
748 (not (string-match "[^a-z0-9A-Z-_]" tag))))
749
5b5afd50
ER
Eric S. Raymond2007-10-10 19:39:23 +0000750(defun vc-svn-valid-revision-number-p (tag)
751 "Return non-nil if TAG is a valid revision number."
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000752 (and (string-match "^[0-9]" tag)
753 (not (string-match "[^0-9]" tag))))
754
17a5a301
SM
Stefan Monnier2004-12-13 06:30:40 +0000755;; Support for `svn annotate'
756
757(defun vc-svn-annotate-command (file buf &optional rev)
b5a0603e
OF
Oscar Fuentes2015-02-26 15:46:12 +0100758 (apply #'vc-svn-command buf 'async file "annotate"
759 (append (vc-switches 'svn 'annotate)
760 (if rev (list (concat "-r" rev))))))
17a5a301
SM
Stefan Monnier2004-12-13 06:30:40 +0000761
762(defun vc-svn-annotate-time-of-rev (rev)
da6062e6 Paul Eggert2011-11-14 23:55:13 -0800763 ;; Arbitrarily assume 10 commits per day.
17a5a301
SM
Stefan Monnier2004-12-13 06:30:40 +0000764 (/ (string-to-number rev) 10.0))
765
e53ac718
DN
Dan Nicolaescu2008-06-25 02:45:50 +0000766(defvar vc-annotate-parent-rev)
767
17a5a301
SM
Stefan Monnier2004-12-13 06:30:40 +0000768(defun vc-svn-annotate-current-time ()
769 (vc-svn-annotate-time-of-rev vc-annotate-parent-rev))
770
771(defconst vc-svn-annotate-re "[ \t]*\\([0-9]+\\)[ \t]+[^\t ]+ ")
772
773(defun vc-svn-annotate-time ()
774 (when (looking-at vc-svn-annotate-re)
775 (goto-char (match-end 0))
776 (vc-svn-annotate-time-of-rev (match-string 1))))
777
778(defun vc-svn-annotate-extract-revision-at-line ()
779 (save-excursion
780 (beginning-of-line)
781 (if (looking-at vc-svn-annotate-re) (match-string 1))))
782
8228a275
MH
Mark A. Hershberger2010-02-05 14:20:17 -0500783(defun vc-svn-revision-table (files)
784 (let ((vc-svn-revisions '()))
785 (with-current-buffer "*vc*"
786 (vc-svn-command nil 0 files "log" "-q")
787 (goto-char (point-min))
788 (forward-line)
789 (let ((start (point-min))
790 (loglines (buffer-substring-no-properties (point-min)
791 (point-max))))
792 (while (string-match "^r\\([0-9]+\\) " loglines)
793 (push (match-string 1 loglines) vc-svn-revisions)
794 (setq start (+ start (match-end 0)))
795 (setq loglines (buffer-substring-no-properties start (point-max)))))
796 vc-svn-revisions)))
797
1fd3454a
SM
Stefan Monnier2003-05-05 15:42:27 +0000798(provide 'vc-svn)
799
800;;; vc-svn.el ends here