O vimdiff para git diffs pode ser iniciado na guia do processo atual?

Jan 20 2021

Digamos que eu tenha um buffer de arquivo aberto e uma :terminaldivisão aberta em uma página de guia. Eu gostaria de criar uma nova guia onde eu corro, vimdiffmas mostre meu git diff. Estou tentando git difftool HEAD~1aparecer no meu processo atual do vim, apenas em outra página da guia.

Isso é possível no Vim 8 sem plug-ins?

Eu meio que tenho essa ilusão quando faço isso :tab terminale depois corro git difftool HEAD~1. No entanto, isso inicia um subprocesso vim e eu gostaria de evitar isso.

Mais ou menos como esta pergunta: Como entro no modo vimdiff, dado que duas divisões já estão abertas? mas para diffs git.

Respostas

2 NikolasTapia Jan 20 2021 at 17:03

Embora isso seja certamente factível no vanilla vim, sugiro que você dê uma olhada no excelente vim-fugitiveplugin do tpope . Em seguida, você simplesmente precisa fazer :tab Gdiffpara obter o que deseja.

Se você realmente não deseja instalar nenhum plug-in, o seguinte pode funcionar assumindo que o arquivo atual está no buffer no. 1:

  1. :tabnew | r! git show HEAD^:$(git rev-parse --show-prefix)#1:t
  2. Na guia recém-aberta, :vert sb 1 | windo diffthis

Explicação

  1. primeiro abre uma nova guia com tabnewe carrega o conteúdo da HEAD^versão do arquivo no buffer 1 nele.
  2. abre uma divisão vertical contendo o buffer 1 com vert sb 1, em seguida, envia :diffthispara todos os buffers na guia para entrar no modo diff.

Editar

O OP pediu mais explicações sobre a etapa 1. git showprecisa de uma entrada do formulário <rev>:<path>em <path>que deve ser relativo à raiz da árvore de trabalho. Por exemplo, se o caminho absoluto do arquivo no buffer 1 é /a/b/foo.extaquele que bcontém sua .gitpasta (ou seja, bé a raiz do seu repo), git showpara funcionar corretamente, você teria que invocá-lo com HEAD^:b/foo.e. Usar um /a/b/foo.extou outro foo.extnão funcionará. Então, eu costumava git rev-parse --show-prefixobter o caminho da pasta atual em relação à raiz git (que seria b/) neste exemplo.

Em seguida, usei a vimexpansão de caminho para acrescentar o nome do arquivo (isto é foo.ext). #1diz vimpara buscar o caminho de qualquer arquivo carregado no buffer 1, e :textrai a "cauda", que é tudo após o último /no caminho retornado por #1. Em alguns casos #1e #1:tsão iguais, mas nem sempre é o caso. Por exemplo, se você executasse, vim b/foo.extentão #1retornaria em b/foo.extvez de apenas foo.ext. Confira :help expandpara mais informações.

Claro, você poderia simplesmente inserir o caminho manualmente, como em :tabnew | r! git show HEAD^:b/foo.ext, e ele funcionaria. Mas a versão acima é programável ou você pode atribuir a um mapa.