emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/git-commit 8394f0d4ea 8/9: Refactor git version asserts


From: ELPA Syncer
Subject: [nongnu] elpa/git-commit 8394f0d4ea 8/9: Refactor git version asserts
Date: Tue, 22 Feb 2022 05:58:10 -0500 (EST)

branch: elpa/git-commit
commit 8394f0d4ea5ffa6858db314efabe91d99f78e67a
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Jonas Bernoulli <jonas@bernoul.li>

    Refactor git version asserts
    
    `magit-git-version' now displays an error message if Git cannot be
    found, if it exits with a non-zero status, or the output does not have
    the expected format.
    
    The new function `magit-git-version-assert' uses the former function
    and so displays a message for the same issues.  Additionally it checks
    if Git is recent enough and if not it displays an error message about
    that.
    
    `magit--tramp-asserts' is no longer needed because the former function
    now does everything it used to do.  Likewise `magit-startup-assert'
    now longer has to display warnings about older Gits itself anymore.
    
    `magit--host-git-version-cache' replaces
    `magit--remotes-using-recent-git', which makes cache lookup more
    expensive because it involves version comparison.  On the other hand
    it allows comparing with different minimal versions, not just the
    global minimum.  The use of `magit--with-refresh-cache' should also
    help with the increased cost.
    
    The displayed error messages are trimmed down a bit, removing some
    snark and adding mentions of `magit-debug-git-executable'.
---
 lisp/magit-git.el    | 74 ++++++++++++++++++++++++++++++++++++++++++++++------
 lisp/magit-mode.el   | 11 ++++----
 lisp/magit-status.el | 25 ++----------------
 lisp/magit.el        | 17 +-----------
 4 files changed, 75 insertions(+), 52 deletions(-)

diff --git a/lisp/magit-git.el b/lisp/magit-git.el
index a81c77bcdd..ea0cb1732d 100644
--- a/lisp/magit-git.el
+++ b/lisp/magit-git.el
@@ -579,14 +579,7 @@ call function WASHER with ARGS as its sole argument."
 (defconst magit--git-version-regexp
   "\\`git version \\([0-9]+\\(\\.[0-9]+\\)\\{1,2\\}\\)")
 
-(defvar magit--remotes-using-recent-git nil)
-
-(defun magit-git-version (&optional raw)
-  "Return the installed Git version."
-  (--when-let (let (magit-git-global-arguments)
-                (ignore-errors (substring (magit-git-string "version") 12)))
-    (if raw it (and (string-match "\\`\\([0-9]+\\(\\.[0-9]+\\)\\{1,2\\}\\)" it)
-                    (match-string 1 it)))))
+(defvar magit--host-git-version-cache nil)
 
 (defun magit-git-version>= (n)
   "Return t if `magit-git-version's value is greater than or equal to N."
@@ -596,6 +589,71 @@ call function WASHER with ARGS as its sole argument."
   "Return t if `magit-git-version's value is smaller than N."
   (version< (magit-git-version) n))
 
+(defun magit-git-version ()
+  "Return the Git version used for `default-directory'.
+Raise an error if Git cannot be found, if it exits with a
+non-zero status, or the output does not have the expected
+format."
+  (magit--with-refresh-cache default-directory
+    (let ((host (file-remote-p default-directory)))
+      (or (cdr (assoc host magit--host-git-version-cache))
+          (magit--with-temp-process-buffer
+            ;; Unset global arguments for ancient Git versions.
+            (let* ((magit-git-global-arguments nil)
+                   (status (magit-process-git t "version"))
+                   (output (buffer-string)))
+              (cond
+               ((not (zerop status))
+                (display-warning
+                 'magit
+                 (format "%S\n\nRunning \"%s --version\" failed with 
output:\n\n%s"
+                         (if host
+                             (format "Magit cannot find Git on host %S.\n
+Check the value of `magit-remote-git-executable' using
+`magit-debug-git-executable' and consult the info node
+`(tramp)Remote programs'." host)
+                           "Magit cannot find Git.\n
+Check the values of `magit-git-executable' and `exec-path'
+using `magit-debug-git-executable'.")
+                         (magit-git-executable)
+                         output)))
+               ((save-match-data
+                  (and (string-match magit--git-version-regexp output)
+                       (let ((version (match-string 1 output)))
+                         (push (cons host version)
+                               magit--host-git-version-cache)
+                         version))))
+               (t (error "Unexpected \"%s --version\" output: %S"
+                         (magit-git-executable)
+                         output)))))))))
+
+(defun magit-git-version-assert (&optional minimal who)
+  "Assert that the used Git version is greater than or equal to MINIMAL.
+If optional MINIMAL is nil, compare with `magit--minimal-git'
+instead.  Optional WHO if non-nil specifies what functionality
+needs at least MINIMAL, otherwise it defaults to \"Magit\"."
+  (when (magit-git-version< (or minimal magit--minimal-git))
+    (let* ((host (file-remote-p default-directory))
+           (msg (format-spec
+                 (cond (host "\
+%w requires Git %m or greater, but on %h the version is %m.
+
+If multiple Git versions are installed on the host, then the
+problem might be that TRAMP uses the wrong executable.
+
+Check the value of `magit-remote-git-executable' and consult
+the info node `(tramp)Remote programs'.\n")
+                       (t "\
+%w requires Git %m or greater, but you are using %v.
+
+If you have multiple Git versions installed, then check the
+values of `magit-remote-git-executable' and `exec-path'.\n"))
+                 `((?w . ,(or who "Magit"))
+                   (?m . ,(or minimal magit--minimal-git))
+                   (?v . ,(magit-git-version))
+                   (?h . ,host)))))
+      (display-warning 'magit msg :error))))
+
 (defun magit--safe-git-version ()
   "Return the Git version used for `default-directory' or an error message."
   (magit--with-temp-process-buffer
diff --git a/lisp/magit-mode.el b/lisp/magit-mode.el
index 12cf4bb3b8..4ec9c27f99 100644
--- a/lisp/magit-mode.el
+++ b/lisp/magit-mode.el
@@ -1425,7 +1425,7 @@ Unless specified, REPOSITORY is the current buffer's 
repository."
   "Zap caches for the current repository.
 
 Remove the repository's entry from `magit-repository-local-cache',
-remove the host's entry from `magit--remotes-using-recent-git', set
+remove the host's entry from `magit--host-git-version-cache', set
 `magit-section-visibility-cache' to nil for all Magit buffers of
 the repository and set `magit--libgit-available-p' to `unknown'.
 
@@ -1434,7 +1434,7 @@ mentioned caches completely."
   (interactive)
   (cond (all
          (setq magit-repository-local-cache nil)
-         (setq magit--remotes-using-recent-git nil)
+         (setq magit--host-git-version-cache nil)
          (dolist (buffer (buffer-list))
            (with-current-buffer buffer
              (when (derived-mode-p 'magit-mode)
@@ -1445,9 +1445,10 @@ mentioned caches completely."
                  (cl-delete default-directory
                             magit-repository-local-cache
                             :key #'car :test #'equal))
-           (setq magit--remotes-using-recent-git
-                 (delete (file-remote-p default-directory)
-                         magit--remotes-using-recent-git)))
+           (setq magit--host-git-version-cache
+                 (cl-delete (file-remote-p default-directory)
+                            magit--host-git-version-cache
+                            :key #'car :test #'equal)))
          (dolist (buffer (magit-mode-get-buffers))
            (with-current-buffer buffer
              (setq magit-section-visibility-cache nil)))))
diff --git a/lisp/magit-status.el b/lisp/magit-status.el
index 589207166d..2ea3c75e28 100644
--- a/lisp/magit-status.el
+++ b/lisp/magit-status.el
@@ -333,28 +333,6 @@ init file: (global-set-key (kbd \"C-x g\") 
'magit-status-quick)."
       (magit-display-buffer buffer)
     (call-interactively #'magit-status)))
 
-(defun magit--tramp-asserts (directory)
-  (when-let ((remote (file-remote-p directory)))
-    (unless (member remote magit--remotes-using-recent-git)
-      (if-let ((version (let ((default-directory directory))
-                          (magit-git-version))))
-          (if (magit--version>= version magit--minimal-git)
-              (push remote magit--remotes-using-recent-git)
-            (display-warning 'magit (format "\
-Magit requires Git >= %s, but on %s the version is %s.
-
-If multiple Git versions are installed on the host, then the
-problem might be that TRAMP uses the wrong executable.
-
-Check the value of `magit-remote-git-executable' and consult
-the info node `(tramp)Remote programs'.
-" magit--minimal-git remote version) :error))
-        (display-warning 'magit (format "\
-Magit cannot find Git on %s.
-
-Check the value of `magit-remote-git-executable' and consult
-the info node `(tramp)Remote programs'." remote) :error)))))
-
 ;;; Mode
 
 (defvar magit-status-mode-map
@@ -440,7 +418,8 @@ Type \\[magit-commit] to create a commit.
 (defun magit-status-setup-buffer (&optional directory)
   (unless directory
     (setq directory default-directory))
-  (magit--tramp-asserts directory)
+  (when (file-remote-p directory)
+    (magit-git-version-assert))
   (let* ((default-directory directory)
          (d (magit-diff--get-value 'magit-status-mode
                                    magit-status-use-buffer-arguments))
diff --git a/lisp/magit.el b/lisp/magit.el
index 5ee9a44907..f36f864fda 100644
--- a/lisp/magit.el
+++ b/lisp/magit.el
@@ -610,22 +610,7 @@ 
https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
 https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
   ;; Git isn't required while building Magit.
   (cl-eval-when (load eval)
-    (when (magit-git-version< magit--minimal-git)
-      (display-warning 'magit (format "\
-Magit requires Git >= %s, you are using %s.
-
-If this comes as a surprise to you, because you do actually have
-a newer version installed, then that probably means that the
-older version happens to appear earlier on the `$PATH'.  If you
-always start Emacs from a shell, then that can be fixed in the
-shell's init file.  If you start Emacs by clicking on an icon,
-or using some sort of application launcher, then you probably
-have to adjust the environment as seen by graphical interface.
-For X11 something like ~/.xinitrc should work.
-
-If you use Tramp to work inside remote Git repositories, then you
-have to make sure a suitable Git is used on the remote machines
-too.\n" magit--minimal-git (magit-git-version)) :error)))
+    (magit-git-version-assert))
   (when (version< emacs-version magit--minimal-emacs)
     (display-warning 'magit (format "\
 Magit requires Emacs >= %s, you are using %s.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]