branch: elpa/git-commit commit 9b48dd7e3618ac3736f66ef964ae5e1fedd54f98 Author: Kyle Meyer <k...@kyleam.com> Commit: Kyle Meyer <k...@kyleam.com>
Prefer 'git log --no-walk' to 'git show --no-patch' In some scenarios, particularly some merge commits, showing a commit with 'git log --no-walk' is much faster than 'git-show --no-patch'. This is perhaps because git-show is still doing work related to preparing the patch despite not showing it. As an example, here are hyperfine timings on a recent git.git merge commit (83937e9592), with the master branch (currently ab336e8f1c) checked out: | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |-----------------------------+-------------+----------+----------+--------------| | show --no-patch --format=%h | 117.6 ± 2.5 | 115.2 | 125.9 | 34.92 ± 2.06 | | log -n1 --format=%h | 3.6 ± 0.2 | 3.4 | 6.6 | 1.08 ± 0.08 | | log --no-walk --format=%h | 3.4 ± 0.2 | 3.1 | 7.0 | 1.00 | Some notes: * I haven't observed this sort of difference for non-merge commits, and the difference seems to vary quite a bit across merge commits. I tried multiple merge commits in the Magit repo, and the show and log variants were pretty much the same. Perhaps the distance of the fork point contributes to the slow down. * hyperfine warns that the two log commands are under 5ms and might be unreliable, but the point is just that the show variant is much slower in this case. Replace all 'git show --no-patch' calls in the code base with the 'git log --no-walk' equivalent. Closes #4702. --- lisp/magit-git.el | 8 ++++++-- lisp/magit-repos.el | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lisp/magit-git.el b/lisp/magit-git.el index 76f4c406c4..297a63ea22 100644 --- a/lisp/magit-git.el +++ b/lisp/magit-git.el @@ -2135,7 +2135,9 @@ Return a list of two integers: (A>B B>A)." (car (split-string (buffer-string)))))) (defun magit-rev-format (format &optional rev args) - (let ((str (magit-git-string "show" "--no-patch" + ;; Prefer `git log --no-walk' to `git show --no-patch' because it + ;; performs better in some scenarios. + (let ((str (magit-git-string "log" "--no-walk" (concat "--format=" format) args (if rev (magit--rev-dereference rev) "HEAD") "--"))) @@ -2143,7 +2145,9 @@ Return a list of two integers: (A>B B>A)." str))) (defun magit-rev-insert-format (format &optional rev args) - (magit-git-insert "show" "--no-patch" + ;; Prefer `git log --no-walk' to `git show --no-patch' because it + ;; performs better in some scenarios. + (magit-git-insert "log" "--no-walk" (concat "--format=" format) args (if rev (magit--rev-dereference rev) "HEAD") "--")) diff --git a/lisp/magit-repos.el b/lisp/magit-repos.el index 9dd924fcc2..e7f63af2ae 100644 --- a/lisp/magit-repos.el +++ b/lisp/magit-repos.el @@ -373,7 +373,7 @@ Usually this is just its basename." "Insert a description of the repository's `HEAD' revision." (and-let* ((v (or (magit-git-string "describe" "--tags" "--dirty") ;; If there are no tags, use the date in MELPA format. - (magit-git-string "show" "--no-patch" "--format=%cd-g%h" + (magit-rev-format "%cd-g%h" nil "--date=format:%Y%m%d.%H%M")))) (save-match-data (when (string-match magit-repolist-column-version-regexp v)