comparison lisp/vc-bzr.el @ 82491:962fb740e73f

Merge from emacs--rel--22 Patches applied: * emacs--rel--22 (patch 93-96) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 245) - Update from CVS Revision: emacs@sv.gnu.org/emacs--devo--0--patch-856
author Miles Bader <miles@gnu.org>
date Tue, 21 Aug 2007 04:51:30 +0000
parents e5a68f18fcb9 8f9613d80af0
children 13fc3289f099 aaccdab0ee26
comparison
equal deleted inserted replaced
82490:458dcdfc3e27 82491:962fb740e73f
57 ;; new functions when we reload this file. 57 ;; new functions when we reload this file.
58 (put 'Bzr 'vc-functions nil) 58 (put 'Bzr 'vc-functions nil)
59 59
60 (defgroup vc-bzr nil 60 (defgroup vc-bzr nil
61 "VC bzr backend." 61 "VC bzr backend."
62 ;; :version "22" 62 :version "22.2"
63 :group 'vc) 63 :group 'vc)
64 64
65 (defcustom vc-bzr-program "bzr" 65 (defcustom vc-bzr-program "bzr"
66 "Name of the bzr command (excluding any arguments)." 66 "Name of the bzr command (excluding any arguments)."
67 :group 'vc-bzr 67 :group 'vc-bzr
129 only parsed if it contains the string `#bazaar dirstate flat 129 only parsed if it contains the string `#bazaar dirstate flat
130 format 3' in the first line. 130 format 3' in the first line.
131 131
132 If the `checkout/dirstate' file cannot be parsed, fall back to 132 If the `checkout/dirstate' file cannot be parsed, fall back to
133 running `vc-bzr-state'." 133 running `vc-bzr-state'."
134 (condition-case nil 134 (lexical-let ((root (vc-bzr-root file)))
135 (lexical-let ((root (vc-bzr-root file))) 135 (when root ; Short cut.
136 (and root ; Short cut. 136 ;; This looks at internal files. May break if they change
137 ;; This looks at internal files. May break if they change 137 ;; their format.
138 ;; their format. 138 (lexical-let ((dirstate (expand-file-name vc-bzr-admin-dirstate root)))
139 (lexical-let 139 (if (not (file-readable-p dirstate))
140 ((dirstate-file (expand-file-name vc-bzr-admin-dirstate root))) 140 (vc-bzr-state file) ; Expensive.
141 (if (file-exists-p dirstate-file) 141 (with-temp-buffer
142 (with-temp-buffer 142 (insert-file-contents dirstate)
143 (insert-file-contents dirstate-file) 143 (goto-char (point-min))
144 (goto-char (point-min)) 144 (if (not (looking-at "#bazaar dirstate flat format 3"))
145 (when (looking-at "#bazaar dirstate flat format 3") 145 (vc-bzr-state file) ; Some other unknown format?
146 (let* ((relfile (file-relative-name file root)) 146 (let* ((relfile (file-relative-name file root))
147 (reldir (file-name-directory relfile))) 147 (reldir (file-name-directory relfile)))
148 (re-search-forward 148 (re-search-forward
149 (concat "^\0" 149 (concat "^\0"
150 (if reldir (regexp-quote (directory-file-name reldir))) 150 (if reldir (regexp-quote (directory-file-name reldir)))
151 "\0" 151 "\0"
152 (regexp-quote (file-name-nondirectory relfile)) 152 (regexp-quote (file-name-nondirectory relfile))
153 "\0") 153 "\0")
154 nil t)))) 154 nil t)))))))))
155 t))
156 (vc-bzr-state file))) ; Expensive.
157 (file-error nil))) ; vc-bzr-program not found
158
159 (defun vc-bzr-buffer-nonblank-p (&optional buffer)
160 "Return non-nil if BUFFER contains any non-blank characters."
161 (or (> (buffer-size buffer) 0)
162 (save-excursion
163 (set-buffer (or buffer (current-buffer)))
164 (goto-char (point-min))
165 (re-search-forward "[^ \t\n]" (point-max) t))))
166 155
167 (defconst vc-bzr-state-words 156 (defconst vc-bzr-state-words
168 "added\\|ignored\\|kind changed\\|modified\\|removed\\|renamed\\|unknown" 157 "added\\|ignored\\|kind changed\\|modified\\|removed\\|renamed\\|unknown"
169 "Regexp matching file status words as reported in `bzr' output.") 158 "Regexp matching file status words as reported in `bzr' output.")
170 159
179 ;; FIXME: Also get this in a non-registered sub-directory. 168 ;; FIXME: Also get this in a non-registered sub-directory.
180 ;; It already works for me. -- Riccardo 169 ;; It already works for me. -- Riccardo
181 (defun vc-bzr-status (file) 170 (defun vc-bzr-status (file)
182 "Return FILE status according to Bzr. 171 "Return FILE status according to Bzr.
183 Return value is a cons (STATUS . WARNING), where WARNING is a 172 Return value is a cons (STATUS . WARNING), where WARNING is a
184 string or nil, and STATUS is one of the symbols: 'added, 173 string or nil, and STATUS is one of the symbols: `added',
185 'ignored, 'kindchange, 'modified, 'removed, 'renamed, 'unknown, 174 `ignored', `kindchanged', `modified', `removed', `renamed', `unknown',
186 which directly correspond to `bzr status' output, or 'unchanged 175 which directly correspond to `bzr status' output, or 'unchanged
187 for files whose copy in the working tree is identical to the one 176 for files whose copy in the working tree is identical to the one
188 in the branch repository, or nil for files that are not 177 in the branch repository, or nil for files that are not
189 registered with Bzr. 178 registered with Bzr.
190 179
191 If any error occurred in running `bzr status', then return nil." 180 If any error occurred in running `bzr status', then return nil."
192 (condition-case nil
193 (with-temp-buffer 181 (with-temp-buffer
194 (let ((ret (vc-bzr-command "status" t 0 file)) 182 (let ((ret (condition-case nil
195 (status 'unchanged)) 183 (vc-bzr-command "status" t 0 file)
196 ;; the only secure status indication in `bzr status' output 184 (file-error nil))) ; vc-bzr-program not found.
197 ;; is a couple of lines following the pattern:: 185 (status 'unchanged))
198 ;; | <status>: 186 ;; the only secure status indication in `bzr status' output
199 ;; | <file name> 187 ;; is a couple of lines following the pattern::
200 ;; if the file is up-to-date, we get no status report from `bzr', 188 ;; | <status>:
201 ;; so if the regexp search for the above pattern fails, we consider 189 ;; | <file name>
202 ;; the file to be up-to-date. 190 ;; if the file is up-to-date, we get no status report from `bzr',
203 (goto-char (point-min)) 191 ;; so if the regexp search for the above pattern fails, we consider
204 (when 192 ;; the file to be up-to-date.
205 (re-search-forward 193 (goto-char (point-min))
206 ;; bzr prints paths relative to the repository root 194 (when (re-search-forward
207 (concat "^\\(" vc-bzr-state-words "\\):[ \t\n]+" 195 ;; bzr prints paths relative to the repository root.
208 (regexp-quote (vc-bzr-file-name-relative file)) 196 (concat "^\\(" vc-bzr-state-words "\\):[ \t\n]+"
209 (if (file-directory-p file) "/?" "") 197 (regexp-quote (vc-bzr-file-name-relative file))
210 "[ \t\n]*$") 198 (if (file-directory-p file) "/?" "")
211 (point-max) t) 199 "[ \t\n]*$")
212 (let ((start (match-beginning 0)) 200 nil t)
213 (end (match-end 0))) 201 (let ((status (match-string 1)))
214 (goto-char start) 202 ;; Erase the status text that matched.
203 (delete-region (match-beginning 0) (match-end 0))
215 (setq status 204 (setq status
216 (cond 205 (and (equal ret 0) ; Seems redundant. --Stef
217 ((not (equal ret 0)) nil) 206 (intern (replace-regexp-in-string " " ""
218 ((looking-at "added") 'added) 207 status))))))
219 ((looking-at "kind changed") 'kindchange) 208 (when status
220 ((looking-at "renamed") 'renamed) 209 (goto-char (point-min))
221 ((looking-at "modified") 'modified) 210 (skip-chars-forward " \n\t") ;Throw away spaces.
222 ((looking-at "removed") 'removed) 211 (cons status
223 ((looking-at "ignored") 'ignored) 212 ;; "bzr" will output warnings and informational messages to
224 ((looking-at "unknown") 'unknown))) 213 ;; stderr; due to Emacs' `vc-do-command' (and, it seems,
225 ;; erase the status text that matched 214 ;; `start-process' itself) limitations, we cannot catch stderr
226 (delete-region start end))) 215 ;; and stdout into different buffers. So, if there's anything
227 (if status 216 ;; left in the buffer after removing the above status
228 (cons status 217 ;; keywords, let us just presume that any other message from
229 ;; "bzr" will output warnings and informational messages to 218 ;; "bzr" is a user warning, and display it.
230 ;; stderr; due to Emacs' `vc-do-command' (and, it seems, 219 (unless (eobp) (buffer-substring (point) (point-max))))))))
231 ;; `start-process' itself) limitations, we cannot catch stderr
232 ;; and stdout into different buffers. So, if there's anything
233 ;; left in the buffer after removing the above status
234 ;; keywords, let us just presume that any other message from
235 ;; "bzr" is a user warning, and display it.
236 (if (vc-bzr-buffer-nonblank-p)
237 (buffer-substring (point-min) (point-max)))))))
238 (file-error nil))) ; vc-bzr-program not found
239 220
240 (defun vc-bzr-state (file) 221 (defun vc-bzr-state (file)
241 (lexical-let ((result (vc-bzr-status file))) 222 (lexical-let ((result (vc-bzr-status file)))
242 (when (consp result) 223 (when (consp result)
243 (if (cdr result) 224 (if (cdr result)
244 (message "Warnings in `bzr' output: %s" (cdr result))) 225 (message "Warnings in `bzr' output: %s" (cdr result)))
245 (cdr (assq (car result) 226 (cdr (assq (car result)
246 '((added . edited) 227 '((added . edited)
247 (kindchange . edited) 228 (kindchanged . edited)
248 (renamed . edited) 229 (renamed . edited)
249 (modified . edited) 230 (modified . edited)
250 (removed . edited) 231 (removed . edited)
251 (ignored . nil) 232 (ignored . nil)
252 (unknown . nil) 233 (unknown . nil)
263 (lastrev-file (concat rootdir "/" "branch/last-revision"))) 244 (lastrev-file (concat rootdir "/" "branch/last-revision")))
264 ;; Count lines in .bzr/branch/revision-history to avoid forking a 245 ;; Count lines in .bzr/branch/revision-history to avoid forking a
265 ;; bzr process. This looks at internal files. May break if they 246 ;; bzr process. This looks at internal files. May break if they
266 ;; change their format. 247 ;; change their format.
267 (if (file-exists-p branch-format-file) 248 (if (file-exists-p branch-format-file)
268 (with-temp-buffer 249 (with-temp-buffer
269 (insert-file-contents branch-format-file) 250 (insert-file-contents branch-format-file)
270 (goto-char (point-min)) 251 (goto-char (point-min))
271 (cond 252 (cond
272 ((or 253 ((or
273 (looking-at "Bazaar-NG branch, format 0.0.4") 254 (looking-at "Bazaar-NG branch, format 0.0.4")
274 (looking-at "Bazaar-NG branch format 5")) 255 (looking-at "Bazaar-NG branch format 5"))
275 ;; count lines in .bzr/branch/revision-history 256 ;; count lines in .bzr/branch/revision-history
276 (insert-file-contents revhistory-file) 257 (insert-file-contents revhistory-file)
277 (number-to-string (count-lines (line-end-position) (point-max)))) 258 (number-to-string (count-lines (line-end-position) (point-max))))
278 ((looking-at "Bazaar Branch Format 6 (bzr 0.15)") 259 ((looking-at "Bazaar Branch Format 6 (bzr 0.15)")
279 ;; revno is the first number in .bzr/branch/last-revision 260 ;; revno is the first number in .bzr/branch/last-revision
280 (insert-file-contents lastrev-file) 261 (insert-file-contents lastrev-file)
281 (goto-char (line-end-position)) 262 (goto-char (line-end-position))
339 EDITABLE is ignored." 320 EDITABLE is ignored."
340 (unless destfile 321 (unless destfile
341 (setq destfile (vc-version-backup-file-name file rev))) 322 (setq destfile (vc-version-backup-file-name file rev)))
342 (let ((coding-system-for-read 'binary) 323 (let ((coding-system-for-read 'binary)
343 (coding-system-for-write 'binary)) 324 (coding-system-for-write 'binary))
344 (with-temp-file destfile 325 (with-temp-file destfile
345 (if rev 326 (if rev
346 (vc-bzr-command "cat" t 0 file "-r" rev) 327 (vc-bzr-command "cat" t 0 file "-r" rev)
347 (vc-bzr-command "cat" t 0 file))))) 328 (vc-bzr-command "cat" t 0 file)))))
348 329
349 (defun vc-bzr-revert (file &optional contents-done) 330 (defun vc-bzr-revert (file &optional contents-done)
350 (unless contents-done 331 (unless contents-done
351 (with-temp-buffer (vc-bzr-command "revert" t 0 file)))) 332 (with-temp-buffer (vc-bzr-command "revert" t 0 file))))
352 333
375 356
376 (defun vc-bzr-print-log (files &optional buffer) ; get buffer arg in Emacs 22 357 (defun vc-bzr-print-log (files &optional buffer) ; get buffer arg in Emacs 22
377 "Get bzr change log for FILES into specified BUFFER." 358 "Get bzr change log for FILES into specified BUFFER."
378 ;; Fixme: This might need the locale fixing up if things like `revno' 359 ;; Fixme: This might need the locale fixing up if things like `revno'
379 ;; got localized, but certainly it shouldn't use LC_ALL=C. 360 ;; got localized, but certainly it shouldn't use LC_ALL=C.
380 ;; NB. Can't be async -- see `vc-bzr-post-command-function'.
381 (vc-bzr-command "log" buffer 0 files) 361 (vc-bzr-command "log" buffer 0 files)
382 ;; FIXME: Until Emacs-23, VC was missing a hook to sort out the mode for 362 ;; FIXME: Until Emacs-23, VC was missing a hook to sort out the mode for
383 ;; the buffer, or at least set the regexps right. 363 ;; the buffer, or at least set the regexps right.
384 (unless (fboundp 'vc-default-log-view-mode) 364 (unless (fboundp 'vc-default-log-view-mode)
385 (add-hook 'log-view-mode-hook 'vc-bzr-log-view-mode))) 365 (add-hook 'log-view-mode-hook 'vc-bzr-log-view-mode)))
399 (let ((working (vc-workfile-version (if (consp files) (car files) files)))) 379 (let ((working (vc-workfile-version (if (consp files) (car files) files))))
400 (if (and (equal rev1 working) (not rev2)) 380 (if (and (equal rev1 working) (not rev2))
401 (setq rev1 nil)) 381 (setq rev1 nil))
402 (if (and (not rev1) rev2) 382 (if (and (not rev1) rev2)
403 (setq rev1 working)) 383 (setq rev1 working))
404 ;; NB. Can't be async -- see `vc-bzr-post-command-function'.
405 ;; bzr diff produces condition code 1 for some reason. 384 ;; bzr diff produces condition code 1 for some reason.
406 (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*") 1 files 385 (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*") 1 files
407 "--diff-options" (mapconcat 'identity (vc-diff-switches-list bzr) 386 "--diff-options" (mapconcat 'identity (vc-diff-switches-list bzr)
408 " ") 387 " ")
409 (when rev1 388 (when rev1
461 (replace-match "") 440 (replace-match "")
462 (insert tag " |"))))) 441 (insert tag " |")))))
463 442
464 ;; Definition from Emacs 22 443 ;; Definition from Emacs 22
465 (unless (fboundp 'vc-annotate-convert-time) 444 (unless (fboundp 'vc-annotate-convert-time)
466 (defun vc-annotate-convert-time (time) 445 (defun vc-annotate-convert-time (time)
467 "Convert a time value to a floating-point number of days. 446 "Convert a time value to a floating-point number of days.
468 The argument TIME is a list as returned by `current-time' or 447 The argument TIME is a list as returned by `current-time' or
469 `encode-time', only the first two elements of that list are considered." 448 `encode-time', only the first two elements of that list are considered."
470 (/ (+ (* (float (car time)) (lsh 1 16)) (cadr time)) 24 3600))) 449 (/ (+ (* (float (car time)) (lsh 1 16)) (cadr time)) 24 3600)))
471 450
472 (defun vc-bzr-annotate-time () 451 (defun vc-bzr-annotate-time ()
473 (when (re-search-forward "^ *[0-9]+ |" nil t) 452 (when (re-search-forward "^ *[0-9]+ |" nil t)
474 (let ((prop (get-text-property (line-beginning-position) 'help-echo))) 453 (let ((prop (get-text-property (line-beginning-position) 'help-echo)))
475 (string-match "[0-9]+\\'" prop) 454 (string-match "[0-9]+\\'" prop)
547 ((looking-at "^added") 526 ((looking-at "^added")
548 (setq current-vc-state 'edited) 527 (setq current-vc-state 'edited)
549 (setq current-bzr-state 'added)) 528 (setq current-bzr-state 'added))
550 ((looking-at "^kind changed") 529 ((looking-at "^kind changed")
551 (setq current-vc-state 'edited) 530 (setq current-vc-state 'edited)
552 (setq current-bzr-state 'kindchange)) 531 (setq current-bzr-state 'kindchanged))
553 ((looking-at "^modified") 532 ((looking-at "^modified")
554 (setq current-vc-state 'edited) 533 (setq current-vc-state 'edited)
555 (setq current-bzr-state 'modified)) 534 (setq current-bzr-state 'modified))
556 ((looking-at "^renamed") 535 ((looking-at "^renamed")
557 (setq current-vc-state 'edited) 536 (setq current-vc-state 'edited)
589 (if bzr-state 568 (if bzr-state
590 (concat "(" (symbol-name bzr-state) ")") 569 (concat "(" (symbol-name bzr-state) ")")
591 ;; else fall back to default vc representation 570 ;; else fall back to default vc representation
592 (vc-default-dired-state-info 'Bzr file))))) 571 (vc-default-dired-state-info 'Bzr file)))))
593 572
594 ;; In case of just `(load "vc-bzr")', but that's probably the wrong
595 ;; way to do it.
596 (add-to-list 'vc-handled-backends 'Bzr)
597
598 (eval-after-load "vc" 573 (eval-after-load "vc"
599 '(add-to-list 'vc-directory-exclusion-list vc-bzr-admin-dirname t)) 574 '(add-to-list 'vc-directory-exclusion-list vc-bzr-admin-dirname t))
600 575
601 (defconst vc-bzr-unload-hook
602 (lambda ()
603 (setq vc-handled-backends (delq 'Bzr vc-handled-backends))
604 (remove-hook 'vc-post-command-functions 'vc-bzr-post-command-function)))
605 576
606 (provide 'vc-bzr) 577 (provide 'vc-bzr)
607 ;; arch-tag: 8101bad8-4e92-4e7d-85ae-d8e08b4e7c06 578 ;; arch-tag: 8101bad8-4e92-4e7d-85ae-d8e08b4e7c06
608 ;;; vc-bzr.el ends here 579 ;;; vc-bzr.el ends here