Magit extremamente lento no Windows. Como otimizar?

15

Sou forçado a usar o Windows 10 para um projeto. Sim, eu prefiro usar o GNU / Linux. Para manter minha sanidade mental, tentei considerar o Windows como um gerenciador de inicialização para o Emacs :)

Infelizmente, o Magit (uma das minhas partes favoritas do Emacs, que também compensa a falta de uma boa linha de comando no Windows) é insuportavelmente lento. Eu tenho um SSD, 16 GB de RAM e um i7 quad-core, mas leva oito segundos para executar magit-statusem um pequeno repositório. Então, quando eu quero realizar outra alteração, leva cerca de 5 segundos por arquivo .

Aqui está o que eu tentei:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • Adicionando o projeto inteiro à lista de exclusão do Windows Defender (meu único AV)
  • Definindo magit-git-executablecomo o msysgit regular que baixei ( https://git-for-windows.github.io/ ). Eu verifiquei e git statusaqui leva <1 segundo. Eu sei que magit-statusfaz muito mais, mas isso é demais.

Alguém pode sugerir maneiras de tornar isso mais rápido? Não consigo imaginar alguém usando o Magit no Windows assim.

Foi sugerido que esta pergunta é uma duplicata, mas eles perguntaram:

Estou lutando para entender por que o Emacs tem um tempo de inicialização visivelmente menor no Ubuntu do que no Windows. Alguém sabe a resposta?

Sei pelo menos algumas razões pelas quais o Emacs, Git e Magit são mais lentos no Windows. Estou perguntando como otimizar o Magit para fazer menos coisas, ou armazenar em cache resultados, ou algo assim, mesmo que seja à custa da funcionalidade.

Hut8
fonte
git-statusdemora <1 segundo? Deve ser essencialmente instantâneo. Existe algum atraso perceptível?
precisa saber é o seguinte
Você tem os mesmos problemas ao executar gitcomandos equivalentes na linha de comando?
elethan
Eu acho que a escolha padrão do magit magit-git-executableprovavelmente será um pouco mais rápida (as que estão cmde binsão realmente wrappers, se executable-findretorna um deles, o magit tentará definir magit-git-executableo git "real"). Porém, 8 segundos para um pequeno repositório parecem estar errados, demora ~ 0,8s para o repositório do magit aqui (Windows 8).
npostavs
1
Além disso, para um tempo mais preciso, você pode definir magit-refresh-verbosecomo t.
Nanny

Respostas:

11

Na verdade, eu fiz bastante pesquisa sobre isso e, fundamentalmente, o problema é que o git for windows é uma merda

Este é o bug do upstream: https://github.com/git-for-windows/git/issues/596 e requer que alguém reescreva os scripts de shell em C para que não haja mais bifurcação de comandos. Para mim, é o rebote interativo que é o verdadeiro assassino (eu posso iniciar um rebote interativo, fazer chá, voltar, ler algumas notícias, beber o chá e, talvez , terminar. É muito pior do que muitas pessoas acho que sim), mas as chamadas gerais de status também são suficientes para interromper o andamento do trabalho.

Uma alternativa pode ser a atualização do jGit para suportar os comandos que o magit usa e, em seguida, executá-lo no nailgun para reduzir o tempo de inicialização da JVM. Iniciei um tópico para discutir isso: http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

Você pode ler /programming/4485059 para obter algumas acelerações em potencial, mas, honestamente, quase não as notará.

Algo que você pode fazer no magit é seguir o conselho do autor na criação de um mínimo magit-statusapenas para a preparação

;; WORKAROUND https://github.com/magit/magit/issues/2395
(define-derived-mode magit-staging-mode magit-status-mode "Magit staging"
  "Mode for showing staged and unstaged changes."
  :group 'magit-status)
(defun magit-staging-refresh-buffer ()
  (magit-insert-section (status)
    (magit-insert-untracked-files)
    (magit-insert-unstaged-changes)
    (magit-insert-staged-changes)))
(defun magit-staging ()
  (interactive)
  (magit-mode-setup #'magit-staging-mode))

Então, você conhece algum desenvolvedor C ou Java experiente que possa ajudar com uma das soluções para corrigir o git ou o jGit?

fommil
fonte
Não tenho tanta certeza de que o problema seja shell scripts vs. C, porque também magit-statusleva muito tempo, e não acho que o status use muitos dos scripts shell.
Nanny
1
E obrigado por esse magit-statuscódigo "mínimo" , ele parece me ajudar um pouco (reduz meu magit-refreshtempo para 2-3 segundos).
Nanny
É exatamente isso que eu quero. Obrigado!
precisa saber é o seguinte
1
Sim, magit-stagingleva alguns segundos para mim também. O suficiente para interromper meu pensamento, mas não o suficiente para destruir o meu dia.
fommil 14/01
2
a razão pela qual magit-statusé lento é porque chama gittalvez 10 ou 20 vezes. Iniciar novos processos no Windows é extremamente lento em comparação com as plataformas GNU. Os scripts shell são um caso extremo deste (porque praticamente todos os declaração é um novo processo)
fommil
2

Tendo analisado recentemente a lista de call-processchamadas de magit-statusoutro motivo, ocorreu-me que algumas delas podem ser armazenadas em cache. Com o seguinte conselho magit-statussobre o repo do Magit, vai de 1,9 a 1,3 segundos (minha medida anterior de 0,8s mencionada nos comentários foi para um computador diferente (mais rápido)). Se você já está usando magit-staginga outra resposta, provavelmente não vai ajudar muito: vi uma redução de 0,16 a 0,12 segundos (mas isso é pouco maior que o ruído de medição).

AVISO: Isso não se encarrega de atualizar o cache; portanto, as coisas podem dar errado (especialmente se você estiver mexendo na sua configuração do git).

(defvar-local magit-git--git-dir-cache nil)
(defvar-local magit-git--toplevel-cache nil)
(defvar-local magit-git--cdup-cache nil)

(defun memoize-rev-parse (fun &rest args)
  (pcase (car args)
    ("--git-dir"
     (unless magit-git--git-dir-cache
       (setq magit-git--git-dir-cache (apply fun args)))
     magit-git--git-dir-cache)
    ("--show-toplevel"
     (unless magit-git--toplevel-cache
       (setq magit-git--toplevel-cache (apply fun args)))
     magit-git--toplevel-cache)
    ("--show-cdup"
     (let ((cdup (assoc default-directory magit-git--cdup-cache)))
       (unless cdup
         (setq cdup (cons default-directory (apply fun args)))
         (push cdup magit-git--cdup-cache))
       (cdr cdup)))
    (_ (apply fun args))))

(advice-add 'magit-rev-parse-safe :around #'memoize-rev-parse)

(defvar-local magit-git--config-cache (make-hash-table :test 'equal))

(defun memoize-git-config (fun &rest keys)
  (let ((val (gethash keys magit-git--config-cache :nil)))
    (when (eq val :nil)
      (setq val (puthash keys (apply fun keys) magit-git--config-cache)))
    val))

(advice-add 'magit-get :around #'memoize-git-config)
(advice-add 'magit-get-boolean :around #'memoize-git-config)
npostavs
fonte
por que você não usa o pacote melpa.org/#/memoize ?
fommil
1
@omomil: eu precisava memorizar a análise de revisão por buffer para alguns argumentos. Não consegui ver uma maneira de fazê-lo depois de uma análise superficial do pacote memoize. Também diz que não pode lidar com memorização nil.
npostavs