X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/8c74a125c85da08e34dceedb271b71b5f09ce690..34dc21db6e57ebbad81a196002fcd3cc557f096e:/lisp/version.el diff --git a/lisp/version.el b/lisp/version.el index e63c51d0d2..68b502ce45 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -1,9 +1,9 @@ ;;; version.el --- record version number of Emacs -;; Copyright (C) 1985, 1992, 1994-1995, 1999-2012 -;; Free Software Foundation, Inc. +;; Copyright (C) 1985, 1992, 1994-1995, 1999-2014 Free Software +;; Foundation, Inc. -;; Maintainer: FSF +;; Maintainer: emacs-devel@gnu.org ;; Keywords: internal ;; Package: emacs @@ -85,42 +85,113 @@ to the system configuration; look at `system-configuration' instead." (defalias 'version 'emacs-version) ;; Set during dumping, this is a defvar so that it can be setq'd. -(defvar emacs-bzr-version nil - "String giving the bzr revision from which this Emacs was built. -Value is the bzr revision number and a revision ID separated by a blank. -Value is nil if Emacs was not built from a bzr checkout, or if we could -not determine the revision.") - -(defun emacs-bzr-get-version (&optional dir) - "Try to return as a string the bzr revision number of the Emacs sources. -Value is the bzr revision number and a revision ID separated by a blank. -Value is nil if the sources do not seem to be under bzr, or if we could -not determine the revision. Note that this reports on the current state -of the sources, which may not correspond to the running Emacs. - -Optional argument DIR is a directory to use instead of `source-directory'." +(defvar emacs-repository-version nil + "String giving the repository revision from which this Emacs was built. +Value is nil if Emacs was not built from a repository checkout, +or if we could not determine the revision.") + +(define-obsolete-variable-alias 'emacs-bzr-version + 'emacs-repository-version "24.4") + +(defun emacs-bzr-version-dirstate (dir) + "Try to return as a string the bzr revision ID of directory DIR. +This uses the dirstate file's parent revision entry. +Returns nil if unable to find this information." + (let ((file (expand-file-name ".bzr/checkout/dirstate" dir))) + (when (file-readable-p file) + (with-temp-buffer + (insert-file-contents file) + (and (looking-at "#bazaar dirstate flat format 3") + (forward-line 3) + (looking-at "[0-9]+\0\\([^\0\n]+\\)\0") + (match-string 1)))))) + +(defun emacs-bzr-version-bzr (dir) + "Ask bzr itself for the version information for directory DIR." + ;; Comments on `bzr version-info': + ;; i) Unknown files also cause clean != 1. + ;; ii) It can be slow, contacting the upstream repo to get the + ;; branch nick if one is not set locally, even with a custom + ;; template that is not asking for the nick (as used here). You'd + ;; think the latter part would be trivial to fix: + ;; https://bugs.launchpad.net/bzr/+bug/882541/comments/3 + ;; https://bugs.launchpad.net/bzr/+bug/629150 + ;; You can set the nick locally with `bzr nick ...', which speeds + ;; things up enormously. `bzr revno' does not have this issue, but + ;; has no way to print the revision_id AFAICS. + (message "Waiting for bzr...") + (with-temp-buffer + (if (zerop + (call-process "bzr" nil '(t nil) nil "version-info" + "--custom" + "--template={revno} {revision_id} (clean = {clean})" + dir)) + (buffer-string)))) + +(define-obsolete-function-alias 'emacs-bzr-get-version + 'emacs-repository-get-version "24.4") + +(defun emacs-repository-get-version (&optional dir external) + "Try to return as a string the repository revision of the Emacs sources. +The format of the returned string is dependent on the VCS in use. +Value is nil if the sources do not seem to be under version +control, or if we could not determine the revision. Note that +this reports on the current state of the sources, which may not +correspond to the running Emacs. + +Optional argument DIR is a directory to use instead of +`source-directory'. Optional argument EXTERNAL non-nil means to +maybe ask the VCS itself, if the sources appear to be under +version control. If `force', always ask. the VCS. Otherwise +only ask the VCS if we cannot find any information ourselves." (or dir (setq dir source-directory)) - (when (file-directory-p (setq dir (expand-file-name ".bzr/branch" dir))) - (let (file loc) - (cond ((file-readable-p - (setq file (expand-file-name "last-revision" dir))) - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-max)) - (if (looking-back "\n") - (delete-char -1)) - (buffer-string))) - ;; OK, no last-revision. Is it a lightweight checkout? - ((file-readable-p - (setq file (expand-file-name "location" dir))) - ;; If the parent branch is local, try looking there for the revid. - (if (setq loc (with-temp-buffer - (insert-file-contents file) - (if (looking-at "file://\\(.*\\)") - (match-string 1)))) - (emacs-bzr-get-version loc))) - ;; Could fall back to eg `bzr testament' at this point. - )))) + (cond ((file-directory-p (expand-file-name ".bzr/branch" dir)) + (if (eq external 'force) + (emacs-bzr-version-bzr dir) + (let (file loc rev) + (cond ((file-readable-p + (setq file (expand-file-name + ".bzr/branch/last-revision" dir))) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-max)) + (if (looking-back "\n") + (delete-char -1)) + (buffer-string))) + ;; OK, no last-revision. Is it a lightweight checkout? + ((file-readable-p + (setq file (expand-file-name ".bzr/branch/location" dir))) + (setq rev (emacs-bzr-version-dirstate dir)) + ;; If parent branch is local, try looking there for the rev. + ;; Note: there is no guarantee that the parent branch's rev + ;; corresponds to this branch. This branch could have + ;; been made with a specific -r revno argument, or the + ;; parent could have been updated since this branch was + ;; created. + ;; To try and detect this, we check the dirstate revids + ;; to see if they match. + (if (and (setq loc (with-temp-buffer + (insert-file-contents file) + (if (looking-at "file://\\(.*\\)") + (match-string 1)))) + (equal rev (emacs-bzr-version-dirstate loc))) + (emacs-repository-get-version loc) + ;; If parent does not match, the best we can do without + ;; calling external commands is to use the dirstate rev. + rev)) + (external + (emacs-bzr-version-bzr dir)))))) + ((file-directory-p (expand-file-name ".git" dir)) + (message "Waiting for git...") + (with-temp-buffer + (let ((default-directory (file-name-as-directory dir))) + (and (eq 0 + (condition-case nil + (call-process "git" nil '(t nil) nil "log" + "-1" "--pretty=format:%N") + (error nil))) + (not (zerop (buffer-size))) + (replace-regexp-in-string "\n" "" (buffer-string)))))))) ;; We put version info into the executable in the form that `ident' uses. (purecopy (concat "\n$Id: " (subst-char-in-string ?\n ?\s (emacs-version))