;; make sure that the file name is searched case-sensitively
(case-fold-search nil))
(if (file-readable-p (expand-file-name "CVS/Entries" dirname))
- (with-temp-buffer
- (vc-cvs-get-entries dirname)
- (goto-char (point-min))
- (cond
- ((re-search-forward
- (concat "^/" (regexp-quote basename) "/[^/]") nil t)
- (beginning-of-line)
- (vc-cvs-parse-entry file)
- t)
- (t nil)))
+ (or (string= basename "")
+ (with-temp-buffer
+ (vc-cvs-get-entries dirname)
+ (goto-char (point-min))
+ (cond ((re-search-forward
+ (concat "^/" (regexp-quote basename) "/[^/]") nil t)
+ (beginning-of-line)
+ (vc-cvs-parse-entry file)
+ t)
+ (t nil))))
nil)))
(defun vc-cvs-state (file)
(cond
((equal checkout-time lastmod) 'up-to-date)
((string= (vc-working-revision file) "0") 'added)
+ ((null checkout-time) 'unregistered)
(t 'edited))))
(defun vc-cvs-working-revision (file)
help-echo
(string
(let ((def-ml (vc-default-mode-line-string 'CVS file)))
- (setq help-echo
+ (setq help-echo
(get-text-property 0 'help-echo def-ml))
def-ml)))
- (propertize
+ (propertize
(if (zerop (length sticky-tag))
string
- (setq help-echo (format "%s on the '%s' branch"
+ (setq help-echo (format "%s on the '%s' branch"
help-echo sticky-tag))
(concat string "[" sticky-tag "]"))
'help-echo help-echo)))
(with-current-buffer (get-buffer "*vc*")
(goto-char (point-min))
(if (re-search-forward "conflicts during merge" nil t)
- (progn
+ (progn
(vc-file-setprop file 'vc-state 'conflict)
;; signal error
1)
(message "Merging changes into %s...done" file))))
(defun vc-cvs-modify-change-comment (files rev comment)
- "Modify the change comments for FILES on a specified REV.
+ "Modify the change comments for FILES on a specified REV.
Will fail unless you have administrative privileges on the repo."
(vc-cvs-command nil 0 files "admin" (concat "-m" rev ":" comment)))
((re-search-forward "\\=\\([^ \t]+\\)" nil t)
(setq file (expand-file-name (match-string 1)))
(vc-file-setprop file 'vc-backend 'CVS)
- (if (not (re-search-forward "\\=[ \t]+Status: \\(.*\\)" nil t))
- (setq status "Unknown")
- (setq status (match-string 1)))
+ (setq status(if (re-search-forward "\\=[ \t]+Status: \\(.*\\)" nil t)
+ (match-string 1) "Unknown"))
(when (and full
(re-search-forward
"\\(RCS Version\\|RCS Revision\\|Repository revision\\):\
((string-match "Locally Added" status) 'added)
((string-match "Locally Removed" status) 'removed)
((string-match "File had conflicts " status) 'conflict)
+ ((string-match "Unknown" status) 'unregistered)
(t 'edited))))))))
(defun vc-cvs-after-dir-status (update-function)
(re-search-forward
"\\(^=+\n\\([^=c?\n].*\n\\|\n\\)+\\)\\|\\(\\(^?? .*\n\\)+\\)\\|\\(^cvs status: Examining .*\n\\)"
nil t)
- ;; XXX: get rid of narrowing here.
+ ;; FIXME: get rid of narrowing here.
(narrow-to-region (match-beginning 0) (match-end 0))
(goto-char (point-min))
;; The subdir
(setq subdir (expand-file-name (match-string 1))))
;; Unregistered files
(while (looking-at "? \\(.*\\)")
- (setq file (file-relative-name
+ (setq file (file-relative-name
(expand-file-name (match-string 1) subdir)))
(push (list file 'unregistered) result)
(forward-line 1))
;; A file entry.
- (when (re-search-forward "^File: " nil t)
- (when (setq missing (looking-at "no file "))
- (goto-char (match-end 0)))
- (cond
- ((re-search-forward "\\=\\([^ \t]+\\)" nil t)
- (setq file (file-relative-name
- (expand-file-name (match-string 1) subdir)))
- (if (not (re-search-forward "\\=[ \t]+Status: \\(.*\\)" nil t))
- (push (list file 'unregistered) result)
- (setq status-str (match-string 1))
- (setq status
- (cond
- ((string-match "Up-to-date" status-str) 'up-to-date)
- ((string-match "Locally Modified" status-str) 'edited)
- ((string-match "Needs Merge" status-str) 'needs-merge)
- ((string-match "Needs \\(Checkout\\|Patch\\)" status-str)
- (if missing 'missing 'needs-update))
- ((string-match "Locally Added" status-str) 'added)
- ((string-match "Locally Removed" status-str) 'removed)
- ((string-match "File had conflicts " status-str) 'conflict)
- (t 'edited)))
- (unless (eq status 'up-to-date)
- (push (list file status) result))))))
+ (when (re-search-forward "^File: \\(no file \\)?\\(.*[^ \t]\\)[ \t]+Status: \\(.*\\)" nil t)
+ (setq missing (match-string 1))
+ (setq file (file-relative-name
+ (expand-file-name (match-string 2) subdir)))
+ (setq status-str (match-string 3))
+ (setq status
+ (cond
+ ((string-match "Up-to-date" status-str) 'up-to-date)
+ ((string-match "Locally Modified" status-str) 'edited)
+ ((string-match "Needs Merge" status-str) 'needs-merge)
+ ((string-match "Needs \\(Checkout\\|Patch\\)" status-str)
+ (if missing 'missing 'needs-update))
+ ((string-match "Locally Added" status-str) 'added)
+ ((string-match "Locally Removed" status-str) 'removed)
+ ((string-match "File had conflicts " status-str) 'conflict)
+ ((string-match "Unknown" status-str) 'unregistered)
+ (t 'edited)))
+ (unless (eq status 'up-to-date)
+ (push (list file status) result)))
(goto-char (point-max))
(widen))
- (funcall update-function result))
+ (funcall update-function result))
;; Alternative implementation: use the "update" command instead of
;; the "status" command.
;; (let ((result nil)
;; (goto-char (point-min))
;; (while (not (eobp))
;; (if (looking-at "^[ACMPRU?] \\(.*\\)$")
- ;; (push (list (match-string 1)
- ;; (cdr (assoc (char-after) translation)))
+ ;; (push (list (match-string 1)
+ ;; (cdr (assoc (char-after) translation)))
;; result)
;; (cond
;; ((looking-at "cvs update: warning: \\(.*\\) was lost")
(defun vc-cvs-dir-status (dir update-function)
"Create a list of conses (file . state) for DIR."
- (vc-cvs-command (current-buffer) 'async dir "status")
+ (vc-cvs-command (current-buffer) 'async dir "-f" "status")
;; Alternative implementation: use the "update" command instead of
;; the "status" command.
;; (vc-cvs-command (current-buffer) 'async
(vc-exec-after
`(vc-cvs-after-dir-status (quote ,update-function))))
+(defun vc-cvs-file-to-string (file)
+ "Read the content of FILE and return it as a string."
+ (condition-case nil
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (buffer-substring (point) (point-max)))
+ (file-error nil)))
+
(defun vc-cvs-status-extra-headers (dir)
+ "Extract and represent per-directory properties of a CVS working copy."
(let ((repo
- (condition-case nil
- (save-excursion
- (set-buffer (find-file-noselect "CVS/Root" t))
+ (condition-case nil
+ (with-temp-buffer
+ (insert-file-contents "CVS/Root")
+ (goto-char (point-min))
(and (looking-at ":ext:") (delete-char 5))
- (buffer-string))
- nil)))
+ (buffer-substring (point) (1- (point-max))))
+ (file-error nil)))
+ (module
+ (condition-case nil
+ (with-temp-buffer
+ (insert-file-contents "CVS/Repository")
+ (goto-char (point-min))
+ (re-search-forward "[^/\n]*" nil t)
+ (concat (match-string 0) "\n"))
+ (file-error nil))))
(concat
- ;; FIXME: see how PCL-CVS gets the data to print all these
- (propertize "Module : " 'face 'font-lock-type-face)
- (propertize "ADD CODE TO PRINT THE MODULE\n"
- 'face 'font-lock-warning-face)
+ (cond (module
+ (concat (propertize "Module : " 'face 'font-lock-type-face)
+ (propertize module 'face 'font-lock-variable-name-face)))
+ (t ""))
(cond (repo
- (concat
- (propertize "Repository : " 'face 'font-lock-type-face)
- (propertize repo 'face 'font-lock-warning-face)))
+ (concat (propertize "Repository : " 'face 'font-lock-type-face)
+ (propertize repo 'face 'font-lock-variable-name-face)))
(t ""))
- (propertize "Branch : " 'face 'font-lock-type-face)
- (propertize "ADD CODE TO PRINT THE BRANCH NAME\n"
- 'face 'font-lock-warning-face))))
+ ;; In CVS, branch is a per-file property, not a per-directory property.
+ ;; We can't really do this here without making dangerous assumptions.
+ ;;(propertize "Branch: " 'face 'font-lock-type-face)
+ ;;(propertize "ADD CODE TO PRINT THE BRANCH NAME\n"
+ ;; 'face 'font-lock-warning-face)
+ )))
(defun vc-cvs-get-entries (dir)
"Insert the CVS/Entries file from below DIR into the current buffer.
(setq table (lazy-completion-table
table (lambda () (vc-cvs-revision-table (car files)))))
table))
-
+
(provide 'vc-cvs)