Mercurial > emacs
comparison lisp/vc-mcvs.el @ 50952:1731748fbe8c
(vc-mcvs-command): Filter output of `status'.
(vc-mcvs-state, vc-mcvs-dir-state, vc-mcvs-print-log, vc-mcvs-diff):
Change dir so that the filtered output of `mcvs makes sense.
(vc-mcvs-mode-line-string): Handle the case where CVS is desync'd.
(vc-mcvs-diff-tree): Don't bother with the local-diff code.
(vc-mcvs-create-snapshot): Use `branch' and `switch'.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 11 May 2003 23:55:07 +0000 |
parents | dc235df7e226 |
children | 575459cc44fb |
comparison
equal
deleted
inserted
replaced
50951:75cc899eee26 | 50952:1731748fbe8c |
---|---|
48 ;; - C-x v g | 48 ;; - C-x v g |
49 ;; - M-x vc-rename-file RET | 49 ;; - M-x vc-rename-file RET |
50 | 50 |
51 ;;; Bugs: | 51 ;;; Bugs: |
52 | 52 |
53 ;; - VC-dired doesn't work. | 53 ;; - Retrieving snapshots doesn't filter `cvs update' output and thus |
54 ;; parses bogus filenames. Don't know if it harms. | |
54 | 55 |
55 ;;; Code: | 56 ;;; Code: |
56 | 57 |
57 (eval-when-compile (require 'vc)) | 58 (eval-when-compile (require 'vc)) |
58 (require 'vc-cvs) | 59 (require 'vc-cvs) |
183 ;; we don't have a more precise state already available. | 184 ;; we don't have a more precise state already available. |
184 (if (memq state '(up-to-date edited)) | 185 (if (memq state '(up-to-date edited)) |
185 (vc-mcvs-state-heuristic file) | 186 (vc-mcvs-state-heuristic file) |
186 state)) | 187 state)) |
187 (with-temp-buffer | 188 (with-temp-buffer |
188 (cd (file-name-directory file)) | 189 (setq default-directory (vc-mcvs-root file)) |
189 (vc-mcvs-command t 0 file "status") | 190 (vc-mcvs-command t 0 file "status") |
190 (vc-cvs-parse-status t)))) | 191 (vc-cvs-parse-status t)))) |
191 | 192 |
192 | 193 |
193 (defalias 'vc-mcvs-state-heuristic 'vc-cvs-state-heuristic) | 194 (defalias 'vc-mcvs-state-heuristic 'vc-cvs-state-heuristic) |
200 (vc-mcvs-dir-state-heuristic dir) | 201 (vc-mcvs-dir-state-heuristic dir) |
201 (let ((default-directory dir)) | 202 (let ((default-directory dir)) |
202 ;; Don't specify DIR in this command, the default-directory is | 203 ;; Don't specify DIR in this command, the default-directory is |
203 ;; enough. Otherwise it might fail with remote repositories. | 204 ;; enough. Otherwise it might fail with remote repositories. |
204 (with-temp-buffer | 205 (with-temp-buffer |
206 (setq default-directory (vc-mcvs-root dir)) | |
205 (vc-mcvs-command t 0 nil "status" "-l") | 207 (vc-mcvs-command t 0 nil "status" "-l") |
206 (goto-char (point-min)) | 208 (goto-char (point-min)) |
207 (while (re-search-forward "^=+\n\\([^=\n].*\n\\|\n\\)+" nil t) | 209 (while (re-search-forward "^=+\n\\([^=\n].*\n\\|\n\\)+" nil t) |
208 (narrow-to-region (match-beginning 0) (match-end 0)) | 210 (narrow-to-region (match-beginning 0) (match-end 0)) |
209 (vc-cvs-parse-status) | 211 (vc-cvs-parse-status) |
214 | 216 |
215 (defalias 'vc-mcvs-checkout-model 'vc-cvs-checkout-model) | 217 (defalias 'vc-mcvs-checkout-model 'vc-cvs-checkout-model) |
216 | 218 |
217 (defun vc-mcvs-mode-line-string (file) | 219 (defun vc-mcvs-mode-line-string (file) |
218 (let ((s (vc-mcvs-cvs mode-line-string file))) | 220 (let ((s (vc-mcvs-cvs mode-line-string file))) |
219 (if s (concat "M" s)))) | 221 (when s |
222 (if (and (not (memq (vc-state file) '(up-to-date needs-patch))) | |
223 (string-match "\\`CVS-" s)) | |
224 ;; The CVS file is not in sync, so we need to adjust the state. | |
225 (concat "MCVS:" (substring s 4)) | |
226 (concat "M" s))))) | |
220 | 227 |
221 ;;; | 228 ;;; |
222 ;;; State-changing functions | 229 ;;; State-changing functions |
223 ;;; | 230 ;;; |
224 | 231 |
282 (unless (or (not rev) (vc-mcvs-valid-version-number-p rev)) | 289 (unless (or (not rev) (vc-mcvs-valid-version-number-p rev)) |
283 (if (not (vc-mcvs-valid-symbolic-tag-name-p rev)) | 290 (if (not (vc-mcvs-valid-symbolic-tag-name-p rev)) |
284 (error "%s is not a valid symbolic tag name" rev) | 291 (error "%s is not a valid symbolic tag name" rev) |
285 ;; If the input revision is a valid symbolic tag name, we create it | 292 ;; If the input revision is a valid symbolic tag name, we create it |
286 ;; as a branch, commit and switch to it. | 293 ;; as a branch, commit and switch to it. |
294 ;; This file-specific form of branching is deprecated. | |
295 ;; We can't use `mcvs branch' and `mcvs switch' because they cannot | |
296 ;; be applied just to this one file. | |
287 (apply 'vc-mcvs-command nil 0 file "tag" "-b" (list rev)) | 297 (apply 'vc-mcvs-command nil 0 file "tag" "-b" (list rev)) |
288 (apply 'vc-mcvs-command nil 0 file "update" "-r" (list rev)) | 298 (apply 'vc-mcvs-command nil 0 file "update" "-r" (list rev)) |
289 (vc-file-setprop file 'vc-mcvs-sticky-tag rev) | 299 (vc-file-setprop file 'vc-mcvs-sticky-tag rev) |
290 (setq rev nil))) | 300 (setq rev nil))) |
291 ;; This commit might cvs-commit several files (e.g. MAP and TYPES) | 301 ;; This commit might cvs-commit several files (e.g. MAP and TYPES) |
438 ;;; History functions | 448 ;;; History functions |
439 ;;; | 449 ;;; |
440 | 450 |
441 (defun vc-mcvs-print-log (file) | 451 (defun vc-mcvs-print-log (file) |
442 "Get change log associated with FILE." | 452 "Get change log associated with FILE." |
443 (vc-mcvs-command | 453 (let ((default-directory (vc-mcvs-root file))) |
444 nil | 454 ;; Run the command from the root dir so that `mcvs filt' returns |
445 (if (and (vc-stay-local-p file) (fboundp 'start-process)) 'async 0) | 455 ;; valid relative names. |
446 file "log")) | 456 (vc-mcvs-command |
457 nil | |
458 (if (and (vc-stay-local-p file) (fboundp 'start-process)) 'async 0) | |
459 file "log"))) | |
447 | 460 |
448 (defun vc-mcvs-diff (file &optional oldvers newvers) | 461 (defun vc-mcvs-diff (file &optional oldvers newvers) |
449 "Get a difference report using Meta-CVS between two versions of FILE." | 462 "Get a difference report using Meta-CVS between two versions of FILE." |
450 (if (string= (vc-workfile-version file) "0") | 463 (if (string= (vc-workfile-version file) "0") |
451 ;; This file is added but not yet committed; there is no master file. | 464 ;; This file is added but not yet committed; there is no master file. |
458 1 "diff" file | 471 1 "diff" file |
459 (append (vc-switches nil 'diff) '("/dev/null"))) | 472 (append (vc-switches nil 'diff) '("/dev/null"))) |
460 ;; Even if it's empty, it's locally modified. | 473 ;; Even if it's empty, it's locally modified. |
461 1) | 474 1) |
462 (let* ((async (and (vc-stay-local-p file) (fboundp 'start-process))) | 475 (let* ((async (and (vc-stay-local-p file) (fboundp 'start-process))) |
476 ;; Run the command from the root dir so that `mcvs filt' returns | |
477 ;; valid relative names. | |
478 (default-directory (vc-mcvs-root file)) | |
463 (status | 479 (status |
464 (apply 'vc-mcvs-command "*vc-diff*" | 480 (apply 'vc-mcvs-command "*vc-diff*" |
465 (if async 'async 1) | 481 (if async 'async 1) |
466 file "diff" | 482 file "diff" |
467 (and oldvers (concat "-r" oldvers)) | 483 (and oldvers (concat "-r" oldvers)) |
470 (if async 1 status)))) ; async diff, pessimistic assumption. | 486 (if async 1 status)))) ; async diff, pessimistic assumption. |
471 | 487 |
472 (defun vc-mcvs-diff-tree (dir &optional rev1 rev2) | 488 (defun vc-mcvs-diff-tree (dir &optional rev1 rev2) |
473 "Diff all files at and below DIR." | 489 "Diff all files at and below DIR." |
474 (with-current-buffer "*vc-diff*" | 490 (with-current-buffer "*vc-diff*" |
475 (setq default-directory dir) | 491 ;; Run the command from the root dir so that `mcvs filt' returns |
476 (if (vc-stay-local-p dir) | 492 ;; valid relative names. |
477 ;; local diff: do it filewise, and only for files that are modified | 493 (setq default-directory (vc-mcvs-root dir)) |
478 (vc-file-tree-walk | 494 ;; cvs diff: use a single call for the entire tree |
479 dir | 495 (let ((coding-system-for-read (or coding-system-for-read 'undecided))) |
480 (lambda (f) | 496 (apply 'vc-mcvs-command "*vc-diff*" 1 dir "diff" |
481 (vc-exec-after | 497 (and rev1 (concat "-r" rev1)) |
482 `(let ((coding-system-for-read (vc-coding-system-for-diff ',f))) | 498 (and rev2 (concat "-r" rev2)) |
483 ;; possible optimization: fetch the state of all files | 499 (vc-switches 'MCVS 'diff))))) |
484 ;; in the tree via vc-mcvs-dir-state-heuristic | |
485 (unless (vc-up-to-date-p ',f) | |
486 (message "Looking at %s" ',f) | |
487 (vc-diff-internal ',f ',rev1 ',rev2)))))) | |
488 ;; cvs diff: use a single call for the entire tree | |
489 (let ((coding-system-for-read | |
490 (or coding-system-for-read 'undecided))) | |
491 (apply 'vc-mcvs-command "*vc-diff*" 1 nil "diff" | |
492 (and rev1 (concat "-r" rev1)) | |
493 (and rev2 (concat "-r" rev2)) | |
494 (vc-switches 'MCVS 'diff)))))) | |
495 | 500 |
496 (defun vc-mcvs-annotate-command (file buffer &optional version) | 501 (defun vc-mcvs-annotate-command (file buffer &optional version) |
497 "Execute \"mcvs annotate\" on FILE, inserting the contents in BUFFER. | 502 "Execute \"mcvs annotate\" on FILE, inserting the contents in BUFFER. |
498 Optional arg VERSION is a version to annotate from." | 503 Optional arg VERSION is a version to annotate from." |
499 (vc-mcvs-command | 504 (vc-mcvs-command |
510 | 515 |
511 (defun vc-mcvs-create-snapshot (dir name branchp) | 516 (defun vc-mcvs-create-snapshot (dir name branchp) |
512 "Assign to DIR's current version a given NAME. | 517 "Assign to DIR's current version a given NAME. |
513 If BRANCHP is non-nil, the name is created as a branch (and the current | 518 If BRANCHP is non-nil, the name is created as a branch (and the current |
514 workspace is immediately moved to that new branch)." | 519 workspace is immediately moved to that new branch)." |
515 (vc-mcvs-command nil 0 dir "tag" "-c" (if branchp "-b") name) | 520 (if (not branchp) |
516 (when branchp (vc-mcvs-command nil 0 dir "update" "-r" name))) | 521 (vc-mcvs-command nil 0 dir "tag" "-c" name) |
522 (vc-mcvs-command nil 0 dir "branch" name) | |
523 (vc-mcvs-command nil 0 dir "switch" name))) | |
517 | 524 |
518 (defun vc-mcvs-retrieve-snapshot (dir name update) | 525 (defun vc-mcvs-retrieve-snapshot (dir name update) |
519 "Retrieve a snapshot at and below DIR. | 526 "Retrieve a snapshot at and below DIR. |
520 NAME is the name of the snapshot; if it is empty, do a `cvs update'. | 527 NAME is the name of the snapshot; if it is empty, do a `cvs update'. |
521 If UPDATE is non-nil, then update (resynch) any affected buffers." | 528 If UPDATE is non-nil, then update (resynch) any affected buffers." |
567 | 574 |
568 (defun vc-mcvs-command (buffer okstatus file &rest flags) | 575 (defun vc-mcvs-command (buffer okstatus file &rest flags) |
569 "A wrapper around `vc-do-command' for use in vc-mcvs.el. | 576 "A wrapper around `vc-do-command' for use in vc-mcvs.el. |
570 The difference to vc-do-command is that this function always invokes `mcvs', | 577 The difference to vc-do-command is that this function always invokes `mcvs', |
571 and that it passes `vc-mcvs-global-switches' to it before FLAGS." | 578 and that it passes `vc-mcvs-global-switches' to it before FLAGS." |
572 (let ((args (append '("--error-continue") | 579 (let ((args (append '("--error-terminate") |
573 (if (stringp vc-mcvs-global-switches) | 580 (if (stringp vc-mcvs-global-switches) |
574 (cons vc-mcvs-global-switches flags) | 581 (cons vc-mcvs-global-switches flags) |
575 (append vc-mcvs-global-switches | 582 (append vc-mcvs-global-switches flags))))) |
576 flags))))) | 583 (if (not (member (car flags) '("diff" "log" "status"))) |
577 (if (member (car flags) '("diff" "log")) | 584 ;; No need to filter: do it the easy way. |
578 ;; We need to filter the output. | 585 (apply 'vc-do-command buffer okstatus "mcvs" file args) |
579 (vc-do-command buffer okstatus "sh" nil "-c" | 586 ;; We need to filter the output. |
580 (concat "mcvs " | 587 ;; The output of the filter uses filenames relative to the root, |
581 (mapconcat | 588 ;; so we need to change the default-directory. |
582 'shell-quote-argument | 589 (assert (equal default-directory (vc-mcvs-root file))) |
583 (append (remq nil args) | 590 (vc-do-command |
584 (if file (list (file-relative-name file)))) | 591 buffer okstatus "sh" nil "-c" |
585 " ") | 592 (concat "mcvs " |
586 " | mcvs filt")) | 593 (mapconcat |
587 (apply 'vc-do-command buffer okstatus "mcvs" file args)))) | 594 'shell-quote-argument |
595 (append (remq nil args) | |
596 (if file (list (file-relative-name file)))) | |
597 " ") | |
598 " | mcvs filt"))))) | |
588 | 599 |
589 (defun vc-mcvs-repository-hostname (dirname) | 600 (defun vc-mcvs-repository-hostname (dirname) |
590 (vc-cvs-repository-hostname (vc-mcvs-root dirname))) | 601 (vc-cvs-repository-hostname (vc-mcvs-root dirname))) |
591 | 602 |
592 (defun vc-mcvs-dir-state-heuristic (dir) | 603 (defun vc-mcvs-dir-state-heuristic (dir) |