aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKévin Le Gouguec2024-02-12 08:29:19 +0100
committerKévin Le Gouguec2024-03-17 22:37:28 +0100
commit8d4a8b7dfd0905defac172cc58c2252dc1b39ad7 (patch)
tree57bb9cc6cdfae228b9768a6f04351533204229b8
parentc29b6df2273347946d5b8c88b5dee39d8d6fd202 (diff)
downloademacs-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.el46
-rw-r--r--test/lisp/vc/vc-git-tests.el40
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.
2239Return 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.
2244The 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.
2233FILE can be nil." 2251FILE 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
89The current directory will be set to the top of that repository; NAME
90will be bound to that directory's file name. Once BODY exits, the
91directory 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