Mercurial > emacs
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." |