Meta git (mgit)
Meta git (mgit) is a wrapper around magit, which is a wrapper around git.
If the output looks familiar, it's because it's the output from command git status -v. For the discerning eye, it uses the font-lock defaults from diff mode (notice the highlight on ;;). diff-mode uses repeated diff commands to highlight the refinements. Use diff-mode or diff-refine-hunk if you must have the eye-candy.
Motivation
Magit is a handy tool for working with git repository in GNU Emacs. However, if you work with a large enough repository, you'll hit a performance road-block. Here's an attempt to deconstruct the problem and find a solution.
Magit provides an information rich dashboard for git status. However, this comes with multiple calls to git command. If you run M-x magit-toggle-verbose-refresh and then run magit-status, you'll see the following output:
magit-insert-error-header 2.031e-06
magit-insert-diff-filter-header 3.0799e-05
magit-insert-head-branch-header 0.004475604
magit-insert-upstream-branch-header 0.005282276
magit-insert-push-branch-header 3.5114e-05
magit-insert-tags-header 0.008421254
magit-insert-status-headers 0.021357499 !
magit-insert-merge-log 0.001540241
magit-insert-rebase-sequence 0.000193708
magit-insert-am-sequence 0.000190186
magit-insert-sequencer-sequence 0.000405629
magit-insert-bisect-output 0.000159796
magit-insert-bisect-rest 4.9848e-05
magit-insert-bisect-log 7.4688e-05
magit-insert-untracked-files 4.554816041 !!
magit-insert-unstaged-changes 3.27816181 !!
magit-insert-staged-changes 0.033723897 !!
magit-insert-stashes 0.009674576
magit-insert-unpushed-to-pushremote 4.0493e-05
magit-insert-unpushed-to-upstream-or-recent 0.014408128 !
magit-insert-unpulled-from-pushremote 3.31e-06
magit-insert-unpulled-from-upstream 0.004328423
Refreshing buffer ‘magit: src<anand>’...done (13.270s)
In comparison, the output from git status -v provides pertinent information (see screenshot) in around 3-4s.
Lessons learnt
- Most git commands are fast except the ones which operate on tree level information. However, magit operations seem slower because of the refresh problem - it needs to refresh the complete dashboard.
- Performance bottleneck is not the number of files edited but the size of the repository (number of files in the repository).
Code (Work In Progress)
https://gitlab.com/atamariya/emacs/-/blob/mgit/lisp/vc/mgit.el
Patches for Magit
(setq orig (magit-decode-git-path orig)))
- (setq file (magit-decode-git-path file))
- (setq header (nreverse header))
- ;; KLUDGE `git-log' ignores `--no-prefix' when `-L' is used.
- (when (and (derived-mode-p 'magit-log-mode)
- (seq-some (lambda (arg) (string-prefix-p "-L" arg))
- magit-buffer-log-args))
+ (when file
+ (setq file (magit-decode-git-path file)))
+ ;; KLUDGE `git-diff' ignores `--no-prefix' for new files and renames at
+ ;; least. And `git-log' ignores `--no-prefix' when `-L' is used.
+ (when (or (and file (string-prefix-p "b/" file))
+ (and orig (string-prefix-p "a/" orig))
+ (and (derived-mode-p 'magit-log-mode)
+ (--first (string-prefix-p "-L" it)
+ magit-buffer-log-args)))
+ (when file
+ (setq file (substring file 2)))
(file orig status modes rename header &optional long-status)
(magit-insert-section section
- (file file (or (equal status "deleted")
- (derived-mode-p 'magit-status-mode)))
+ (file (or file orig)
+ (or (equal status "deleted")
+ (derived-mode-p 'magit-status-mode)))
(insert (propertize (format "%-10s %s" status
- (if (or (not orig) (equal orig file))
- file
- (format "%s -> %s" orig file)))
+ (if (and orig file)
+ (if (equal orig file)
+ file
+ (format "%s -> %s" orig file))
+ (or orig file)))
'font-lock-face 'magit-diff-file-heading))
Comments
Post a Comment