comparison lisp/vc-bzr.el @ 87649:107ccd98fa12

Merge from emacs--rel--22 Revision: emacs@sv.gnu.org/emacs--devo--0--patch-987
author Miles Bader <miles@gnu.org>
date Tue, 08 Jan 2008 20:46:54 +0000
parents 21fcd219fd6e f62e87c6eb20
children 606f2d163a64 74bf6df13b6c
comparison
equal deleted inserted replaced
87648:7ae99e295dfd 87649:107ccd98fa12
1 ;;; vc-bzr.el --- VC backend for the bzr revision control system 1 ;;; vc-bzr.el --- VC backend for the bzr revision control system
2 2
3 ;; Copyright (C) 2006, 2007 Free Software Foundation, Inc. 3 ;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
4 4
5 ;; Author: Dave Love <fx@gnu.org>, Riccardo Murri <riccardo.murri@gmail.com> 5 ;; Author: Dave Love <fx@gnu.org>, Riccardo Murri <riccardo.murri@gmail.com>
6 ;; Keywords: tools 6 ;; Keywords: tools
7 ;; Created: Sept 2006 7 ;; Created: Sept 2006
8 ;; Version: 2007-09-05 8 ;; Version: 2008-01-04 (Bzr revno 25)
9 ;; URL: http://launchpad.net/vc-bzr 9 ;; URL: http://launchpad.net/vc-bzr
10 10
11 ;; This file is free software; you can redistribute it and/or modify 11 ;; This file is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by 12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option) 13 ;; the Free Software Foundation; either version 3, or (at your option)
24 ;; Boston, MA 02110-1301, USA. 24 ;; Boston, MA 02110-1301, USA.
25 25
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;; See <URL:http://bazaar-vcs.org/> concerning bzr. 29 ;; See <URL:http://bazaar-vcs.org/> concerning bzr. See
30 30 ;; <URL:http://launchpad.net/vc-bzr> for alternate development
31 ;; Load this library to register bzr support in VC. It covers basic VC 31 ;; branches of `vc-bzr'.
32 ;; functionality, but was only lightly exercised with a few Emacs/bzr 32
33 ;; version combinations, namely those current on the authors' PCs. 33 ;; Load this library to register bzr support in VC.
34 ;; See various Fixmes below.
35
36 34
37 ;; Known bugs 35 ;; Known bugs
38 ;; ========== 36 ;; ==========
39 37
40 ;; When edititing a symlink and *both* the symlink and its target 38 ;; When edititing a symlink and *both* the symlink and its target
64 62
65 (defcustom vc-bzr-program "bzr" 63 (defcustom vc-bzr-program "bzr"
66 "Name of the bzr command (excluding any arguments)." 64 "Name of the bzr command (excluding any arguments)."
67 :group 'vc-bzr 65 :group 'vc-bzr
68 :type 'string) 66 :type 'string)
69
70 ;; Fixme: there's probably no call for this.
71 (defcustom vc-bzr-program-args nil
72 "List of global arguments to pass to `vc-bzr-program'."
73 :group 'vc-bzr
74 :type '(repeat string))
75 67
76 (defcustom vc-bzr-diff-switches nil 68 (defcustom vc-bzr-diff-switches nil
77 "String/list of strings specifying extra switches for bzr diff under VC." 69 "String/list of strings specifying extra switches for bzr diff under VC."
78 :type '(choice (const :tag "None" nil) 70 :type '(choice (const :tag "None" nil)
79 (string :tag "Argument String") 71 (string :tag "Argument String")
80 (repeat :tag "Argument List" :value ("") string)) 72 (repeat :tag "Argument List" :value ("") string))
81 :group 'vc-bzr) 73 :group 'vc-bzr)
82 74
75 (defcustom vc-bzr-log-switches nil
76 "String/list of strings specifying extra switches for `bzr log' under VC."
77 :type '(choice (const :tag "None" nil)
78 (string :tag "Argument String")
79 (repeat :tag "Argument List" :value ("") string))
80 :group 'vc-bzr)
81
83 ;; since v0.9, bzr supports removing the progress indicators 82 ;; since v0.9, bzr supports removing the progress indicators
84 ;; by setting environment variable BZR_PROGRESS_BAR to "none". 83 ;; by setting environment variable BZR_PROGRESS_BAR to "none".
85 (defun vc-bzr-command (bzr-command buffer okstatus file-or-list &rest args) 84 (defun vc-bzr-command (bzr-command buffer okstatus file-or-list &rest args)
86 "Wrapper round `vc-do-command' using `vc-bzr-program' as COMMAND. 85 "Wrapper round `vc-do-command' using `vc-bzr-program' as COMMAND.
87 Invoke the bzr command adding `BZR_PROGRESS_BAR=none' to the environment." 86 Invoke the bzr command adding `BZR_PROGRESS_BAR=none' and
87 `LC_MESSAGES=C' to the environment."
88 (let ((process-environment 88 (let ((process-environment
89 (list* "BZR_PROGRESS_BAR=none" ; Suppress progress output (bzr >=0.9) 89 (list* "BZR_PROGRESS_BAR=none" ; Suppress progress output (bzr >=0.9)
90 "LC_ALL=C" ; Force English output 90 "LC_MESSAGES=C" ; Force English output
91 process-environment))) 91 process-environment)))
92 (apply 'vc-do-command buffer okstatus vc-bzr-program 92 (apply 'vc-do-command buffer okstatus vc-bzr-program
93 file-or-list bzr-command (append vc-bzr-program-args args)))) 93 file-or-list bzr-command args)))
94 94
95 95
96 ;;;###autoload 96 ;;;###autoload
97 (defconst vc-bzr-admin-dirname ".bzr" ; FIXME: "_bzr" on w32? 97 (defconst vc-bzr-admin-dirname ".bzr"
98 "Name of the directory containing Bzr repository status files.") 98 "Name of the directory containing Bzr repository status files.")
99 ;;;###autoload 99 ;;;###autoload
100 (defconst vc-bzr-admin-checkout-format-file 100 (defconst vc-bzr-admin-checkout-format-file
101 (concat vc-bzr-admin-dirname "/checkout/format")) 101 (concat vc-bzr-admin-dirname "/checkout/format"))
102 (defconst vc-bzr-admin-dirstate 102 (defconst vc-bzr-admin-dirstate
160 160
161 (defun vc-bzr-file-name-relative (filename) 161 (defun vc-bzr-file-name-relative (filename)
162 "Return file name FILENAME stripped of the initial Bzr repository path." 162 "Return file name FILENAME stripped of the initial Bzr repository path."
163 (lexical-let* 163 (lexical-let*
164 ((filename* (expand-file-name filename)) 164 ((filename* (expand-file-name filename))
165 (rootdir (vc-bzr-root (file-name-directory filename*)))) 165 (rootdir (vc-bzr-root filename*)))
166 (when rootdir 166 (when rootdir
167 (file-relative-name filename* rootdir)))) 167 (file-relative-name filename* rootdir))))
168 168
169 ;; FIXME: Also get this in a non-registered sub-directory.
170 ;; It already works for me. -- Riccardo
171 (defun vc-bzr-status (file) 169 (defun vc-bzr-status (file)
172 "Return FILE status according to Bzr. 170 "Return FILE status according to Bzr.
173 Return value is a cons (STATUS . WARNING), where WARNING is a 171 Return value is a cons (STATUS . WARNING), where WARNING is a
174 string or nil, and STATUS is one of the symbols: `added', 172 string or nil, and STATUS is one of the symbols: `added',
175 `ignored', `kindchanged', `modified', `removed', `renamed', `unknown', 173 `ignored', `kindchanged', `modified', `removed', `renamed', `unknown',
194 (goto-char (point-min)) 192 (goto-char (point-min))
195 (when (re-search-forward 193 (when (re-search-forward
196 ;; bzr prints paths relative to the repository root. 194 ;; bzr prints paths relative to the repository root.
197 (concat "^\\(" vc-bzr-state-words "\\):[ \t\n]+" 195 (concat "^\\(" vc-bzr-state-words "\\):[ \t\n]+"
198 (regexp-quote (vc-bzr-file-name-relative file)) 196 (regexp-quote (vc-bzr-file-name-relative file))
199 (if (file-directory-p file) "/?" "") 197 ;; Bzr appends a '/' to directory names and
198 ;; '*' to executable files
199 (if (file-directory-p file) "/?" "\\*?")
200 "[ \t\n]*$") 200 "[ \t\n]*$")
201 nil t) 201 nil t)
202 (lexical-let ((statusword (match-string 1))) 202 (lexical-let ((statusword (match-string 1)))
203 ;; Erase the status text that matched. 203 ;; Erase the status text that matched.
204 (delete-region (match-beginning 0) (match-end 0)) 204 (delete-region (match-beginning 0) (match-end 0))
205 (setq status 205 (setq status
206 (and (equal ret 0) ; Seems redundant. --Stef 206 (intern (replace-regexp-in-string " " "" statusword)))))
207 (intern (replace-regexp-in-string " " ""
208 statusword))))))
209 (when status 207 (when status
210 (goto-char (point-min)) 208 (goto-char (point-min))
211 (skip-chars-forward " \n\t") ;Throw away spaces. 209 (skip-chars-forward " \n\t") ;Throw away spaces.
212 (cons status 210 (cons status
213 ;; "bzr" will output warnings and informational messages to 211 ;; "bzr" will output warnings and informational messages to
277 275
278 (defun vc-bzr-create-repo () 276 (defun vc-bzr-create-repo ()
279 "Create a new Bzr repository." 277 "Create a new Bzr repository."
280 (vc-bzr-command "init" nil 0 nil)) 278 (vc-bzr-command "init" nil 0 nil))
281 279
280 (defun vc-bzr-init-version (&optional file)
281 "Always return nil, as Bzr cannot register explicit versions."
282 nil)
283
282 (defun vc-bzr-register (files &optional rev comment) 284 (defun vc-bzr-register (files &optional rev comment)
283 "Register FILE under bzr. 285 "Register FILE under bzr.
284 Signal an error unless REV is nil. 286 Signal an error unless REV is nil.
285 COMMENT is ignored." 287 COMMENT is ignored."
286 (if rev (error "Can't register explicit revision with bzr")) 288 (if rev (error "Can't register explicit revision with bzr"))
305 (looking-at "added ")) 307 (looking-at "added "))
306 (error)))) 308 (error))))
307 309
308 (defun vc-bzr-unregister (file) 310 (defun vc-bzr-unregister (file)
309 "Unregister FILE from bzr." 311 "Unregister FILE from bzr."
310 (vc-bzr-command "remove" nil 0 file)) 312 (vc-bzr-command "remove" nil 0 file "--keep"))
311 313
312 (defun vc-bzr-checkin (files rev comment) 314 (defun vc-bzr-checkin (files rev comment)
313 "Check FILE in to bzr with log message COMMENT. 315 "Check FILE in to bzr with log message COMMENT.
314 REV non-nil gets an error." 316 REV non-nil gets an error."
315 (if rev (error "Can't check in a specific revision with bzr")) 317 (if rev (error "Can't check in a specific revision with bzr"))
316 (vc-bzr-command "commit" nil 0 files "-m" comment)) 318 (vc-bzr-command "commit" nil 0 files "-m" comment))
319
320 (defun vc-bzr-find-version (file rev buffer)
321 "Fetch version REV of file FILE and put it into BUFFER."
322 (with-current-buffer buffer
323 (if (and rev (stringp rev) (not (string= rev "")))
324 (vc-bzr-command "cat" t 0 file "-r" rev)
325 (vc-bzr-command "cat" t 0 file))))
317 326
318 (defun vc-bzr-checkout (file &optional editable rev destfile) 327 (defun vc-bzr-checkout (file &optional editable rev destfile)
319 "Checkout revision REV of FILE from bzr to DESTFILE. 328 "Checkout revision REV of FILE from bzr to DESTFILE.
320 EDITABLE is ignored." 329 EDITABLE is ignored."
321 (unless destfile 330 (unless destfile
322 (setq destfile (vc-version-backup-file-name file rev))) 331 (setq destfile (vc-version-backup-file-name file rev)))
323 (let ((coding-system-for-read 'binary) 332 (let ((coding-system-for-read 'binary)
324 (coding-system-for-write 'binary)) 333 (coding-system-for-write 'binary))
325 (with-temp-file destfile 334 (with-temp-file destfile
326 (if rev 335 (if (and rev (stringp rev) (not (string= rev "")))
327 (vc-bzr-command "cat" t 0 file "-r" rev) 336 (vc-bzr-command "cat" t 0 file "-r" rev)
328 (vc-bzr-command "cat" t 0 file))))) 337 (vc-bzr-command "cat" t 0 file)))))
329 338
330 (defun vc-bzr-revert (file &optional contents-done) 339 (defun vc-bzr-revert (file &optional contents-done)
331 (unless contents-done 340 (unless contents-done
354 (2 'change-log-email)) 363 (2 'change-log-email))
355 ("^ *timestamp: \\(.*\\)" (1 'change-log-date-face)))))) 364 ("^ *timestamp: \\(.*\\)" (1 'change-log-date-face))))))
356 365
357 (defun vc-bzr-print-log (files &optional buffer) ; get buffer arg in Emacs 22 366 (defun vc-bzr-print-log (files &optional buffer) ; get buffer arg in Emacs 22
358 "Get bzr change log for FILES into specified BUFFER." 367 "Get bzr change log for FILES into specified BUFFER."
359 ;; Fixme: This might need the locale fixing up if things like `revno' 368 ;; FIXME: `vc-bzr-command' runs `bzr log' with `LC_MESSAGES=C', so
360 ;; got localized, but certainly it shouldn't use LC_ALL=C. 369 ;; the log display may not what the user wants - but I see no other
361 (vc-bzr-command "log" buffer 0 files) 370 ;; way of getting the above regexps working.
371 (apply 'vc-bzr-command "log" buffer 0 files
372 (if (stringp vc-bzr-log-switches)
373 (list vc-bzr-log-switches)
374 vc-bzr-log-switches))
362 ;; FIXME: Until Emacs-23, VC was missing a hook to sort out the mode for 375 ;; FIXME: Until Emacs-23, VC was missing a hook to sort out the mode for
363 ;; the buffer, or at least set the regexps right. 376 ;; the buffer, or at least set the regexps right.
364 (unless (fboundp 'vc-default-log-view-mode) 377 (unless (fboundp 'vc-default-log-view-mode)
365 (add-hook 'log-view-mode-hook 'vc-bzr-log-view-mode))) 378 (add-hook 'log-view-mode-hook 'vc-bzr-log-view-mode)))
366 379
374 387
375 (autoload 'vc-diff-switches-list "vc" nil nil t) 388 (autoload 'vc-diff-switches-list "vc" nil nil t)
376 389
377 (defun vc-bzr-diff (files &optional rev1 rev2 buffer) 390 (defun vc-bzr-diff (files &optional rev1 rev2 buffer)
378 "VC bzr backend for diff." 391 "VC bzr backend for diff."
379 (let ((working (vc-working-revision (if (consp files) (car files) files)))) 392 ;; `bzr diff' exits with code 1 if diff is non-empty
380 (if (and (equal rev1 working) (not rev2)) 393 (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*") 1 files
381 (setq rev1 nil)) 394 "--diff-options" (mapconcat 'identity
382 (if (and (not rev1) rev2) 395 (vc-diff-switches-list bzr)
383 (setq rev1 working)) 396 " ")
384 ;; bzr diff produces condition code 1 for some reason. 397 (list "-r" (format "%s..%s"
385 (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*") 1 files 398 (or rev1 "revno:-1")
386 "--diff-options" (mapconcat 'identity (vc-diff-switches-list bzr) 399 (or rev2 "")))))
387 " ")
388 (when rev1
389 (if rev2
390 (list "-r" (format "%s..%s" rev1 rev2))
391 (list "-r" rev1))))))
392
393 400
394 401
395 ;; FIXME: vc-{next,previous}-revision need fixing in vc.el to deal with 402 ;; FIXME: vc-{next,previous}-revision need fixing in vc.el to deal with
396 ;; straight integer revisions. 403 ;; straight integer revisions.
397 404
434 'mouse-face 'highlight)) 441 'mouse-face 'highlight))
435 (puthash key tag vc-bzr-annotation-table)) 442 (puthash key tag vc-bzr-annotation-table))
436 (replace-match "") 443 (replace-match "")
437 (insert tag " |"))))) 444 (insert tag " |")))))
438 445
439 ;; Definition from Emacs 22
440 (unless (fboundp 'vc-annotate-convert-time)
441 (defun vc-annotate-convert-time (time)
442 "Convert a time value to a floating-point number of days.
443 The argument TIME is a list as returned by `current-time' or
444 `encode-time', only the first two elements of that list are considered."
445 (/ (+ (* (float (car time)) (lsh 1 16)) (cadr time)) 24 3600)))
446
447 (defun vc-bzr-annotate-time () 446 (defun vc-bzr-annotate-time ()
448 (when (re-search-forward "^ *[0-9]+ |" nil t) 447 (when (re-search-forward "^ *[0-9]+ |" nil t)
449 (let ((prop (get-text-property (line-beginning-position) 'help-echo))) 448 (let ((prop (get-text-property (line-beginning-position) 'help-echo)))
450 (string-match "[0-9]+\\'" prop) 449 (string-match "[0-9]+\\'" prop)
451 (vc-annotate-convert-time 450 (vc-annotate-convert-time
460 Return nil if current line isn't annotated." 459 Return nil if current line isn't annotated."
461 (save-excursion 460 (save-excursion
462 (beginning-of-line) 461 (beginning-of-line)
463 (if (looking-at " *\\([0-9]+\\) | ") 462 (if (looking-at " *\\([0-9]+\\) | ")
464 (match-string-no-properties 1)))) 463 (match-string-no-properties 1))))
465
466 ;; Not needed for Emacs 22
467 (defun vc-bzr-annotate-difference (point)
468 (let ((next-time (vc-bzr-annotate-time)))
469 (if next-time
470 (- (vc-annotate-convert-time (current-time)) next-time))))
471 464
472 (defun vc-bzr-command-discarding-stderr (command &rest args) 465 (defun vc-bzr-command-discarding-stderr (command &rest args)
473 "Execute shell command COMMAND (with ARGS); return its output and exitcode. 466 "Execute shell command COMMAND (with ARGS); return its output and exitcode.
474 Return value is a cons (EXITCODE . OUTPUT), where EXITCODE is 467 Return value is a cons (EXITCODE . OUTPUT), where EXITCODE is
475 the (numerical) exit code of the process, and OUTPUT is a string 468 the (numerical) exit code of the process, and OUTPUT is a string
505 (setq at-start nil) 498 (setq at-start nil)
506 (let ((file (expand-file-name 499 (let ((file (expand-file-name
507 (buffer-substring-no-properties 500 (buffer-substring-no-properties
508 (line-beginning-position) (line-end-position)) 501 (line-beginning-position) (line-end-position))
509 bzr-root-directory))) 502 bzr-root-directory)))
503 ;; files are up-to-date unless they appear in the `bzr
504 ;; status' output below
510 (vc-file-setprop file 'vc-state 'up-to-date) 505 (vc-file-setprop file 'vc-state 'up-to-date)
511 ;; XXX: is this correct? what happens if one 506 ;; XXX: is this correct? what happens if one
512 ;; mixes different SCMs in the same dir? 507 ;; mixes different SCMs in the same dir?
508 ;; Anyway, we're looking at the output of `bzr ls --versioned',
509 ;; so we know these files are registered with Bzr.
513 (vc-file-setprop file 'vc-backend 'Bzr)))) 510 (vc-file-setprop file 'vc-backend 'Bzr))))
514 ;; `bzr status' reports on added/modified/renamed and unknown/ignored files 511 ;; `bzr status' reports on added/modified/renamed and unknown/ignored files
515 (setq at-start t) 512 (setq at-start t)
516 (with-temp-buffer 513 (with-temp-buffer
517 (vc-bzr-command "status" t 0 nil) 514 (vc-bzr-command "status" t 0 nil)
562 (setq current-bzr-state nil))))))) 559 (setq current-bzr-state nil)))))))
563 560
564 (defun vc-bzr-dired-state-info (file) 561 (defun vc-bzr-dired-state-info (file)
565 "Bzr-specific version of `vc-dired-state-info'." 562 "Bzr-specific version of `vc-dired-state-info'."
566 (if (eq 'edited (vc-state file)) 563 (if (eq 'edited (vc-state file))
567 (let ((bzr-state (vc-file-getprop file 'vc-bzr-state))) 564 (concat "(" (symbol-name (or (vc-file-getprop file 'vc-bzr-state)
568 (if bzr-state 565 'edited)) ")")
569 (concat "(" (symbol-name bzr-state) ")") 566 ;; else fall back to default vc.el representation
570 ;; else fall back to default vc representation 567 (vc-default-dired-state-info 'Bzr file)))
571 (vc-default-dired-state-info 'Bzr file)))))
572 568
573 (eval-after-load "vc" 569 (eval-after-load "vc"
574 '(add-to-list 'vc-directory-exclusion-list vc-bzr-admin-dirname t)) 570 '(add-to-list 'vc-directory-exclusion-list vc-bzr-admin-dirname t))
575 571
576 (provide 'vc-bzr) 572 (provide 'vc-bzr)