diff options
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/vc-bzr.el | 81 |
2 files changed, 70 insertions, 17 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ad16204be35..ff7f79ca0e5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2008-03-28 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * vc-bzr.el (vc-bzr-sha1): New fun. | ||
| 4 | (vc-bzr-state-heuristic): New fun, extracted from vc-bzr-registered. | ||
| 5 | (vc-bzr-registered): Use it. | ||
| 6 | |||
| 1 | 2008-03-28 Dan Nicolaescu <dann@ics.uci.edu> | 7 | 2008-03-28 Dan Nicolaescu <dann@ics.uci.edu> |
| 2 | 8 | ||
| 3 | * vc.el (vc-status-kill-dir-status-process): Simplify. | 9 | * vc.el (vc-status-kill-dir-status-process): Simplify. |
diff --git a/lisp/vc-bzr.el b/lisp/vc-bzr.el index 5fff3d8e544..f90ead85c19 100644 --- a/lisp/vc-bzr.el +++ b/lisp/vc-bzr.el | |||
| @@ -121,17 +121,31 @@ Invoke the bzr command adding `BZR_PROGRESS_BAR=none' and | |||
| 121 | (let ((root (vc-find-root file vc-bzr-admin-checkout-format-file))) | 121 | (let ((root (vc-find-root file vc-bzr-admin-checkout-format-file))) |
| 122 | (when root (vc-file-setprop file 'bzr-root root))))) | 122 | (when root (vc-file-setprop file 'bzr-root root))))) |
| 123 | 123 | ||
| 124 | (defun vc-bzr-registered (file) | 124 | (require 'sha1) ;For sha1-program |
| 125 | "Return non-nil if FILE is registered with bzr. | ||
| 126 | |||
| 127 | For speed, this function tries first to parse Bzr internal file | ||
| 128 | `checkout/dirstate', but it may fail if Bzr internal file format | ||
| 129 | has changed. As a safeguard, the `checkout/dirstate' file is | ||
| 130 | only parsed if it contains the string `#bazaar dirstate flat | ||
| 131 | format 3' in the first line. | ||
| 132 | 125 | ||
| 133 | If the `checkout/dirstate' file cannot be parsed, fall back to | 126 | (defun vc-bzr-sha1 (file) |
| 134 | running `vc-bzr-state'." | 127 | (with-temp-buffer |
| 128 | (set-buffer-multibyte nil) | ||
| 129 | (let ((prog sha1-program) | ||
| 130 | (args nil)) | ||
| 131 | (when (consp prog) | ||
| 132 | (setq args (cdr prog)) | ||
| 133 | (setq prog (car prog))) | ||
| 134 | (apply 'call-process prog file t nil args) | ||
| 135 | (buffer-substring (point-min) (+ (point-min) 40))))) | ||
| 136 | |||
| 137 | (defun vc-bzr-state-heuristic (file) | ||
| 138 | "Like `vc-bzr-state' but hopefully without running Bzr." | ||
| 139 | ;; `bzr status' is excrutiatingly slow with large histories and | ||
| 140 | ;; pending merges, so try to avoid using it until they fix their | ||
| 141 | ;; performance problems. | ||
| 142 | ;; This function tries first to parse Bzr internal file | ||
| 143 | ;; `checkout/dirstate', but it may fail if Bzr internal file format | ||
| 144 | ;; has changed. As a safeguard, the `checkout/dirstate' file is | ||
| 145 | ;; only parsed if it contains the string `#bazaar dirstate flat | ||
| 146 | ;; format 3' in the first line. | ||
| 147 | ;; If the `checkout/dirstate' file cannot be parsed, fall back to | ||
| 148 | ;; running `vc-bzr-state'." | ||
| 135 | (lexical-let ((root (vc-bzr-root file))) | 149 | (lexical-let ((root (vc-bzr-root file))) |
| 136 | (when root ; Short cut. | 150 | (when root ; Short cut. |
| 137 | ;; This looks at internal files. May break if they change | 151 | ;; This looks at internal files. May break if they change |
| @@ -146,13 +160,44 @@ running `vc-bzr-state'." | |||
| 146 | (vc-bzr-state file) ; Some other unknown format? | 160 | (vc-bzr-state file) ; Some other unknown format? |
| 147 | (let* ((relfile (file-relative-name file root)) | 161 | (let* ((relfile (file-relative-name file root)) |
| 148 | (reldir (file-name-directory relfile))) | 162 | (reldir (file-name-directory relfile))) |
| 149 | (re-search-forward | 163 | (if (re-search-forward |
| 150 | (concat "^\0" | 164 | (concat "^\0" |
| 151 | (if reldir (regexp-quote (directory-file-name reldir))) | 165 | (if reldir (regexp-quote |
| 152 | "\0" | 166 | (directory-file-name reldir))) |
| 153 | (regexp-quote (file-name-nondirectory relfile)) | 167 | "\0" |
| 154 | "\0") | 168 | (regexp-quote (file-name-nondirectory relfile)) |
| 155 | nil t))))))))) | 169 | "\0" |
| 170 | "[^\0]*\0" ;id? | ||
| 171 | "\\([^\0]*\\)\0" ;"a/f/d", a=removed? | ||
| 172 | "\\([^\0]*\\)\0" ;sha1? | ||
| 173 | "\\([^\0]*\\)\0" ;size? | ||
| 174 | "[^\0]*\0" ;"y/n", executable? | ||
| 175 | "[^\0]*\0" ;? | ||
| 176 | "\\([^\0]*\\)\0" ;"a/f/d" a=added? | ||
| 177 | "[^\0]*\0" ;sha1 again? | ||
| 178 | "[^\0]*\0" ;size again? | ||
| 179 | "[^\0]*\0" ;"y/n", executable again? | ||
| 180 | "[^\0]*\0$") ;last revid? | ||
| 181 | nil t) | ||
| 182 | ;; FIXME: figure out which of the first or the second | ||
| 183 | ;; "size" and "sha1" we should use. They seem to always | ||
| 184 | ;; be equal, but there's probably a good reason why | ||
| 185 | ;; there are 2 entries. | ||
| 186 | (cond | ||
| 187 | ((eq (char-after (match-beginning 4)) ?a) 'removed) | ||
| 188 | ((eq (char-after (match-beginning 3)) ?a) 'added) | ||
| 189 | ((and (eq (string-to-number (match-string 3)) | ||
| 190 | (nth 7 (file-attributes file))) | ||
| 191 | (equal (match-string 2) | ||
| 192 | (vc-bzr-sha1 file))) | ||
| 193 | 'up-to-date) | ||
| 194 | (t 'edited)) | ||
| 195 | 'unregistered))))))))) | ||
| 196 | |||
| 197 | (defun vc-bzr-registered (file) | ||
| 198 | "Return non-nil if FILE is registered with bzr." | ||
| 199 | (let ((state (vc-bzr-state-heuristic file))) | ||
| 200 | (not (memq state '(nil unregistered ignored))))) | ||
| 156 | 201 | ||
| 157 | (defconst vc-bzr-state-words | 202 | (defconst vc-bzr-state-words |
| 158 | "added\\|ignored\\|kind changed\\|modified\\|removed\\|renamed\\|unknown" | 203 | "added\\|ignored\\|kind changed\\|modified\\|removed\\|renamed\\|unknown" |
| @@ -263,6 +308,8 @@ If any error occurred in running `bzr status', then return nil." | |||
| 263 | (eq 'unchanged (car (vc-bzr-status file)))) | 308 | (eq 'unchanged (car (vc-bzr-status file)))) |
| 264 | 309 | ||
| 265 | (defun vc-bzr-working-revision (file) | 310 | (defun vc-bzr-working-revision (file) |
| 311 | ;; Together with the code in vc-state-heuristic, this makes it possible | ||
| 312 | ;; to get the initial VC state of a Bzr file even if Bzr is not installed. | ||
| 266 | (lexical-let* | 313 | (lexical-let* |
| 267 | ((rootdir (vc-bzr-root file)) | 314 | ((rootdir (vc-bzr-root file)) |
| 268 | (branch-format-file (expand-file-name vc-bzr-admin-branch-format-file | 315 | (branch-format-file (expand-file-name vc-bzr-admin-branch-format-file |