comparison lisp/vc-rcs.el @ 81966:cedd5b77aae4

Put the lower half (the back-end) of NewVC in place. This commit makes only the minimum changes needed to get the old vc.el logic working with the new back ends.
author Eric S. Raymond <esr@snark.thyrsus.com>
date Wed, 18 Jul 2007 16:32:37 +0000
parents f35ed3fecce9
children f9f0d45ce573
comparison
equal deleted inserted replaced
81965:88498b7a5bb5 81966:cedd5b77aae4
94 function))) 94 function)))
95 :version "21.1" 95 :version "21.1"
96 :group 'vc) 96 :group 'vc)
97 97
98 98
99 ;;; Properties of the backend
100
101 (defun vc-rcs-revision-granularity ()
102 'file)
103
99 ;;; 104 ;;;
100 ;;; State-querying functions 105 ;;; State-querying functions
101 ;;; 106 ;;;
102 107
103 ;;; The autoload cookie below places vc-rcs-registered directly into 108 ;;; The autoload cookie below places vc-rcs-registered directly into
228 233
229 ;;; 234 ;;;
230 ;;; State-changing functions 235 ;;; State-changing functions
231 ;;; 236 ;;;
232 237
233 (defun vc-rcs-register (file &optional rev comment) 238 (defun vc-rcs-create-repo ()
234 "Register FILE into the RCS version-control system. 239 "Create a new RCS repository."
235 REV is the optional revision number for the file. COMMENT can be used 240 ;; RCS is totally file-oriented, so all we have to do is make the directory
236 to provide an initial description of FILE. 241 (make-directory "RCS"))
242
243 (defun vc-rcs-register (files &optional rev comment)
244 "Register FILES into the RCS version-control system.
245 REV is the optional revision number for the files. COMMENT can be used
246 to provide an initial description for each FILES.
237 247
238 `vc-register-switches' and `vc-rcs-register-switches' are passed to 248 `vc-register-switches' and `vc-rcs-register-switches' are passed to
239 the RCS command (in that order). 249 the RCS command (in that order).
240 250
241 Automatically retrieve a read-only version of the file with keywords 251 Automatically retrieve a read-only version of the file with keywords
242 expanded if `vc-keep-workfiles' is non-nil, otherwise, delete the workfile." 252 expanded if `vc-keep-workfiles' is non-nil, otherwise, delete the workfile."
243 (let ((subdir (expand-file-name "RCS" (file-name-directory file)))) 253 (let ((subdir (expand-file-name "RCS" (file-name-directory file))))
254 (dolist (file files)
244 (and (not (file-exists-p subdir)) 255 (and (not (file-exists-p subdir))
245 (not (directory-files (file-name-directory file) 256 (not (directory-files (file-name-directory file)
246 nil ".*,v$" t)) 257 nil ".*,v$" t))
247 (yes-or-no-p "Create RCS subdirectory? ") 258 (yes-or-no-p "Create RCS subdirectory? ")
248 (make-directory subdir)) 259 (make-directory subdir))
271 (file-name-directory file)))))) 282 (file-name-directory file))))))
272 (vc-file-setprop file 'vc-workfile-version 283 (vc-file-setprop file 'vc-workfile-version
273 (if (re-search-forward 284 (if (re-search-forward
274 "^initial revision: \\([0-9.]+\\).*\n" 285 "^initial revision: \\([0-9.]+\\).*\n"
275 nil t) 286 nil t)
276 (match-string 1)))))) 287 (match-string 1)))))))
277 288
278 (defun vc-rcs-responsible-p (file) 289 (defun vc-rcs-responsible-p (file)
279 "Return non-nil if RCS thinks it would be responsible for registering FILE." 290 "Return non-nil if RCS thinks it would be responsible for registering FILE."
280 ;; TODO: check for all the patterns in vc-rcs-master-templates 291 ;; TODO: check for all the patterns in vc-rcs-master-templates
281 (file-directory-p (expand-file-name "RCS" (file-name-directory file)))) 292 (file-directory-p (expand-file-name "RCS" (file-name-directory file))))
305 (not (directory-files dir nil 316 (not (directory-files dir nil
306 "^\\([^.]\\|\\.[^.]\\|\\.\\.[^.]\\).*")) 317 "^\\([^.]\\|\\.[^.]\\|\\.\\.[^.]\\).*"))
307 (yes-or-no-p (format "Directory %s is empty; remove it? " dir)) 318 (yes-or-no-p (format "Directory %s is empty; remove it? " dir))
308 (delete-directory dir)))) 319 (delete-directory dir))))
309 320
310 (defun vc-rcs-checkin (file rev comment) 321 (defun vc-rcs-checkin (files rev comment)
311 "RCS-specific version of `vc-backend-checkin'." 322 "RCS-specific version of `vc-backend-checkin'."
312 (let ((switches (vc-switches 'RCS 'checkin))) 323 (let ((switches (vc-switches 'RCS 'checkin)))
313 (let ((old-version (vc-workfile-version file)) new-version 324 ;; Now operate on the files
314 (default-branch (vc-file-getprop file 'vc-rcs-default-branch))) 325 (dolist (file files)
315 ;; Force branch creation if an appropriate 326 (let ((old-version (vc-workfile-version file)) new-version
316 ;; default branch has been set. 327 (default-branch (vc-file-getprop file 'vc-rcs-default-branch)))
317 (and (not rev) 328 ;; Force branch creation if an appropriate
318 default-branch 329 ;; default branch has been set.
319 (string-match (concat "^" (regexp-quote old-version) "\\.") 330 (and (not rev)
320 default-branch) 331 default-branch
321 (setq rev default-branch) 332 (string-match (concat "^" (regexp-quote old-version) "\\.")
322 (setq switches (cons "-f" switches))) 333 default-branch)
323 (if (and (not rev) old-version) 334 (setq rev default-branch)
324 (setq rev (vc-branch-part old-version))) 335 (setq switches (cons "-f" switches)))
325 (apply 'vc-do-command nil 0 "ci" (vc-name file) 336 (if (and (not rev) old-version)
326 ;; if available, use the secure check-in option 337 (setq rev (vc-branch-part old-version)))
327 (and (vc-rcs-release-p "5.6.4") "-j") 338 (apply 'vc-do-command nil 0 "ci" (vc-name file)
328 (concat (if vc-keep-workfiles "-u" "-r") rev) 339 ;; if available, use the secure check-in option
329 (concat "-m" comment) 340 (and (vc-rcs-release-p "5.6.4") "-j")
330 switches) 341 (concat (if vc-keep-workfiles "-u" "-r") rev)
331 (vc-file-setprop file 'vc-workfile-version nil) 342 (concat "-m" comment)
332 343 switches)
333 ;; determine the new workfile version 344 (vc-file-setprop file 'vc-workfile-version nil)
334 (set-buffer "*vc*") 345
335 (goto-char (point-min)) 346 ;; determine the new workfile version
336 (when (or (re-search-forward 347 (set-buffer "*vc*")
337 "new revision: \\([0-9.]+\\);" nil t) 348 (goto-char (point-min))
338 (re-search-forward 349 (when (or (re-search-forward
339 "reverting to previous revision \\([0-9.]+\\)" nil t)) 350 "new revision: \\([0-9.]+\\);" nil t)
340 (setq new-version (match-string 1)) 351 (re-search-forward
341 (vc-file-setprop file 'vc-workfile-version new-version)) 352 "reverting to previous revision \\([0-9.]+\\)" nil t))
342 353 (setq new-version (match-string 1))
343 ;; if we got to a different branch, adjust the default 354 (vc-file-setprop file 'vc-workfile-version new-version))
344 ;; branch accordingly 355
345 (cond 356 ;; if we got to a different branch, adjust the default
346 ((and old-version new-version 357 ;; branch accordingly
347 (not (string= (vc-branch-part old-version) 358 (cond
348 (vc-branch-part new-version)))) 359 ((and old-version new-version
349 (vc-rcs-set-default-branch file 360 (not (string= (vc-branch-part old-version)
350 (if (vc-trunk-p new-version) nil 361 (vc-branch-part new-version))))
351 (vc-branch-part new-version))) 362 (vc-rcs-set-default-branch file
352 ;; If this is an old RCS release, we might have 363 (if (vc-trunk-p new-version) nil
353 ;; to remove a remaining lock. 364 (vc-branch-part new-version)))
354 (if (not (vc-rcs-release-p "5.6.2")) 365 ;; If this is an old RCS release, we might have
355 ;; exit status of 1 is also accepted. 366 ;; to remove a remaining lock.
356 ;; It means that the lock was removed before. 367 (if (not (vc-rcs-release-p "5.6.2"))
357 (vc-do-command nil 1 "rcs" (vc-name file) 368 ;; exit status of 1 is also accepted.
358 (concat "-u" old-version)))))))) 369 ;; It means that the lock was removed before.
370 (vc-do-command nil 1 "rcs" (vc-name file)
371 (concat "-u" old-version)))))))))
359 372
360 (defun vc-rcs-find-version (file rev buffer) 373 (defun vc-rcs-find-version (file rev buffer)
361 (apply 'vc-do-command 374 (apply 'vc-do-command
362 buffer 0 "co" (vc-name file) 375 buffer 0 "co" (vc-name file)
363 "-q" ;; suppress diagnostic output 376 "-q" ;; suppress diagnostic output
425 (if (vc-trunk-p new-version) nil 438 (if (vc-trunk-p new-version) nil
426 (vc-branch-part new-version)) 439 (vc-branch-part new-version))
427 new-version))))) 440 new-version)))))
428 (message "Checking out %s...done" file))))) 441 (message "Checking out %s...done" file)))))
429 442
443 (defun vc-rcs-rollback (files)
444 "Roll back, undoing the most recent checkins of FILES."
445 (if (not files)
446 (error "RCS backend doesn't support directory-level rollback."))
447 (dolist (file files)
448 (let* ((discard (vc-workfile-version file))
449 (previous (if (vc-trunk-p discard) "" (vc-branch-part discard)))
450 (config (current-window-configuration))
451 (done nil))
452 (if (null (yes-or-no-p (format "Remove version %s from %s history? "
453 discard file)))
454 (error "Aborted"))
455 (message "Removing revision %s from %s." discard file)
456 (vc-do-command nil 0 "rcs" (vc-name file) (concat "-o" discard))
457 ;; Check out the most recent remaining version. If it
458 ;; fails, because the whole branch got deleted, do a
459 ;; double-take and check out the version where the branch
460 ;; started.
461 (while (not done)
462 (condition-case err
463 (progn
464 (vc-do-command nil 0 "co" (vc-name file) "-f"
465 (concat "-u" previous))
466 (setq done t))
467 (error (set-buffer "*vc*")
468 (goto-char (point-min))
469 (if (search-forward "no side branches present for" nil t)
470 (progn (setq previous (vc-branch-part previous))
471 (vc-rcs-set-default-branch file previous)
472 ;; vc-do-command popped up a window with
473 ;; the error message. Get rid of it, by
474 ;; restoring the old window configuration.
475 (set-window-configuration config))
476 ;; No, it was some other error: re-signal it.
477 (signal (car err) (cdr err)))))))))
478
430 (defun vc-rcs-revert (file &optional contents-done) 479 (defun vc-rcs-revert (file &optional contents-done)
431 "Revert FILE to the version it was based on." 480 "Revert FILE to the version it was based on."
432 (vc-do-command nil 0 "co" (vc-name file) "-f" 481 (vc-do-command nil 0 "co" (vc-name file) "-f"
433 (concat (if (eq (vc-state file) 'edited) "-u" "-r") 482 (concat (if (eq (vc-state file) 'edited) "-u" "-r")
434 (vc-workfile-version file)))) 483 (vc-workfile-version file))))
435
436 (defun vc-rcs-cancel-version (file editable)
437 "Undo the most recent checkin of FILE.
438 EDITABLE non-nil means previous version should be locked."
439 (let* ((target (vc-workfile-version file))
440 (previous (if (vc-trunk-p target) "" (vc-branch-part target)))
441 (config (current-window-configuration))
442 (done nil))
443 (vc-do-command nil 0 "rcs" (vc-name file) (concat "-o" target))
444 ;; Check out the most recent remaining version. If it fails, because
445 ;; the whole branch got deleted, do a double-take and check out the
446 ;; version where the branch started.
447 (while (not done)
448 (condition-case err
449 (progn
450 (vc-do-command nil 0 "co" (vc-name file) "-f"
451 (concat (if editable "-l" "-u") previous))
452 (setq done t))
453 (error (set-buffer "*vc*")
454 (goto-char (point-min))
455 (if (search-forward "no side branches present for" nil t)
456 (progn (setq previous (vc-branch-part previous))
457 (vc-rcs-set-default-branch file previous)
458 ;; vc-do-command popped up a window with
459 ;; the error message. Get rid of it, by
460 ;; restoring the old window configuration.
461 (set-window-configuration config))
462 ;; No, it was some other error: re-signal it.
463 (signal (car err) (cdr err))))))))
464 484
465 (defun vc-rcs-merge (file first-version &optional second-version) 485 (defun vc-rcs-merge (file first-version &optional second-version)
466 "Merge changes into current working copy of FILE. 486 "Merge changes into current working copy of FILE.
467 The changes are between FIRST-VERSION and SECOND-VERSION." 487 The changes are between FIRST-VERSION and SECOND-VERSION."
468 (vc-do-command nil 1 "rcsmerge" (vc-name file) 488 (vc-do-command nil 1 "rcsmerge" (vc-name file)
482 502
483 ;;; 503 ;;;
484 ;;; History functions 504 ;;; History functions
485 ;;; 505 ;;;
486 506
487 (defun vc-rcs-print-log (file &optional buffer) 507 (defun vc-rcs-print-log (files &optional buffer)
488 "Get change log associated with FILE." 508 "Get change log associated with FILE."
489 (vc-do-command buffer 0 "rlog" (vc-name file))) 509 (vc-do-command buffer 0 "rlog" (mapcar 'vc-name files)))
490 510
491 (defun vc-rcs-diff (file &optional oldvers newvers buffer) 511 (defun vc-rcs-diff (files &optional oldvers newvers buffer)
492 "Get a difference report using RCS between two versions of FILE." 512 "Get a difference report using RCS between two sets of files."
493 (if (not oldvers) (setq oldvers (vc-workfile-version file))) 513 (apply 'vc-do-command (or buffer "*vc-diff*")
494 (apply 'vc-do-command (or buffer "*vc-diff*") 1 "rcsdiff" file 514 1 ;; Always go synchronous, the repo is local
515 "rcsdiff" (vc-expand-dirs files)
495 (append (list "-q" 516 (append (list "-q"
496 (concat "-r" oldvers) 517 (and oldvers (concat "-r" oldvers))
497 (and newvers (concat "-r" newvers))) 518 (and newvers (concat "-r" newvers)))
498 (vc-switches 'RCS 'diff)))) 519 (vc-switches 'RCS 'diff))))
520
521 (defun vc-rcs-wash-log ()
522 "Remove all non-comment information from log output."
523 (let ((separator (concat "^-+\nrevision [0-9.]+\ndate: .*\n"
524 "\\(branches: .*;\n\\)?"
525 "\\(\\*\\*\\* empty log message \\*\\*\\*\n\\)?")))
526 (goto-char (point-max)) (forward-line -1)
527 (while (looking-at "=*\n")
528 (delete-char (- (match-end 0) (match-beginning 0)))
529 (forward-line -1))
530 (goto-char (point-min))
531 (if (looking-at "[\b\t\n\v\f\r ]+")
532 (delete-char (- (match-end 0) (match-beginning 0))))
533 (goto-char (point-min))
534 (re-search-forward separator nil t)
535 (delete-region (point-min) (point))
536 (while (re-search-forward separator nil t)
537 (delete-region (match-beginning 0) (match-end 0)))))
499 538
500 (defun vc-rcs-annotate-command (file buffer &optional revision) 539 (defun vc-rcs-annotate-command (file buffer &optional revision)
501 "Annotate FILE, inserting the results in BUFFER. 540 "Annotate FILE, inserting the results in BUFFER.
502 Optional arg REVISION is a revision to annotate from." 541 Optional arg REVISION is a revision to annotate from."
503 (vc-setup-buffer buffer) 542 (vc-setup-buffer buffer)
664 (apply 'concat 703 (apply 'concat
665 (format-time-string "%Y-%m-%d" (aref rda 1)) 704 (format-time-string "%Y-%m-%d" (aref rda 1))
666 " " 705 " "
667 (aref rda 0) 706 (aref rda 0)
668 ls) 707 ls)
669 :vc-annotate-prefix t
670 :vc-rcs-r/d/a rda))) 708 :vc-rcs-r/d/a rda)))
671 (maphash 709 (maphash
672 (if all-me 710 (if all-me
673 (lambda (rda w) 711 (lambda (rda w)
674 (puthash rda (render rda (pad w) ": ") ht)) 712 (puthash rda (render rda (pad w) ": ") ht))