diff options
| author | Karl Heuer | 1995-04-26 21:47:35 +0000 |
|---|---|---|
| committer | Karl Heuer | 1995-04-26 21:47:35 +0000 |
| commit | f3c61d82f224e52f98f060090f74efa91b235997 (patch) | |
| tree | 5c125ea05702bf232ab25d8da420d11f6a39a547 | |
| parent | e1c0c2d1bf45a7fd909b7865419a3013ec79b141 (diff) | |
| download | emacs-f3c61d82f224e52f98f060090f74efa91b235997.tar.gz emacs-f3c61d82f224e52f98f060090f74efa91b235997.zip | |
(vc-next-action-on-file): Add missing let-binding.
(vc-default-backend, vc-keep-workfiles, vc-consult-headers):
(vc-mistrust-permissions, vc-path): Vars moved to vc-hooks.el.
(vc-match-substring, vc-lock-file, vc-parse-buffer, vc-master-info):
(vc-log-info, vc-consult-rcs-headers, vc-fetch-properties):
(vc-backend-subdirectory-name, vc-locking-user, vc-true-locking-user):
(vc-latest-version, vc-your-latest-version, vc-branch-version):
(vc-workfile-version): Functions moved to vc-hooks.el.
(vc-trunk-p, vc-minor-revision, vc-branch-part): Functions moved
here from vc-hooks.el.
| -rw-r--r-- | lisp/vc.el | 429 |
1 files changed, 25 insertions, 404 deletions
diff --git a/lisp/vc.el b/lisp/vc.el index 0c299418e7c..1e32275122e 100644 --- a/lisp/vc.el +++ b/lisp/vc.el | |||
| @@ -77,32 +77,16 @@ | |||
| 77 | 77 | ||
| 78 | ;; General customization | 78 | ;; General customization |
| 79 | 79 | ||
| 80 | (defvar vc-default-back-end nil | ||
| 81 | "*Back-end actually used by this interface; may be SCCS or RCS. | ||
| 82 | The value is only computed when needed to avoid an expensive search.") | ||
| 83 | (defvar vc-suppress-confirm nil | 80 | (defvar vc-suppress-confirm nil |
| 84 | "*If non-nil, treat user as expert; suppress yes-no prompts on some things.") | 81 | "*If non-nil, treat user as expert; suppress yes-no prompts on some things.") |
| 85 | (defvar vc-keep-workfiles t | ||
| 86 | "*If non-nil, don't delete working files after registering changes. | ||
| 87 | If the back-end is CVS, workfiles are always kept, regardless of the | ||
| 88 | value of this flag.") | ||
| 89 | (defvar vc-initial-comment nil | 82 | (defvar vc-initial-comment nil |
| 90 | "*Prompt for initial comment when a file is registered.") | 83 | "*Prompt for initial comment when a file is registered.") |
| 91 | (defvar vc-command-messages nil | 84 | (defvar vc-command-messages nil |
| 92 | "*Display run messages from back-end commands.") | 85 | "*Display run messages from back-end commands.") |
| 93 | (defvar vc-consult-headers t | ||
| 94 | "*Identify work files by searching for version headers.") | ||
| 95 | (defvar vc-mistrust-permissions nil | ||
| 96 | "*Don't assume that permissions and ownership track version-control status.") | ||
| 97 | (defvar vc-checkin-switches nil | 86 | (defvar vc-checkin-switches nil |
| 98 | "*Extra switches passed to the checkin program by \\[vc-checkin].") | 87 | "*Extra switches passed to the checkin program by \\[vc-checkin].") |
| 99 | (defvar vc-checkout-switches nil | 88 | (defvar vc-checkout-switches nil |
| 100 | "*Extra switches passed to the checkout program by \\[vc-checkout].") | 89 | "*Extra switches passed to the checkout program by \\[vc-checkout].") |
| 101 | (defvar vc-path | ||
| 102 | (if (file-directory-p "/usr/sccs") | ||
| 103 | '("/usr/sccs") | ||
| 104 | nil) | ||
| 105 | "*List of extra directories to search for version control commands.") | ||
| 106 | (defvar vc-directory-exclusion-list '("SCCS" "RCS") | 90 | (defvar vc-directory-exclusion-list '("SCCS" "RCS") |
| 107 | "*Directory names ignored by functions that recursively walk file trees.") | 91 | "*Directory names ignored by functions that recursively walk file trees.") |
| 108 | 92 | ||
| @@ -202,6 +186,23 @@ and that its contents match what the master file says.") | |||
| 202 | ;; log buffer with a nonzero local value of vc-comment-ring-index. | 186 | ;; log buffer with a nonzero local value of vc-comment-ring-index. |
| 203 | (setq vc-comment-ring nil)) | 187 | (setq vc-comment-ring nil)) |
| 204 | 188 | ||
| 189 | ;;; functions that operate on RCS revision numbers | ||
| 190 | |||
| 191 | ;; vc-occurences and vc-branch-p moved to vc-hooks.el | ||
| 192 | |||
| 193 | (defun vc-trunk-p (rev) | ||
| 194 | ;; return t if REV is a revision on the trunk | ||
| 195 | (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev)))) | ||
| 196 | |||
| 197 | (defun vc-minor-revision (rev) | ||
| 198 | ;; return the minor revision number of REV, | ||
| 199 | ;; i.e. the number after the last dot. | ||
| 200 | (substring rev (1+ (string-match "\\.[0-9]+\\'" rev)))) | ||
| 201 | |||
| 202 | (defun vc-branch-part (rev) | ||
| 203 | ;; return the branch part of a revision number REV | ||
| 204 | (substring rev 0 (string-match "\\.[0-9]+\\'" rev))) | ||
| 205 | |||
| 205 | ;; Random helper functions | 206 | ;; Random helper functions |
| 206 | 207 | ||
| 207 | (defun vc-registration-error (file) | 208 | (defun vc-registration-error (file) |
| @@ -298,7 +299,7 @@ the master name of FILE if LAST is 'MASTER, or the workfile of FILE if LAST is | |||
| 298 | "Execute FORM1, FORM2 or FORM3 depending whether we're using SCCS, RCS or CVS. | 299 | "Execute FORM1, FORM2 or FORM3 depending whether we're using SCCS, RCS or CVS. |
| 299 | If FORM3 is RCS, use FORM2 even if we are using CVS. (CVS shares some code | 300 | If FORM3 is RCS, use FORM2 even if we are using CVS. (CVS shares some code |
| 300 | with RCS)." | 301 | with RCS)." |
| 301 | (list 'let (list (list 'type (list 'vc-backend-deduce f))) | 302 | (list 'let (list (list 'type (list 'vc-backend f))) |
| 302 | (list 'cond | 303 | (list 'cond |
| 303 | (list (list 'eq 'type (quote 'SCCS)) s) ;; SCCS | 304 | (list (list 'eq 'type (quote 'SCCS)) s) ;; SCCS |
| 304 | (list (list 'eq 'type (quote 'RCS)) r) ;; RCS | 305 | (list (list 'eq 'type (quote 'RCS)) r) ;; RCS |
| @@ -438,7 +439,7 @@ with RCS)." | |||
| 438 | (defun vc-next-action-on-file (file verbose &optional comment) | 439 | (defun vc-next-action-on-file (file verbose &optional comment) |
| 439 | ;;; If comment is specified, it will be used as an admin or checkin comment. | 440 | ;;; If comment is specified, it will be used as an admin or checkin comment. |
| 440 | (let ((vc-file (vc-name file)) | 441 | (let ((vc-file (vc-name file)) |
| 441 | (vc-type (vc-backend-deduce file)) | 442 | (vc-type (vc-backend file)) |
| 442 | owner version) | 443 | owner version) |
| 443 | (cond | 444 | (cond |
| 444 | 445 | ||
| @@ -521,8 +522,7 @@ with RCS)." | |||
| 521 | ;; make the buffer writable, and assert the user to be the locker | 522 | ;; make the buffer writable, and assert the user to be the locker |
| 522 | ((and (eq vc-type 'CVS) buffer-read-only) | 523 | ((and (eq vc-type 'CVS) buffer-read-only) |
| 523 | (if verbose | 524 | (if verbose |
| 524 | (progn | 525 | (let ((rev (read-string "Trunk version to move to: "))) |
| 525 | (setq rev (read-string "Trunk version to move to: ")) | ||
| 526 | (if (not (string= rev "")) | 526 | (if (not (string= rev "")) |
| 527 | (vc-checkout file nil rev) | 527 | (vc-checkout file nil rev) |
| 528 | (vc-do-command 0 "cvs" file 'WORKFILE "update" "-A") | 528 | (vc-do-command 0 "cvs" file 'WORKFILE "update" "-A") |
| @@ -1056,7 +1056,7 @@ the variable `vc-header-alist'." | |||
| 1056 | (let* ((delims (cdr (assq major-mode vc-comment-alist))) | 1056 | (let* ((delims (cdr (assq major-mode vc-comment-alist))) |
| 1057 | (comment-start-vc (or (car delims) comment-start "#")) | 1057 | (comment-start-vc (or (car delims) comment-start "#")) |
| 1058 | (comment-end-vc (or (car (cdr delims)) comment-end "")) | 1058 | (comment-end-vc (or (car (cdr delims)) comment-end "")) |
| 1059 | (hdstrings (cdr (assoc (vc-backend-deduce (buffer-file-name)) vc-header-alist)))) | 1059 | (hdstrings (cdr (assoc (vc-backend (buffer-file-name)) vc-header-alist)))) |
| 1060 | (mapcar (function (lambda (s) | 1060 | (mapcar (function (lambda (s) |
| 1061 | (insert comment-start-vc "\t" s "\t" | 1061 | (insert comment-start-vc "\t" s "\t" |
| 1062 | comment-end-vc "\n"))) | 1062 | comment-end-vc "\n"))) |
| @@ -1368,7 +1368,7 @@ A prefix argument means do not revert the buffer afterwards." | |||
| 1368 | ;; consider to be wrong. When the famous, long-awaited rename database is | 1368 | ;; consider to be wrong. When the famous, long-awaited rename database is |
| 1369 | ;; implemented things might change for the better. This is unlikely to occur | 1369 | ;; implemented things might change for the better. This is unlikely to occur |
| 1370 | ;; until CVS 2.0 is released. --ceder 1994-01-23 21:27:51 | 1370 | ;; until CVS 2.0 is released. --ceder 1994-01-23 21:27:51 |
| 1371 | (if (eq (vc-backend-deduce old) 'CVS) | 1371 | (if (eq (vc-backend old) 'CVS) |
| 1372 | (error "Renaming files under CVS is dangerous and not supported in VC.")) | 1372 | (error "Renaming files under CVS is dangerous and not supported in VC.")) |
| 1373 | (let ((oldbuf (get-file-buffer old))) | 1373 | (let ((oldbuf (get-file-buffer old))) |
| 1374 | (if (and oldbuf (buffer-modified-p oldbuf)) | 1374 | (if (and oldbuf (buffer-modified-p oldbuf)) |
| @@ -1388,7 +1388,7 @@ A prefix argument means do not revert the buffer afterwards." | |||
| 1388 | (error "This is not a safe thing to do in the presence of symbolic links")) | 1388 | (error "This is not a safe thing to do in the presence of symbolic links")) |
| 1389 | (rename-file | 1389 | (rename-file |
| 1390 | oldmaster | 1390 | oldmaster |
| 1391 | (let ((backend (vc-backend-deduce old)) | 1391 | (let ((backend (vc-backend old)) |
| 1392 | (newdir (or (file-name-directory new) "")) | 1392 | (newdir (or (file-name-directory new) "")) |
| 1393 | (newbase (file-name-nondirectory new))) | 1393 | (newbase (file-name-nondirectory new))) |
| 1394 | (catch 'found | 1394 | (catch 'found |
| @@ -1438,7 +1438,7 @@ From a program, any arguments are passed to the `rcs2log' script." | |||
| 1438 | file) | 1438 | file) |
| 1439 | (while buffers | 1439 | (while buffers |
| 1440 | (setq file (buffer-file-name (car buffers))) | 1440 | (setq file (buffer-file-name (car buffers))) |
| 1441 | (and file (vc-backend-deduce file) | 1441 | (and file (vc-backend file) |
| 1442 | (setq files (cons file files))) | 1442 | (setq files (cons file files))) |
| 1443 | (setq buffers (cdr buffers))) | 1443 | (setq buffers (cdr buffers))) |
| 1444 | files)) | 1444 | files)) |
| @@ -1477,387 +1477,8 @@ From a program, any arguments are passed to the `rcs2log' script." | |||
| 1477 | args)))) | 1477 | args)))) |
| 1478 | "done" "failed")))) | 1478 | "done" "failed")))) |
| 1479 | 1479 | ||
| 1480 | ;; Functions for querying the master and lock files. | ||
| 1481 | |||
| 1482 | (defun vc-match-substring (bn) | ||
| 1483 | (buffer-substring (match-beginning bn) (match-end bn))) | ||
| 1484 | |||
| 1485 | (defun vc-parse-buffer (patterns &optional file properties) | ||
| 1486 | ;; Use PATTERNS to parse information out of the current buffer | ||
| 1487 | ;; by matching each regular expression in the list and returning \\1. | ||
| 1488 | ;; If a regexp has three tag brackets, assume the third is a date | ||
| 1489 | ;; field and we want the most recent entry matching the template. | ||
| 1490 | ;; If FILE and PROPERTIES are given, the latter must be a list of | ||
| 1491 | ;; properties of the same length as PATTERNS; each property is assigned | ||
| 1492 | ;; the corresponding value. | ||
| 1493 | (mapcar (function (lambda (p) | ||
| 1494 | (goto-char (point-min)) | ||
| 1495 | (if (string-match "\\\\([^(]*\\\\([^(]*\\\\(" p) | ||
| 1496 | (let ((latest-date "") (latest-val)) | ||
| 1497 | (while (re-search-forward p nil t) | ||
| 1498 | (let ((date (vc-match-substring 3))) | ||
| 1499 | (if (string< latest-date date) | ||
| 1500 | (progn | ||
| 1501 | (setq latest-date date) | ||
| 1502 | (setq latest-val | ||
| 1503 | (vc-match-substring 1)))))) | ||
| 1504 | (if file | ||
| 1505 | (progn (vc-file-setprop file (car properties) latest-val) | ||
| 1506 | (setq properties (cdr properties)))) | ||
| 1507 | latest-val) | ||
| 1508 | (let ((value nil)) | ||
| 1509 | (if (re-search-forward p nil t) | ||
| 1510 | (setq value (vc-match-substring 1))) | ||
| 1511 | (if file | ||
| 1512 | (progn (vc-file-setprop file (car properties) value) | ||
| 1513 | (setq properties (cdr properties)))) | ||
| 1514 | value)))) | ||
| 1515 | patterns) | ||
| 1516 | ) | ||
| 1517 | |||
| 1518 | (defun vc-master-info (file fields &optional rfile properties) | ||
| 1519 | ;; Search for information in a master file. | ||
| 1520 | (if (and file (file-exists-p file)) | ||
| 1521 | (save-excursion | ||
| 1522 | (let ((buf)) | ||
| 1523 | (setq buf (create-file-buffer file)) | ||
| 1524 | (set-buffer buf)) | ||
| 1525 | (erase-buffer) | ||
| 1526 | (insert-file-contents file) | ||
| 1527 | (set-buffer-modified-p nil) | ||
| 1528 | (auto-save-mode nil) | ||
| 1529 | (prog1 | ||
| 1530 | (vc-parse-buffer fields rfile properties) | ||
| 1531 | (kill-buffer (current-buffer))) | ||
| 1532 | ) | ||
| 1533 | (if rfile | ||
| 1534 | (mapcar | ||
| 1535 | (function (lambda (p) (vc-file-setprop rfile p nil))) | ||
| 1536 | properties)) | ||
| 1537 | ) | ||
| 1538 | ) | ||
| 1539 | |||
| 1540 | (defun vc-log-info (command file last flags patterns &optional properties) | ||
| 1541 | ;; Search for information in log program output. | ||
| 1542 | ;; If there is a string `\X' in any of the PATTERNS, replace | ||
| 1543 | ;; it with a regexp to search for a branch revision. | ||
| 1544 | (if (and file (file-exists-p file)) | ||
| 1545 | (save-excursion | ||
| 1546 | ;; Don't switch to the *vc* buffer before running vc-do-command, | ||
| 1547 | ;; because that would change its default-directory. | ||
| 1548 | (apply 'vc-do-command 0 command file last flags) | ||
| 1549 | (set-buffer (get-buffer "*vc*")) | ||
| 1550 | (set-buffer-modified-p nil) | ||
| 1551 | (let ((branch | ||
| 1552 | (car (vc-parse-buffer (list "^branch:[ \t]+\\([0-9.]+\\)$"))))) | ||
| 1553 | (setq patterns | ||
| 1554 | (mapcar | ||
| 1555 | (function | ||
| 1556 | (lambda (p) | ||
| 1557 | (if (string-match "\\\\X" p) | ||
| 1558 | (if branch | ||
| 1559 | (cond ((vc-branch-p branch) | ||
| 1560 | (concat | ||
| 1561 | (substring p 0 (match-beginning 0)) | ||
| 1562 | (regexp-quote branch) | ||
| 1563 | "\\.[0-9]+" | ||
| 1564 | (substring p (match-end 0)))) | ||
| 1565 | (t | ||
| 1566 | (concat | ||
| 1567 | (substring p 0 (match-beginning 0)) | ||
| 1568 | (regexp-quote branch) | ||
| 1569 | (substring p (match-end 0))))) | ||
| 1570 | ;; if there is no current branch, | ||
| 1571 | ;; return a completely different regexp, | ||
| 1572 | ;; which searches for the *head* | ||
| 1573 | "^head:[ \t]+\\([0-9.]+\\)$") | ||
| 1574 | p))) | ||
| 1575 | patterns))) | ||
| 1576 | (prog1 | ||
| 1577 | (vc-parse-buffer patterns file properties) | ||
| 1578 | (kill-buffer (current-buffer)) | ||
| 1579 | ) | ||
| 1580 | ) | ||
| 1581 | (if file | ||
| 1582 | (mapcar | ||
| 1583 | (function (lambda (p) (vc-file-setprop file p nil))) | ||
| 1584 | properties)) | ||
| 1585 | ) | ||
| 1586 | ) | ||
| 1587 | |||
| 1588 | (defun vc-locking-user (file) | ||
| 1589 | "Return the name of the person currently holding a lock on FILE. | ||
| 1590 | Return nil if there is no such person. | ||
| 1591 | Under CVS, a file is considered locked if it has been modified since it | ||
| 1592 | was checked out. Under CVS, this will sometimes return the uid of | ||
| 1593 | the owner of the file (as a number) instead of a string." | ||
| 1594 | ;; The property is cached. If it is non-nil, it is simply returned. | ||
| 1595 | ;; The other routines clear it when the locking state changes. | ||
| 1596 | (setq file (expand-file-name file));; ??? Work around bug in 19.0.4 | ||
| 1597 | (cond | ||
| 1598 | ((vc-file-getprop file 'vc-locking-user)) | ||
| 1599 | ((eq (vc-backend-deduce file) 'CVS) | ||
| 1600 | (if (vc-workfile-unchanged-p file) | ||
| 1601 | nil | ||
| 1602 | ;; The expression below should return the username of the owner | ||
| 1603 | ;; of the file. It doesn't. It returns the username if it is | ||
| 1604 | ;; you, or otherwise the UID of the owner of the file. The | ||
| 1605 | ;; return value from this function is only used by | ||
| 1606 | ;; vc-dired-reformat-line, and it does the proper thing if a UID | ||
| 1607 | ;; is returned. | ||
| 1608 | ;; | ||
| 1609 | ;; The *proper* way to fix this would be to implement a built-in | ||
| 1610 | ;; function in Emacs, say, (username UID), that returns the | ||
| 1611 | ;; username of a given UID. | ||
| 1612 | ;; | ||
| 1613 | ;; The result of this hack is that vc-directory will print the | ||
| 1614 | ;; name of the owner of the file for any files that are | ||
| 1615 | ;; modified. | ||
| 1616 | (let ((uid (nth 2 (file-attributes file)))) | ||
| 1617 | (if (= uid (user-uid)) | ||
| 1618 | (vc-file-setprop file 'vc-locking-user (user-login-name)) | ||
| 1619 | (vc-file-setprop file 'vc-locking-user uid))))) | ||
| 1620 | (t | ||
| 1621 | (if (and (eq (vc-backend-deduce file) 'RCS) | ||
| 1622 | (eq (vc-consult-rcs-headers file) 'rev-and-lock)) | ||
| 1623 | (vc-file-getprop file 'vc-locking-user) | ||
| 1624 | (if (or (not vc-keep-workfiles) | ||
| 1625 | (eq vc-mistrust-permissions 't) | ||
| 1626 | (and vc-mistrust-permissions | ||
| 1627 | (funcall vc-mistrust-permissions (vc-backend-subdirectory-name | ||
| 1628 | file)))) | ||
| 1629 | (vc-file-setprop file 'vc-locking-user (vc-true-locking-user file)) | ||
| 1630 | ;; This implementation assumes that any file which is under version | ||
| 1631 | ;; control and has -rw-r--r-- is locked by its owner. This is true | ||
| 1632 | ;; for both RCS and SCCS, which keep unlocked files at -r--r--r--. | ||
| 1633 | ;; We have to be careful not to exclude files with execute bits on; | ||
| 1634 | ;; scripts can be under version control too. Also, we must ignore | ||
| 1635 | ;; the group-read and other-read bits, since paranoid users turn them off. | ||
| 1636 | ;; This hack wins because calls to the very expensive vc-fetch-properties | ||
| 1637 | ;; function only have to be made if (a) the file is locked by someone | ||
| 1638 | ;; other than the current user, or (b) some untoward manipulation | ||
| 1639 | ;; behind vc's back has changed the owner or the `group' or `other' | ||
| 1640 | ;; write bits. | ||
| 1641 | (let ((attributes (file-attributes file))) | ||
| 1642 | (cond ((string-match ".r-..-..-." (nth 8 attributes)) | ||
| 1643 | nil) | ||
| 1644 | ((and (= (nth 2 attributes) (user-uid)) | ||
| 1645 | (string-match ".rw..-..-." (nth 8 attributes))) | ||
| 1646 | (vc-file-setprop file 'vc-locking-user (user-login-name))) | ||
| 1647 | (t | ||
| 1648 | (vc-file-setprop file 'vc-locking-user | ||
| 1649 | (vc-true-locking-user file)))))))))) | ||
| 1650 | |||
| 1651 | (defun vc-true-locking-user (file) | ||
| 1652 | ;; The slow but reliable version | ||
| 1653 | (vc-fetch-properties file) | ||
| 1654 | (vc-file-getprop file 'vc-locking-user)) | ||
| 1655 | |||
| 1656 | (defun vc-latest-version (file) | ||
| 1657 | ;; Return version level of the latest version of FILE | ||
| 1658 | (vc-fetch-properties file) | ||
| 1659 | (vc-file-getprop file 'vc-latest-version)) | ||
| 1660 | |||
| 1661 | (defun vc-your-latest-version (file) | ||
| 1662 | ;; Return version level of the latest version of FILE checked in by you | ||
| 1663 | (vc-fetch-properties file) | ||
| 1664 | (vc-file-getprop file 'vc-your-latest-version)) | ||
| 1665 | |||
| 1666 | (defun vc-branch-version (file) | ||
| 1667 | ;; Return version level of the highest revision on the default branch | ||
| 1668 | ;; If there is no default branch, return the highest version number | ||
| 1669 | ;; on the trunk. | ||
| 1670 | ;; This property is defined for RCS only. | ||
| 1671 | (vc-fetch-properties file) | ||
| 1672 | (vc-file-getprop file 'vc-branch-version)) | ||
| 1673 | |||
| 1674 | (defun vc-workfile-version (file) | ||
| 1675 | ;; Return version level of the current workfile FILE | ||
| 1676 | ;; This is attempted by first looking at the RCS keywords. | ||
| 1677 | ;; If there are no keywords in the working file, | ||
| 1678 | ;; vc-branch-version is taken. | ||
| 1679 | ;; Note that this value is cached, that is, it is only | ||
| 1680 | ;; looked up if it is nil. | ||
| 1681 | ;; For SCCS, this property is equivalent to vc-latest-version. | ||
| 1682 | (cond ((vc-file-getprop file 'vc-workfile-version)) | ||
| 1683 | (t (vc-backend-dispatch file | ||
| 1684 | (vc-latest-version file) ;; SCCS | ||
| 1685 | (if (vc-consult-rcs-headers file) ;; RCS | ||
| 1686 | (vc-file-getprop file 'vc-workfile-version) | ||
| 1687 | (let ((rev (cond ((vc-branch-version file)) | ||
| 1688 | ((vc-latest-version file))))) | ||
| 1689 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1690 | rev)) | ||
| 1691 | (if (vc-consult-rcs-headers file) ;; CVS | ||
| 1692 | (vc-file-getprop file 'vc-workfile-version) | ||
| 1693 | (vc-find-cvs-master (file-name-directory file) | ||
| 1694 | (file-name-nondirectory file)) | ||
| 1695 | (vc-file-getprop file 'vc-workfile-version)))))) | ||
| 1696 | |||
| 1697 | (defun vc-consult-rcs-headers (file) | ||
| 1698 | ;; Search for RCS headers in FILE, and set properties | ||
| 1699 | ;; accordingly. This function can be disabled by setting | ||
| 1700 | ;; vc-consult-headers to nil. | ||
| 1701 | ;; Returns: nil if no headers were found | ||
| 1702 | ;; (or if the feature is disabled, | ||
| 1703 | ;; or if there is currently no buffer | ||
| 1704 | ;; visiting FILE) | ||
| 1705 | ;; 'rev if a workfile revision was found | ||
| 1706 | ;; 'rev-and-lock if revision and lock info was found | ||
| 1707 | (cond | ||
| 1708 | ((or (not vc-consult-headers) | ||
| 1709 | (not (get-file-buffer file)) nil)) | ||
| 1710 | ((save-excursion | ||
| 1711 | (set-buffer (get-file-buffer file)) | ||
| 1712 | (goto-char (point-min)) | ||
| 1713 | (cond | ||
| 1714 | ;; search for $Id or $Header | ||
| 1715 | ;; ------------------------- | ||
| 1716 | ((re-search-forward "\\$\\(Id\\|Header\\): [^ ]+ \\([0-9.]+\\) " | ||
| 1717 | nil t) | ||
| 1718 | ;; if found, store the revision number ... | ||
| 1719 | (let ((rev (buffer-substring (match-beginning 2) | ||
| 1720 | (match-end 2)))) | ||
| 1721 | ;; ... and check for the locking state | ||
| 1722 | (if (re-search-forward | ||
| 1723 | (concat "\\=[0-9]+/[0-9]+/[0-9]+ " ; date | ||
| 1724 | "[0-9]+:[0-9]+:[0-9]+ " ; time | ||
| 1725 | "[^ ]+ [^ ]+ ") ; author & state | ||
| 1726 | nil t) | ||
| 1727 | (cond | ||
| 1728 | ;; unlocked revision | ||
| 1729 | ((looking-at "\\$") | ||
| 1730 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1731 | (vc-file-setprop file 'vc-locking-user nil) | ||
| 1732 | (vc-file-setprop file 'vc-locked-version nil) | ||
| 1733 | 'rev-and-lock) | ||
| 1734 | ;; revision is locked by some user | ||
| 1735 | ((looking-at "\\([^ ]+\\) \\$") | ||
| 1736 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1737 | (vc-file-setprop file 'vc-locking-user | ||
| 1738 | (buffer-substring (match-beginning 1) | ||
| 1739 | (match-end 1))) | ||
| 1740 | (vc-file-setprop file 'vc-locked-version rev) | ||
| 1741 | 'rev-and-lock) | ||
| 1742 | ;; everything else: false | ||
| 1743 | (nil)) | ||
| 1744 | ;; unexpected information in | ||
| 1745 | ;; keyword string --> quit | ||
| 1746 | nil))) | ||
| 1747 | ;; search for $Revision | ||
| 1748 | ;; -------------------- | ||
| 1749 | ((re-search-forward (concat "\\$" | ||
| 1750 | "Revision: \\([0-9.]+\\) \\$") | ||
| 1751 | nil t) | ||
| 1752 | ;; if found, store the revision number ... | ||
| 1753 | (let ((rev (buffer-substring (match-beginning 1) | ||
| 1754 | (match-end 1)))) | ||
| 1755 | ;; and see if there's any lock information | ||
| 1756 | (goto-char (point-min)) | ||
| 1757 | (if (re-search-forward (concat "\\$" "Locker:") nil t) | ||
| 1758 | (cond ((looking-at " \\([^ ]+\\) \\$") | ||
| 1759 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1760 | (vc-file-setprop file 'vc-locking-user | ||
| 1761 | (buffer-substring (match-beginning 1) | ||
| 1762 | (match-end 1))) | ||
| 1763 | (vc-file-setprop file 'vc-locked-version rev) | ||
| 1764 | 'rev-and-lock) | ||
| 1765 | ((looking-at " *\\$") | ||
| 1766 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1767 | (vc-file-setprop file 'vc-locking-user nil) | ||
| 1768 | (vc-file-setprop file 'vc-locked-version nil) | ||
| 1769 | 'rev-and-lock) | ||
| 1770 | (t | ||
| 1771 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1772 | 'rev-and-lock)) | ||
| 1773 | (vc-file-setprop file 'vc-workfile-version rev) | ||
| 1774 | 'rev))) | ||
| 1775 | ;; else: nothing found | ||
| 1776 | ;; ------------------- | ||
| 1777 | (t nil)))))) | ||
| 1778 | |||
| 1779 | ;; Collect back-end-dependent stuff here | 1480 | ;; Collect back-end-dependent stuff here |
| 1780 | 1481 | ||
| 1781 | (defun vc-lock-file (file) | ||
| 1782 | ;; Generate lock file name corresponding to FILE | ||
| 1783 | (let ((master (vc-name file))) | ||
| 1784 | (and | ||
| 1785 | master | ||
| 1786 | (string-match "\\(.*/\\)s\\.\\(.*\\)" master) | ||
| 1787 | (concat | ||
| 1788 | (substring master (match-beginning 1) (match-end 1)) | ||
| 1789 | "p." | ||
| 1790 | (substring master (match-beginning 2) (match-end 2)))))) | ||
| 1791 | |||
| 1792 | |||
| 1793 | (defun vc-fetch-properties (file) | ||
| 1794 | ;; Re-fetch some properties associated with the given file. | ||
| 1795 | ;; Currently these properties are: | ||
| 1796 | ;; vc-locking-user | ||
| 1797 | ;; vc-locked-version | ||
| 1798 | ;; vc-latest-version | ||
| 1799 | ;; vc-your-latest-version | ||
| 1800 | ;; vc-branch-version (RCS only) | ||
| 1801 | (vc-backend-dispatch | ||
| 1802 | file | ||
| 1803 | ;; SCCS | ||
| 1804 | (progn | ||
| 1805 | (vc-master-info (vc-lock-file file) | ||
| 1806 | (list | ||
| 1807 | "^[^ ]+ [^ ]+ \\([^ ]+\\)" | ||
| 1808 | "^\\([^ ]+\\)") | ||
| 1809 | file | ||
| 1810 | '(vc-locking-user vc-locked-version)) | ||
| 1811 | (vc-master-info (vc-name file) | ||
| 1812 | (list | ||
| 1813 | "^\001d D \\([^ ]+\\)" | ||
| 1814 | (concat "^\001d D \\([^ ]+\\) .* " | ||
| 1815 | (regexp-quote (user-login-name)) " ") | ||
| 1816 | ) | ||
| 1817 | file | ||
| 1818 | '(vc-latest-version vc-your-latest-version)) | ||
| 1819 | ) | ||
| 1820 | ;; RCS | ||
| 1821 | (vc-log-info "rlog" file 'MASTER nil | ||
| 1822 | (list | ||
| 1823 | "^locks: strict\n\t\\([^:]+\\)" | ||
| 1824 | "^locks: strict\n\t[^:]+: \\(.+\\)" | ||
| 1825 | "^revision[\t ]+\\([0-9.]+\\)\\(\n\\|[ \t].*\n\\)date: \\([ /0-9:]+\\);" | ||
| 1826 | (concat | ||
| 1827 | "^revision[\t ]+\\([0-9.]+\\)\\(\n\\|[ \t].*\n\\)date: \\([ /0-9:]+\\); *author: " | ||
| 1828 | (regexp-quote (user-login-name)) | ||
| 1829 | ";") | ||
| 1830 | |||
| 1831 | ;; special regexp to search for branch revision: | ||
| 1832 | ;; \X will be replaced by vc-log-info (see there) | ||
| 1833 | "^revision[\t ]+\\(\\X\\)\\(\n\\|[ \t].*\n\\)date: \\([ /0-9:]+\\);") | ||
| 1834 | |||
| 1835 | '(vc-locking-user | ||
| 1836 | vc-locked-version | ||
| 1837 | vc-latest-version | ||
| 1838 | vc-your-latest-version | ||
| 1839 | vc-branch-version)) | ||
| 1840 | ;; CVS | ||
| 1841 | ;; Only fetch vc-latest-version here, all other properties are | ||
| 1842 | ;; computed elsehow. | ||
| 1843 | (vc-log-info | ||
| 1844 | "cvs" file 'WORKFILE '("status") | ||
| 1845 | ;; CVS 1.3 says "RCS Version:", other releases "RCS Revision:", | ||
| 1846 | ;; and CVS 1.4a1 says "Repository revision:". The regexp below | ||
| 1847 | ;; matches much more, but because of the way vc-log-info is | ||
| 1848 | ;; implemented it is impossible to use additional groups. | ||
| 1849 | '("R[eC][pS][ositry]* [VRr]e[rv][si][is]i?on:[\t ]+\\([0-9.]+\\)") | ||
| 1850 | '(vc-latest-version)) | ||
| 1851 | )) | ||
| 1852 | |||
| 1853 | (defun vc-backend-subdirectory-name (&optional file) | ||
| 1854 | ;; Where the master and lock files for the current directory are kept | ||
| 1855 | (symbol-name | ||
| 1856 | (or | ||
| 1857 | (and file (vc-backend-deduce file)) | ||
| 1858 | vc-default-back-end | ||
| 1859 | (setq vc-default-back-end (if (vc-find-binary "rcs") 'RCS 'SCCS))))) | ||
| 1860 | |||
| 1861 | (defun vc-backend-admin (file &optional rev comment) | 1482 | (defun vc-backend-admin (file &optional rev comment) |
| 1862 | ;; Register a file into the version-control system | 1483 | ;; Register a file into the version-control system |
| 1863 | ;; Automatically retrieves a read-only version of the file with | 1484 | ;; Automatically retrieves a read-only version of the file with |
| @@ -2184,7 +1805,7 @@ the owner of the file (as a number) instead of a string." | |||
| 2184 | (defun vc-backend-diff (file &optional oldvers newvers cmp) | 1805 | (defun vc-backend-diff (file &optional oldvers newvers cmp) |
| 2185 | ;; Get a difference report between two versions of FILE. | 1806 | ;; Get a difference report between two versions of FILE. |
| 2186 | ;; Get only a brief comparison report if CMP, a difference report otherwise. | 1807 | ;; Get only a brief comparison report if CMP, a difference report otherwise. |
| 2187 | (let ((backend (vc-backend-deduce file))) | 1808 | (let ((backend (vc-backend file))) |
| 2188 | (cond | 1809 | (cond |
| 2189 | ((eq backend 'SCCS) | 1810 | ((eq backend 'SCCS) |
| 2190 | (setq oldvers (vc-lookup-triple file oldvers)) | 1811 | (setq oldvers (vc-lookup-triple file oldvers)) |