diff options
| author | Kévin Le Gouguec | 2024-02-12 08:29:19 +0100 |
|---|---|---|
| committer | Kévin Le Gouguec | 2024-03-17 22:37:28 +0100 |
| commit | 8d4a8b7dfd0905defac172cc58c2252dc1b39ad7 (patch) | |
| tree | 57bb9cc6cdfae228b9768a6f04351533204229b8 | |
| parent | c29b6df2273347946d5b8c88b5dee39d8d6fd202 (diff) | |
| download | emacs-8d4a8b7dfd0905defac172cc58c2252dc1b39ad7.tar.gz emacs-8d4a8b7dfd0905defac172cc58c2252dc1b39ad7.zip | |
; Re-apply accidentally reverted commit
This re-applies:
2024-03-17 "Fix vc-dir when "remote" Git branch is local"
(21828f288ef)
reverted as part of the unrelated:
2024-03-17 "Update modus-themes to their 4.4.0 version"
(67b0c1c09ea)
The original commit message follows:
Fix vc-dir when "remote" Git branch is local
While in there, add that "tracking" branch to the vc-dir
buffer. For bug#68183.
* lisp/vc/vc-git.el (vc-git-dir-extra-headers): Reduce
boilerplate with new function 'vc-git--out-ok'; stop calling
vc-git-repository-url when REMOTE is "." to avoid throwing an
error; display tracking branch; prefer "none (<details...>)" to
"not (<details...>)" since that reads more grammatically
correct.
(vc-git--out-ok): Add documentation.
(vc-git--out-str): New function to easily get the output from a
Git command.
* test/lisp/vc/vc-git-tests.el (vc-git-test--with-repo)
(vc-git-test--run): New helpers, defined to steer clear of
vc-git-- internal functions.
(vc-git-test-dir-track-local-branch): Check that vc-dir does
not crash.
| -rw-r--r-- | lisp/vc/vc-git.el | 46 | ||||
| -rw-r--r-- | test/lisp/vc/vc-git-tests.el | 40 |
2 files changed, 72 insertions, 14 deletions
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 18b4a8691e9..0d54e234659 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el | |||
| @@ -817,27 +817,31 @@ or an empty string if none." | |||
| 817 | cmds)) | 817 | cmds)) |
| 818 | 818 | ||
| 819 | (defun vc-git-dir-extra-headers (dir) | 819 | (defun vc-git-dir-extra-headers (dir) |
| 820 | (let ((str (with-output-to-string | 820 | (let ((str (vc-git--out-str "symbolic-ref" "HEAD")) |
| 821 | (with-current-buffer standard-output | ||
| 822 | (vc-git--out-ok "symbolic-ref" "HEAD")))) | ||
| 823 | (stash-list (vc-git-stash-list)) | 821 | (stash-list (vc-git-stash-list)) |
| 824 | (default-directory dir) | 822 | (default-directory dir) |
| 825 | (in-progress (vc-git--cmds-in-progress)) | 823 | (in-progress (vc-git--cmds-in-progress)) |
| 826 | 824 | ||
| 827 | branch remote remote-url stash-button stash-string) | 825 | branch remote-url stash-button stash-string tracking-branch) |
| 828 | (if (string-match "^\\(refs/heads/\\)?\\(.+\\)$" str) | 826 | (if (string-match "^\\(refs/heads/\\)?\\(.+\\)$" str) |
| 829 | (progn | 827 | (progn |
| 830 | (setq branch (match-string 2 str)) | 828 | (setq branch (match-string 2 str)) |
| 831 | (setq remote | 829 | (let ((remote (vc-git--out-str |
| 832 | (with-output-to-string | 830 | "config" (concat "branch." branch ".remote"))) |
| 833 | (with-current-buffer standard-output | 831 | (merge (vc-git--out-str |
| 834 | (vc-git--out-ok "config" | 832 | "config" (concat "branch." branch ".merge")))) |
| 835 | (concat "branch." branch ".remote"))))) | 833 | (when (string-match "\\([^\n]+\\)" remote) |
| 836 | (when (string-match "\\([^\n]+\\)" remote) | 834 | (setq remote (match-string 1 remote))) |
| 837 | (setq remote (match-string 1 remote))) | 835 | (when (string-match "^\\(refs/heads/\\)?\\(.+\\)$" merge) |
| 838 | (when (> (length remote) 0) | 836 | (setq tracking-branch (match-string 2 merge))) |
| 839 | (setq remote-url (vc-git-repository-url dir remote)))) | 837 | (pcase remote |
| 840 | (setq branch "not (detached HEAD)")) | 838 | ("." |
| 839 | (setq remote-url "none (tracking local branch)")) | ||
| 840 | ((pred (not string-empty-p)) | ||
| 841 | (setq | ||
| 842 | remote-url (vc-git-repository-url dir remote) | ||
| 843 | tracking-branch (concat remote "/" tracking-branch)))))) | ||
| 844 | (setq branch "none (detached HEAD)")) | ||
| 841 | (when stash-list | 845 | (when stash-list |
| 842 | (let* ((len (length stash-list)) | 846 | (let* ((len (length stash-list)) |
| 843 | (limit | 847 | (limit |
| @@ -890,6 +894,11 @@ or an empty string if none." | |||
| 890 | (propertize "Branch : " 'face 'vc-dir-header) | 894 | (propertize "Branch : " 'face 'vc-dir-header) |
| 891 | (propertize branch | 895 | (propertize branch |
| 892 | 'face 'vc-dir-header-value) | 896 | 'face 'vc-dir-header-value) |
| 897 | (when tracking-branch | ||
| 898 | (concat | ||
| 899 | "\n" | ||
| 900 | (propertize "Tracking : " 'face 'vc-dir-header) | ||
| 901 | (propertize tracking-branch 'face 'vc-dir-header-value))) | ||
| 893 | (when remote-url | 902 | (when remote-url |
| 894 | (concat | 903 | (concat |
| 895 | "\n" | 904 | "\n" |
| @@ -2226,8 +2235,17 @@ The difference to vc-do-command is that this function always invokes | |||
| 2226 | (apply #'process-file vc-git-program nil buffer nil "--no-pager" command args))) | 2235 | (apply #'process-file vc-git-program nil buffer nil "--no-pager" command args))) |
| 2227 | 2236 | ||
| 2228 | (defun vc-git--out-ok (command &rest args) | 2237 | (defun vc-git--out-ok (command &rest args) |
| 2238 | "Run `git COMMAND ARGS...' and insert standard output in current buffer. | ||
| 2239 | Return whether the process exited with status zero." | ||
| 2229 | (zerop (apply #'vc-git--call '(t nil) command args))) | 2240 | (zerop (apply #'vc-git--call '(t nil) command args))) |
| 2230 | 2241 | ||
| 2242 | (defun vc-git--out-str (command &rest args) | ||
| 2243 | "Run `git COMMAND ARGS...' and return standard output. | ||
| 2244 | The exit status is ignored." | ||
| 2245 | (with-output-to-string | ||
| 2246 | (with-current-buffer standard-output | ||
| 2247 | (apply #'vc-git--out-ok command args)))) | ||
| 2248 | |||
| 2231 | (defun vc-git--run-command-string (file &rest args) | 2249 | (defun vc-git--run-command-string (file &rest args) |
| 2232 | "Run a git command on FILE and return its output as string. | 2250 | "Run a git command on FILE and return its output as string. |
| 2233 | FILE can be nil." | 2251 | FILE can be nil." |
diff --git a/test/lisp/vc/vc-git-tests.el b/test/lisp/vc/vc-git-tests.el index c52cd9c5875..fd3e8ccd602 100644 --- a/test/lisp/vc/vc-git-tests.el +++ b/test/lisp/vc/vc-git-tests.el | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Code: | 25 | ;;; Code: |
| 26 | 26 | ||
| 27 | (require 'ert-x) | ||
| 28 | (require 'vc) | ||
| 27 | (require 'vc-git) | 29 | (require 'vc-git) |
| 28 | 30 | ||
| 29 | (ert-deftest vc-git-test-program-version-general () | 31 | (ert-deftest vc-git-test-program-version-general () |
| @@ -81,4 +83,42 @@ | |||
| 81 | (should-not (vc-git-annotate-time)) | 83 | (should-not (vc-git-annotate-time)) |
| 82 | (should-not (vc-git-annotate-time)))) | 84 | (should-not (vc-git-annotate-time)))) |
| 83 | 85 | ||
| 86 | (defmacro vc-git-test--with-repo (name &rest body) | ||
| 87 | "Initialize a repository in a temporary directory and evaluate BODY. | ||
| 88 | |||
| 89 | The current directory will be set to the top of that repository; NAME | ||
| 90 | will be bound to that directory's file name. Once BODY exits, the | ||
| 91 | directory will be deleted." | ||
| 92 | (declare (indent 1)) | ||
| 93 | `(ert-with-temp-directory ,name | ||
| 94 | (let ((default-directory ,name)) | ||
| 95 | (vc-create-repo 'Git) | ||
| 96 | ,@body))) | ||
| 97 | |||
| 98 | (defun vc-git-test--run (&rest args) | ||
| 99 | "Run git ARGS…, check for non-zero status, and return output." | ||
| 100 | (with-temp-buffer | ||
| 101 | (apply 'vc-git-command t 0 nil args) | ||
| 102 | (buffer-string))) | ||
| 103 | |||
| 104 | (ert-deftest vc-git-test-dir-track-local-branch () | ||
| 105 | "Test that `vc-dir' works when tracking local branches. Bug#68183." | ||
| 106 | (skip-unless (executable-find vc-git-program)) | ||
| 107 | (vc-git-test--with-repo repo | ||
| 108 | ;; Create an initial commit to get a branch started. | ||
| 109 | (write-region "hello" nil "README") | ||
| 110 | (vc-git-test--run "add" "README") | ||
| 111 | (vc-git-test--run "commit" "-mFirst") | ||
| 112 | ;; Get current branch name lazily, to remain agnostic of | ||
| 113 | ;; init.defaultbranch. | ||
| 114 | (let ((upstream-branch | ||
| 115 | (string-trim (vc-git-test--run "branch" "--show-current")))) | ||
| 116 | (vc-git-test--run "checkout" "--track" "-b" "hack" upstream-branch) | ||
| 117 | (vc-dir default-directory) | ||
| 118 | (pcase-dolist (`(,header ,value) | ||
| 119 | `(("Branch" "hack") | ||
| 120 | ("Tracking" ,upstream-branch))) | ||
| 121 | (goto-char (point-min)) | ||
| 122 | (re-search-forward (format "^%s *: %s$" header value)))))) | ||
| 123 | |||
| 84 | ;;; vc-git-tests.el ends here | 124 | ;;; vc-git-tests.el ends here |