diff options
| author | Juanma Barranquero | 2015-11-19 21:32:43 +0100 |
|---|---|---|
| committer | Juanma Barranquero | 2015-11-20 01:23:35 +0100 |
| commit | c210b8b128c17929dbb8e0b0564ee25930d44dd1 (patch) | |
| tree | 99189a70672671e9d556c6b2cd45985abff3b2d9 | |
| parent | 32845e3aad4d45a03851e92973ce0d31fd8a81e1 (diff) | |
| download | emacs-c210b8b128c17929dbb8e0b0564ee25930d44dd1.tar.gz emacs-c210b8b128c17929dbb8e0b0564ee25930d44dd1.zip | |
Discover repository version in linked worktrees (bug#21930)
* lisp/version.el (emacs-repository--version-git-1): Do not assume
HEAD is at .git/HEAD, it can also be at .git/worktrees/<branch>/HEAD.
(emacs-repository-get-version): Grok linked worktrees when EXTERNAL
is nil too.
| -rw-r--r-- | lisp/version.el | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/lisp/version.el b/lisp/version.el index 43103fde131..4207cb41f21 100644 --- a/lisp/version.el +++ b/lisp/version.el | |||
| @@ -113,17 +113,17 @@ or if we could not determine the revision.") | |||
| 113 | (looking-at "[0-9a-fA-F]\\{40\\}")) | 113 | (looking-at "[0-9a-fA-F]\\{40\\}")) |
| 114 | (match-string 0))))) | 114 | (match-string 0))))) |
| 115 | 115 | ||
| 116 | (defun emacs-repository--version-git-1 (file) | 116 | (defun emacs-repository--version-git-1 (file dir) |
| 117 | "Internal subroutine of `emacs-repository-get-version'." | 117 | "Internal subroutine of `emacs-repository-get-version'." |
| 118 | (when (file-readable-p file) | 118 | (when (file-readable-p file) |
| 119 | (erase-buffer) | 119 | (with-temp-buffer |
| 120 | (insert-file-contents file) | 120 | (insert-file-contents file) |
| 121 | (cond ((looking-at "[0-9a-fA-F]\\{40\\}") | 121 | (cond ((looking-at "[0-9a-fA-F]\\{40\\}") |
| 122 | (match-string 0)) | 122 | (match-string 0)) |
| 123 | ((looking-at "ref: \\(.*\\)") | 123 | ((looking-at "ref: \\(.*\\)") |
| 124 | (emacs-repository--version-git-1 | 124 | (emacs-repository--version-git-1 |
| 125 | (expand-file-name (match-string 1) | 125 | (expand-file-name (match-string 1) dir) |
| 126 | (file-name-directory file))))))) | 126 | dir)))))) |
| 127 | 127 | ||
| 128 | (defun emacs-repository-get-version (&optional dir external) | 128 | (defun emacs-repository-get-version (&optional dir external) |
| 129 | "Try to return as a string the repository revision of the Emacs sources. | 129 | "Try to return as a string the repository revision of the Emacs sources. |
| @@ -138,20 +138,38 @@ Optional argument EXTERNAL non-nil means to just ask the VCS itself, | |||
| 138 | if the sources appear to be under version control. Otherwise only ask | 138 | if the sources appear to be under version control. Otherwise only ask |
| 139 | the VCS if we cannot find any information ourselves." | 139 | the VCS if we cannot find any information ourselves." |
| 140 | (or dir (setq dir source-directory)) | 140 | (or dir (setq dir source-directory)) |
| 141 | (when (file-directory-p (expand-file-name ".git" dir)) | 141 | (let* ((base-dir (expand-file-name ".git" dir)) |
| 142 | (if external | 142 | (in-main-worktree (file-directory-p base-dir)) |
| 143 | (emacs-repository-version-git dir) | 143 | (in-linked-worktree nil) |
| 144 | (or (let ((files '("HEAD" "refs/heads/master")) | 144 | sub-dir) |
| 145 | file rev) | 145 | ;; If the sources are in a linked worktree, .git is a file that points to |
| 146 | (with-temp-buffer | 146 | ;; the location of the main worktree and the repo's administrative files. |
| 147 | (while (and (not rev) | 147 | (when (and (not in-main-worktree) |
| 148 | (setq file (car files))) | 148 | (file-regular-p base-dir) |
| 149 | (setq file (expand-file-name (format ".git/%s" file) dir) | 149 | (file-readable-p base-dir)) |
| 150 | files (cdr files) | 150 | (with-temp-buffer |
| 151 | rev (emacs-repository--version-git-1 file)))) | 151 | (insert-file-contents base-dir) |
| 152 | rev) | 152 | (when (looking-at "gitdir: \\(.*\.git\\)\\(.*\\)$") |
| 153 | ;; AFAICS this doesn't work during dumping (bug#20799). | 153 | (setq base-dir (match-string 1) |
| 154 | (emacs-repository-version-git dir))))) | 154 | sub-dir (concat base-dir (match-string 2)) |
| 155 | in-linked-worktree t)))) | ||
| 156 | ;; We've found a worktree, either main or linked. | ||
| 157 | (when (or in-main-worktree in-linked-worktree) | ||
| 158 | (if external | ||
| 159 | (emacs-repository-version-git dir) | ||
| 160 | (or (if in-linked-worktree | ||
| 161 | (emacs-repository--version-git-1 | ||
| 162 | (expand-file-name "HEAD" sub-dir) base-dir) | ||
| 163 | (let ((files '("HEAD" "refs/heads/master")) | ||
| 164 | file rev) | ||
| 165 | (while (and (not rev) | ||
| 166 | (setq file (car files))) | ||
| 167 | (setq file (expand-file-name file base-dir) | ||
| 168 | files (cdr files) | ||
| 169 | rev (emacs-repository--version-git-1 file base-dir))) | ||
| 170 | rev)) | ||
| 171 | ;; AFAICS this doesn't work during dumping (bug#20799). | ||
| 172 | (emacs-repository-version-git dir)))))) | ||
| 155 | 173 | ||
| 156 | ;; We put version info into the executable in the form that `ident' uses. | 174 | ;; We put version info into the executable in the form that `ident' uses. |
| 157 | (purecopy (concat "\n$Id: " (subst-char-in-string ?\n ?\s (emacs-version)) | 175 | (purecopy (concat "\n$Id: " (subst-char-in-string ?\n ?\s (emacs-version)) |