A maneira mais fácil de fazer o downgrade de um pacote instalado via MELPA

22

Às vezes, as atualizações de pacotes do MELPA podem quebrar parte do emacs e, quando isso acontece, eu gostaria de poder voltar a usar uma versão mais antiga do pacote.

No momento, eu posso fazer isso de duas maneiras:

  • Eu configurei o emacs para excluir arquivos movendo-os para o lixo e, quando atualizo um pacote, a versão mais antiga é lixeira. Posso recuperar a versão mais antiga e substituir a ~/.emacs.d/elpa.

  • Vá para o repositório github do pacote que quebrou a funcionalidade, busque uma versão mais antiga do pacote, substitua a ~/.emacs.d/elpado gitub e recompile os arquivos.

Ambas as formas envolvem muito trabalho manual movendo as coisas. Existe uma maneira mais fácil (de preferência automática) de fazer o downgrade dos pacotes instalados no MELPA?

Chakravarthy Raghunandan
fonte
4
Você só pode instalar a versão mais recente através do ELPA / package.el, Melpa e Melpa-stable, nem mantém versões antigas dos pacotes. Para instalar um pacote manualmente, 1) faça o download do código-fonte 2) M-x package-install-file. Também existem outras maneiras de gerenciar pacotes além do ELPA / package.el, como el-get e quelpa , eles parecem poder ser usados ​​sem o ELPA, talvez eles possam fazer o que você deseja.
xuchunyang
2
Se você não obtiver uma resposta simples e viável para esta pergunta, considere enviar uma solicitação de aprimoramento ao Emacs: M-x report-emacs-bug(também é para solicitações de aprimoramento).
Drew

Respostas:

9

Quando você atualiza seus pacotes pela M-x list-packagesinterface, após a instalação bem-sucedida do pacote, você será perguntado se deseja remover o pacote antigo. Não os exclua para que eles permaneçam no lugar e, em seguida, você poderá remover o pacote mais recente por essa interface.

Minha lista de pacotes atual mostra 4 versões do magit instaladas na minha árvore de diretórios ~ / .emacs.d / elpa /.

  magit              20160827.1549 obsolete              A Git porcelain inside Emacs
  magit              20160907.945  obsolete              A Git porcelain inside Emacs
  magit              20161001.1454 obsolete              A Git porcelain inside Emacs
  magit              20161123.617  installed             A Git porcelain inside Emacs

Você pode limpar as versões antigas posteriormente com a tecla ~(marca do menu pacote obsoleta para exclusão) para marcar todos os pacotes obsoletos. Para excluir uma determinada versão antiga, vá para sua linha e pressione dpara marcá-las para exclusão. Depois de marcar os pacotes, você usaria xpara executar as ações como de costume.

No Emacs 25, a marcação de todos os pacotes para a Ufuncionalidade pgrade define automaticamente todos os pacotes antigos para exclusão e não solicita confirmação após a instalação. Você precisa procurar linhas que começam com um "D" maiúsculo, que pode ser desmarcado (melhor com a macro a seguir)

Digite a tecla ou o acorde à esquerda do traço nas seguintes linhas.

<F3>  - start macro recording
C-s   - isearch-forward
C-q   - quoted-insert
C-j   - linefeed character
D     - the mark at the start of the line
<Ret> - stops the isearch on the line with the "D"
u     - unmark the package for deletion
<F4>  - stops macro recording - the first package is now unmarked
<F4>  - executes the macro for the next upgraded package

Se não houver mais correspondências para a pesquisa, a macro tocará a campainha e será interrompida. Assim, você poderá C-u 0 <F4>desmarcar todos os pacotes marcados para exclusão. Depois disso, você pode xexecutar as instalações.

A função que declarei ser alterada no meu comentário deve ser alterada de uma maneira que ainda não consigo entender, pois é importante que o último bloco (cond) seja bem-sucedido para não fazer loop infinito.

p_wiersig
fonte
Oh hey, ele não pede confirmação para excluir no meu emacs. Apenas apaga o pacote antigo: / acho que costumava perguntar no emacs 24? não me lembro
Chakravarthy Raghunandan
de fato. O Emacs 24 solicita, 25 parece marcar o antigo para exclusão e isso será acionado na execução das marcas. Você pode marcar os pacotes para instalação manualmente ou desmarcar as exclusões ou alterar as (t (package-menu-mark-delete))linhas package-menu--mark-upgrades-1para que a primeira linha seja um teste para uma variável de configuração ou algo que retorne nilquando você não deseja excluir pacotes antigos imediatamente
p_wiersig
Você pode adicionar as linhas relevantes para editar na package.elresposta original, para que eu possa aceitar a resposta? Obrigado
Chakravarthy Raghunandan
Certo. Percebi que não posso criar a função para fazer o que quero, então expliquei como desmarcar tudo por meio de uma macro.
p_wiersig
7

A "opção nuclear", por assim dizer, seria abandonar package.elcompletamente e usar o gerenciador de pacotes que escrevi straight.el,. A vantagem seria que straight.elinstala pacotes clonando seus repositórios Git, tornando fácil o uso da versão que você desejar. Além disso, straight.elfornece funcionalidade para lidar com arquivos de bloqueio de revisão, que permitem registrar o estado exato da sua configuração de gerenciamento de pacotes nos mínimos detalhes. Então, em caso de emergência, você pode simplesmente reverter todos os pacotes para suas versões em bom estado.

Geralmente, esses tipos de operações são impossíveis package.ele sempre serão impossíveis devido ao design geral.

Em resposta ao seu desejo de evitar fazer um commit toda vez que você atualizar seus pacotes, isso não é necessário straight.el. Eu recomendaria escrever uma versão lockfile e confirmar isso toda vez que você atualizar seus pacotes, pois isso torna impossível entrar em um estado em que sua configuração do Emacs é interrompida após uma atualização e você não sabe como reverter. Mas você não precisa fazer isso, se gosta de viver a vida no limite.

Radon Rosborough
fonte
4

Eu acho uma maneira fácil de fazer o downgrade: gerenciar seu próprio arquivo melpa.

  1. Clone melpa repo.
  2. Siga a página wiki de arquivo melpa personalizada do melpa para remover todas as receitas.
  3. Encontre o commit do pacote para o qual deseja baixar a nota e crie uma nova receita com esse commit para o pacote. (consulte o leia-me de melpa sobre como especificar o commit)
  4. Execute makepara criar o pacote desclassificado
  5. Adicione seu próprio arquivo melpa, que pode ser um diretório local, à package-archiveslista.
  6. Instale o pacote desatualizado usando o menu do pacote. Ou você pode usar package-pinned-packagespara restringir o arquivo de onde o pacote deve ser baixado.
chunfengd
fonte
3

Muitas pessoas optam por não comprometer pacotes ELPA para controle de versão, mas este é um exemplo de por que acredito que você deve fazê-lo.

Reverter qualquer coisa é trivial se tudo estiver comprometido.

Dependendo do estado dos pacotes ELPA upstream, há um risco.

phils
fonte
Mas isso significaria que eu teria que me lembrar de confirmar toda vez que atualizar pacotes. Não é isso que eu quero. OU existe uma maneira de eu fazer o emacs encenar e confirmar automaticamente os pacotes atualizados sempre que eu fizer uma atualização de pacote?
Chakravarthy Raghunandan
1
Não entendo por que você não deseja que alterações na sua configuração sejam decisões intencionais. Em relação às confirmações automáticas, tenho certeza de que poderia ser automatizado, mas não tenho uma solução para isso. A busca por essas soluções pode fornecer produtividade, no entanto.
phils