comparison lisp/vc-svn.el @ 50927:6f478e2878c7

(vc-svn-rename-file): New fun. (vc-svn-diff): Correctly check svn's return status. (vc-svn-state, vc-svn-dir-state, vc-svn-print-log, vc-svn-diff) (vc-svn-diff-tree): Use vc-stay-local-p. (vc-svn-register-switches, vc-svn-diff-switches, vc-svn-header) (vc-svn-use-edit): Fix the :version property. (vc-svn-stay-local): Remove unused var. (vc-svn-mode-line-string): Remove, use the default instead. (vc-svn-repository-hostname): New fun taken from vc-svn-stay-local-p. (vc-svn-stay-local-p): Remove.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 09 May 2003 16:41:19 +0000
parents bdc62a6694f7
children c09edac18f97
comparison
equal deleted inserted replaced
50926:dd6110a63907 50927:6f478e2878c7
60 :type '(choice (const :tag "None" nil) 60 :type '(choice (const :tag "None" nil)
61 (string :tag "Argument String") 61 (string :tag "Argument String")
62 (repeat :tag "Argument List" 62 (repeat :tag "Argument List"
63 :value ("") 63 :value ("")
64 string)) 64 string))
65 :version "21.1" 65 :version "21.4"
66 :group 'vc) 66 :group 'vc)
67 67
68 (defcustom vc-svn-diff-switches nil 68 (defcustom vc-svn-diff-switches nil
69 "*A string or list of strings specifying extra switches for svn diff under VC." 69 "*A string or list of strings specifying extra switches for svn diff under VC."
70 :type '(choice (const :tag "None" nil) 70 :type '(choice (const :tag "None" nil)
71 (string :tag "Argument String") 71 (string :tag "Argument String")
72 (repeat :tag "Argument List" 72 (repeat :tag "Argument List"
73 :value ("") 73 :value ("")
74 string)) 74 string))
75 :version "21.1" 75 :version "21.4"
76 :group 'vc) 76 :group 'vc)
77 77
78 (defcustom vc-svn-header (or (cdr (assoc 'SVN vc-header-alist)) '("\$Id\$")) 78 (defcustom vc-svn-header (or (cdr (assoc 'SVN vc-header-alist)) '("\$Id\$"))
79 "*Header keywords to be inserted by `vc-insert-headers'." 79 "*Header keywords to be inserted by `vc-insert-headers'."
80 :version "21.1" 80 :version "21.4"
81 :type '(repeat string) 81 :type '(repeat string)
82 :group 'vc) 82 :group 'vc)
83 83
84 (defcustom vc-svn-use-edit nil 84 (defcustom vc-svn-use-edit nil
85 "*Non-nil means to use `svn edit' to \"check out\" a file. 85 "*Non-nil means to use `svn edit' to \"check out\" a file.
86 This is only meaningful if you don't use the implicit checkout model 86 This is only meaningful if you don't use the implicit checkout model
87 \(i.e. if you have $SVNREAD set)." 87 \(i.e. if you have $SVNREAD set)."
88 :type 'boolean 88 :type 'boolean
89 :version "21.1" 89 :version "21.4"
90 :group 'vc)
91
92 (defcustom vc-svn-stay-local t
93 "*Non-nil means use local operations when possible for remote repositories.
94 This avoids slow queries over the network and instead uses heuristics
95 and past information to determine the current status of a file.
96
97 The value can also be a regular expression or list of regular
98 expressions to match against the host name of a repository; then VC
99 only stays local for hosts that match it. Alternatively, the value
100 can be a list of regular expressions where the first element is the
101 symbol `except'; then VC always stays local except for hosts matched
102 by these regular expressions."
103 :type '(choice (const :tag "Always stay local" t)
104 (const :tag "Don't stay local" nil)
105 (list :format "\nExamine hostname and %v" :tag "Examine hostname ..."
106 (set :format "%v" :inline t (const :format "%t" :tag "don't" except))
107 (regexp :format " stay local,\n%t: %v" :tag "if it matches")
108 (repeat :format "%v%i\n" :inline t (regexp :tag "or"))))
109 :version "21.1"
110 :group 'vc) 90 :group 'vc)
111 91
112 ;;; 92 ;;;
113 ;;; State-querying functions 93 ;;; State-querying functions
114 ;;; 94 ;;;
132 (vc-svn-parse-status t) 112 (vc-svn-parse-status t)
133 (eq 'SVN (vc-file-getprop file 'vc-backend))))) 113 (eq 'SVN (vc-file-getprop file 'vc-backend)))))
134 114
135 (defun vc-svn-state (file &optional localp) 115 (defun vc-svn-state (file &optional localp)
136 "SVN-specific version of `vc-state'." 116 "SVN-specific version of `vc-state'."
137 (setq localp (or localp (vc-svn-stay-local-p file))) 117 (setq localp (or localp (vc-stay-local-p file)))
138 (with-temp-buffer 118 (with-temp-buffer
139 (cd (file-name-directory file)) 119 (cd (file-name-directory file))
140 (vc-svn-command t 0 file "status" (if localp "-v" "-u")) 120 (vc-svn-command t 0 file "status" (if localp "-v" "-u"))
141 (vc-svn-parse-status localp) 121 (vc-svn-parse-status localp)
142 (vc-file-getprop file 'vc-state))) 122 (vc-file-getprop file 'vc-state)))
145 "SVN-specific state heuristic." 125 "SVN-specific state heuristic."
146 (vc-svn-state file 'local)) 126 (vc-svn-state file 'local))
147 127
148 (defun vc-svn-dir-state (dir &optional localp) 128 (defun vc-svn-dir-state (dir &optional localp)
149 "Find the SVN state of all files in DIR." 129 "Find the SVN state of all files in DIR."
150 (setq localp (or localp (vc-svn-stay-local-p dir))) 130 (setq localp (or localp (vc-stay-local-p dir)))
151 (let ((default-directory dir)) 131 (let ((default-directory dir))
152 ;; Don't specify DIR in this command, the default-directory is 132 ;; Don't specify DIR in this command, the default-directory is
153 ;; enough. Otherwise it might fail with remote repositories. 133 ;; enough. Otherwise it might fail with remote repositories.
154 (with-temp-buffer 134 (with-temp-buffer
155 (vc-svn-command t 0 nil "status" (if localp "-v" "-u")) 135 (vc-svn-command t 0 nil "status" (if localp "-v" "-u"))
165 145
166 (defun vc-svn-checkout-model (file) 146 (defun vc-svn-checkout-model (file)
167 "SVN-specific version of `vc-checkout-model'." 147 "SVN-specific version of `vc-checkout-model'."
168 ;; It looks like Subversion has no equivalent of CVSREAD. 148 ;; It looks like Subversion has no equivalent of CVSREAD.
169 'implicit) 149 'implicit)
170
171 (defun vc-svn-mode-line-string (file)
172 "Return string for placement into the modeline for FILE.
173 Compared to the default implementation, this function does two things:
174 Handle the special case of a SVN file that is added but not yet
175 committed and support display of sticky tags."
176 (let* ((state (vc-state file))
177 (rev (vc-workfile-version file))
178 (sticky-tag (vc-file-getprop file 'vc-svn-sticky-tag))
179 (sticky-tag-printable (and sticky-tag
180 (not (string= sticky-tag ""))
181 (concat "[" sticky-tag "]"))))
182 (cond ((string= rev "0")
183 ;; A file that is added but not yet committed.
184 "SVN @@")
185 ((or (eq state 'up-to-date)
186 (eq state 'needs-patch))
187 (concat "SVN-" rev sticky-tag-printable))
188 ((stringp state)
189 (concat "SVN:" state ":" rev sticky-tag-printable))
190 (t
191 ;; Not just for the 'edited state, but also a fallback
192 ;; for all other states. Think about different symbols
193 ;; for 'needs-patch and 'needs-merge.
194 (concat "SVN:" rev sticky-tag-printable)))))
195 150
196 (defun vc-svn-dired-state-info (file) 151 (defun vc-svn-dired-state-info (file)
197 "SVN-specific version of `vc-dired-state-info'." 152 "SVN-specific version of `vc-dired-state-info'."
198 (let ((svn-state (vc-state file))) 153 (let ((svn-state (vc-state file)))
199 (cond ((eq svn-state 'edited) 154 (cond ((eq svn-state 'edited)
376 (goto-char (point-min)) 331 (goto-char (point-min))
377 ;; Add a line to tell log-view-mode what file this is. 332 ;; Add a line to tell log-view-mode what file this is.
378 (insert "Working file: " (file-relative-name file) "\n")) 333 (insert "Working file: " (file-relative-name file) "\n"))
379 (vc-svn-command 334 (vc-svn-command
380 t 335 t
381 (if (and (vc-svn-stay-local-p file) (fboundp 'start-process)) 'async 0) 336 (if (and (vc-stay-local-p file) (fboundp 'start-process)) 'async 0)
382 file "log"))) 337 file "log")))
383 338
384 (defun vc-svn-diff (file &optional oldvers newvers) 339 (defun vc-svn-diff (file &optional oldvers newvers)
385 "Get a difference report using SVN between two versions of FILE." 340 "Get a difference report using SVN between two versions of FILE."
386 (if (string= (vc-workfile-version file) "0") 341 (if (string= (vc-workfile-version file) "0")
394 1 "diff" file 349 1 "diff" file
395 (append (vc-switches nil 'diff) '("/dev/null"))) 350 (append (vc-switches nil 'diff) '("/dev/null")))
396 ;; Even if it's empty, it's locally modified. 351 ;; Even if it's empty, it's locally modified.
397 1) 352 1)
398 (let* ((switches (vc-switches 'SVN 'diff)) 353 (let* ((switches (vc-switches 'SVN 'diff))
399 (async (and (vc-svn-stay-local-p file) 354 (async (and (vc-stay-local-p file)
400 (or oldvers newvers) ; Svn diffs those locally. 355 (or oldvers newvers) ; Svn diffs those locally.
401 (fboundp 'start-process)))) 356 (fboundp 'start-process))))
402 (apply 'vc-svn-command "*vc-diff*" 357 (apply 'vc-svn-command "*vc-diff*"
403 (if async 'async 0) 358 (if async 'async 0)
404 file "diff" 359 file "diff"
415 370
416 (defun vc-svn-diff-tree (dir &optional rev1 rev2) 371 (defun vc-svn-diff-tree (dir &optional rev1 rev2)
417 "Diff all files at and below DIR." 372 "Diff all files at and below DIR."
418 (with-current-buffer "*vc-diff*" 373 (with-current-buffer "*vc-diff*"
419 (setq default-directory dir) 374 (setq default-directory dir)
420 (if (vc-svn-stay-local-p dir) 375 (if (vc-stay-local-p dir)
421 ;; local diff: do it filewise, and only for files that are modified 376 ;; local diff: do it filewise, and only for files that are modified
422 (vc-file-tree-walk 377 (vc-file-tree-walk
423 dir 378 dir
424 (lambda (f) 379 (lambda (f)
425 (vc-exec-after 380 (vc-exec-after
490 ;;; 445 ;;;
491 ;;; Miscellaneous 446 ;;; Miscellaneous
492 ;;; 447 ;;;
493 448
494 ;; Subversion makes backups for us, so don't bother. 449 ;; Subversion makes backups for us, so don't bother.
495 ;; (defalias 'vc-svn-make-version-backups-p 'vc-svn-stay-local-p 450 ;; (defalias 'vc-svn-make-version-backups-p 'vc-stay-local-p
496 ;; "Return non-nil if version backups should be made for FILE.") 451 ;; "Return non-nil if version backups should be made for FILE.")
497 452
498 (defun vc-svn-check-headers () 453 (defun vc-svn-check-headers ()
499 "Check if the current file has any headers in it." 454 "Check if the current file has any headers in it."
500 (save-excursion 455 (save-excursion
515 (if (stringp vc-svn-global-switches) 470 (if (stringp vc-svn-global-switches)
516 (cons vc-svn-global-switches flags) 471 (cons vc-svn-global-switches flags)
517 (append vc-svn-global-switches 472 (append vc-svn-global-switches
518 flags)))) 473 flags))))
519 474
520 (defun vc-svn-stay-local-p (file) 475 (defun vc-svn-repository-hostname (dirname)
521 "Return non-nil if VC should stay local when handling FILE. 476 (with-temp-buffer
522 See `vc-svn-stay-local'." 477 (let ((coding-system-for-read
523 (when vc-svn-stay-local 478 (or file-name-coding-system
524 (let* ((dirname (if (file-directory-p file) 479 default-file-name-coding-system)))
525 (directory-file-name file) 480 (vc-insert-file (expand-file-name ".svn/entries" dirname)))
526 (file-name-directory file))) 481 (goto-char (point-min))
527 (prop 482 (when (re-search-forward
528 (or (vc-file-getprop dirname 'vc-svn-stay-local-p) 483 (concat "name=\"svn:this_dir\"[\n\t ]*"
529 (vc-file-setprop 484 "\\([-a-z]+=\"[^\"]*\"[\n\t ]*\\)*?"
530 dirname 'vc-svn-stay-local-p 485 "url=\"\\([^\"]+\\)\"") nil t)
531 (let ((rootname (expand-file-name ".svn/entries" dirname))) 486 (match-string 2))))
532 (cond
533 ((not (file-readable-p rootname)) 'no)
534 ((stringp vc-svn-stay-local)
535 (with-temp-buffer
536 (let ((coding-system-for-read
537 (or file-name-coding-system
538 default-file-name-coding-system)))
539 (vc-insert-file rootname))
540 (goto-char (point-min))
541 (when (re-search-forward
542 (concat "name=\"svn:this_dir\"[\n\t ]*"
543 "url=\"\\([^\"]+\\)\"") nil t)
544 (let ((hostname (match-string 1)))
545 (if (not hostname)
546 'no
547 (let* ((stay-local t)
548 (rx
549 (cond
550 ;; vc-svn-stay-local: rx
551 ((stringp vc-svn-stay-local)
552 vc-svn-stay-local)
553 ;; vc-svn-stay-local: '( [except] rx ... )
554 ((consp vc-svn-stay-local)
555 (mapconcat
556 'identity
557 (if (not (eq (car vc-svn-stay-local)
558 'except))
559 vc-svn-stay-local
560 (setq stay-local nil)
561 (cdr vc-svn-stay-local))
562 "\\|")))))
563 (if (not rx)
564 'yes
565 (if (not (string-match rx hostname))
566 (setq stay-local (not stay-local)))
567 (if stay-local
568 'yes
569 'no))))))))
570 ;; vc-svn-stay-local is neither nil nor list nor string.
571 (t 'yes)))))))
572 (if (eq prop 'yes) t nil))))
573 487
574 (defun vc-svn-parse-status (localp) 488 (defun vc-svn-parse-status (localp)
575 "Parse output of \"svn status\" command in the current buffer. 489 "Parse output of \"svn status\" command in the current buffer.
576 Set file properties accordingly. Unless FULL is t, parse only 490 Set file properties accordingly. Unless FULL is t, parse only
577 essential information." 491 essential information."