Package: emacs Version: 25.0.50 Severity: minor When run inside a linked worktree (created with "git worktree add ..."), emacs-repository-get-version needs to ask the VCS to find the repository version, which doesn't work during dumping. I'd like to apply this patch to the release branch. diff --git i/lisp/version.el w/lisp/version.el index 43103fd..4207cb4 100644 --- i/lisp/version.el +++ w/lisp/version.el @@ -114,15 +114,15 @@ emacs-repository-version-git (match-string 0))))) -(defun emacs-repository--version-git-1 (file) +(defun emacs-repository--version-git-1 (file dir) "Internal subroutine of `emacs-repository-get-version'." (when (file-readable-p file) - (erase-buffer) - (insert-file-contents file) - (cond ((looking-at "[0-9a-fA-F]\\{40\\}") - (match-string 0)) - ((looking-at "ref: \\(.*\\)") - (emacs-repository--version-git-1 - (expand-file-name (match-string 1) - (file-name-directory file))))))) + (with-temp-buffer + (insert-file-contents file) + (cond ((looking-at "[0-9a-fA-F]\\{40\\}") + (match-string 0)) + ((looking-at "ref: \\(.*\\)") + (emacs-repository--version-git-1 + (expand-file-name (match-string 1) dir) + dir)))))) (defun emacs-repository-get-version (&optional dir external) @@ -139,18 +139,36 @@ emacs-repository-get-version the VCS if we cannot find any information ourselves." (or dir (setq dir source-directory)) - (when (file-directory-p (expand-file-name ".git" dir)) - (if external - (emacs-repository-version-git dir) - (or (let ((files '("HEAD" "refs/heads/master")) - file rev) - (with-temp-buffer - (while (and (not rev) - (setq file (car files))) - (setq file (expand-file-name (format ".git/%s" file) dir) - files (cdr files) - rev (emacs-repository--version-git-1 file)))) - rev) - ;; AFAICS this doesn't work during dumping (bug#20799). - (emacs-repository-version-git dir))))) + (let* ((base-dir (expand-file-name ".git" dir)) + (in-main-worktree (file-directory-p base-dir)) + (in-linked-worktree nil) + sub-dir) + ;; If the sources are in a linked worktree, .git is a file that points to + ;; the location of the main worktree and the repo's administrative files. + (when (and (not in-main-worktree) + (file-regular-p base-dir) + (file-readable-p base-dir)) + (with-temp-buffer + (insert-file-contents base-dir) + (when (looking-at "gitdir: \\(.*\.git\\)\\(.*\\)$") + (setq base-dir (match-string 1) + sub-dir (concat base-dir (match-string 2)) + in-linked-worktree t)))) + ;; We've found a worktree, either main or linked. + (when (or in-main-worktree in-linked-worktree) + (if external + (emacs-repository-version-git dir) + (or (if in-linked-worktree + (emacs-repository--version-git-1 + (expand-file-name "HEAD" sub-dir) base-dir) + (let ((files '("HEAD" "refs/heads/master")) + file rev) + (while (and (not rev) + (setq file (car files))) + (setq file (expand-file-name file base-dir) + files (cdr files) + rev (emacs-repository--version-git-1 file base-dir))) + rev)) + ;; AFAICS this doesn't work during dumping (bug#20799). + (emacs-repository-version-git dir)))))) ;; We put version info into the executable in the form that `ident' uses.