O git pode alternar automaticamente entre espaços e tabulações?

196

Eu uso guias para indentação em meus programas python, mas gostaria de colaborar (usando o git) com pessoas que usam espaços.

Existe uma maneira de o git converter automaticamente entre espaços e guias (digamos, 4 espaços = 1 guia) ao pressionar / buscar? (semelhante à conversão CR / LF)

Olivier Verdier
fonte
33
O PEP8 é precisamente o meu problema. Todo mundo segue e eu estou preso com minhas abas. Por acaso, acho que um recuo = uma guia é a coisa certa a fazer (por que espaços? Por que 4 espaços? O PEP8 não explica isso ...). Enfim, com esse truque do git, posso usar as guias do meu computador e compartilhar meu código com todos os seguidores do PEP8 por aí.
Olivier Verdier
7
Oh! Eu uso o TextMate e posso converter entre espaços em guias. O problema é que, quando clico em tab, gosto que meu editor escreva ... tab. Portanto, se eu fizer check-out de um projeto python com espaços, inserirei todos os tipos de guias. Preciso converter manualmente em guias, mas, quando faço check-in, parece haver 1000 exclusões, 1000 adições e meus colaboradores não ficarão felizes. :-)
Olivier Verdier 23/02
6
O motivo pelo qual o PEP8 especifica espaços em vez de guias é por causa das regras de recuo de continuação. Existem duas maneiras de continuar uma linha longa demais dentro de um parênteses. Se você iniciar uma nova linha imediatamente após um parêntese, basta recuar uma. Se você colocar parte do conteúdo dos parênteses na primeira linha, será necessário continuar os parênteses na próxima linha no nível de indentação dos parênteses de abertura. Se você usar guias que não funcionam.
John Christopher Jones
2
@JohnChristopherJones para essa situação, pode-se usar guias para combinar o recuo com a linha anterior e espaços para corresponder a uma posição na linha anterior. Isso pode ser convertido em espaços facilmente. Infelizmente, o inverso não é verdadeiro, porque combina informações de indentação com informações de alinhamento.
Patrick Parker

Respostas:

195

Aqui está a solução completa:

No seu repositório, adicione um arquivo .git/info/attributesque contenha:

*.py  filter=tabspace

Linux / Unix

Agora execute os comandos:

git config --global filter.tabspace.smudge 'unexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'expand --tabs=4 --initial'

OS X

Primeiro instale o coreutils com o brew:

brew install coreutils

Agora execute os comandos:

git config --global filter.tabspace.smudge 'gunexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'gexpand --tabs=4 --initial'

Todos os sistemas

Agora você pode verificar todos os arquivos do seu projeto. Você pode fazer isso com:

git checkout HEAD -- **

e todos os arquivos python agora terão guias em vez de espaços.

Editar : alterou o comando de saída forçada. Você deve comprometer seu trabalho primeiro, é claro.

Olivier Verdier
fonte
1
O filtro limpo não está funcionando para mim. Quando eu adiciono o git. Eu recebo um erro dizendo "erro: expansão do filtro externo --tabs = 4 - falha inicial". Estou no Windows. Isso faz diferença?
Jeremy Hicks
2
@ Jeremy: expandir / expandir são comandos unix. Você precisará encontrar portas / equivalentes do Windows ou usar algo como Cygwin
Tim
1
Encontrei bast versão de trabalho sourceforge.net/projects/gnuwin32/files/coreutils/5.3.0
hazzik
3
@ Marc-André Bom ponto. Na verdade, eu uso as versões coreutils. (Instale homebrewe execute brew install coreutils).
Olivier Verdier
2
Parece que isso não funciona mais, os filtros não fazem nada para mim. Após o checkout, os arquivos ainda têm espaços. alguma atualização disso?
Philipp Ludwig
141

Sim, uma solução em potencial é usar um driver de filtro de atributo git (consulte também o livro GitPro ), para definir um mecanismo de manchas / limpeza.

texto alternativo

Dessa maneira:

  • sempre que você faz o checkout de alguns arquivos do seu repositório, os espaços podem ser convertidos em guias,
  • mas quando você faz check-in (e envia e envia), esses mesmos arquivos são armazenados de volta usando apenas espaços.

Você pode declarar esse driver de filtro (nomeado aqui ' tabspace') em .git/info/attributes(para um filtro aplicado a todos os arquivos no repositório Git), com o seguinte conteúdo:

*.py  filter=tabspace

Agora execute os comandos:

# local config for the current repo
git config filter.tabspace.smudge 'script_to_make_tabs'
git config filter.tabspace.clean 'script_to_make_spaces'

Consulte a resposta de Olivier para obter um exemplo concreto de um conjunto de instruções tão limpas / borradas.

VonC
fonte
Infelizmente, simplesmente não funciona. Eu segui todas as instruções, mas o git não aplica o fiter. :-( Quando faço o checkout, o filtro de manchas não é aplicado e, quando faço o check-in, nada acontece ... o git às vezes é tão frustrante ...
Olivier Verdier
@ Olivier: Estranho, nunca tive nenhum problema com isso, desde que limitasse cuidadosamente o escopo do filtro de atributos (a uma subárvore específica, apenas para um tipo específico de arquivo) para não desacelerar o checkout / check- em processo. Veja, por exemplo, stackoverflow.com/questions/62264/…
VonC
Obrigado! Agora funciona. Veja a solução completa: stackoverflow.com/questions/2316677/…
Olivier Verdier
@Vonc: talvez um deve remover a --globalbandeira, já que isso implicaria, você envia espaços para cada projeto de colaboração ...
Willem Van Onsem
@CommuSoft apenas para os projetos que têm o direito .gitattributes. Mas sim, é mais fácil entender se a configuração é mantida local no repositório. Eu editei a resposta.
VonC
39

Informações muito úteis para todos que usam o GitHub (ou outro serviço similar)

~/.gitconfig

[filter "tabspace"]
    smudge = unexpand --tabs=4 --first-only
    clean = expand --tabs=4 --initial
[filter "tabspace2"]
    smudge = unexpand --tabs=2 --first-only
    clean = expand --tabs=2 --initial

Então eu tenho dois arquivos: attributes

*.js  filter=tabspace
*.html  filter=tabspace
*.css  filter=tabspace
*.json  filter=tabspace

e attributes2

*.js  filter=tabspace2
*.html  filter=tabspace2
*.css  filter=tabspace2
*.json  filter=tabspace2

Trabalhando em projetos pessoais

mkdir project
cd project
git init
cp ~/path/to/attributes .git/info/

Dessa forma, quando você finalmente empurra seu trabalho no github, ele não parecerá bobo na visualização de código com 8 space tabs o comportamento padrão em todos os navegadores.

Contribuindo para outros projetos

mkdir project
cd project
git init
cp ~/path/to/attributes2 .git/info/attributes
git remote add origin [email protected]:some/repo.git
git pull origin branch

Dessa forma, você pode trabalhar com guias normais em 2 space indented projetos.

É claro que você pode escrever uma solução semelhante para a conversão a partir da 4 space to 2 spacequal é o caso, se quiser contribuir com projetos publicados por mim e tender a usar 2 espaços durante o desenvolvimento.

simo
fonte
2
Relacionado: Armazenando a configuração do git como parte do repositório ; Observe também que você pode usar (e cometer) um .gitattributesarquivo em seu repo
Tobias KIENZLER
1

Se você estiver no Windows, terá algumas etapas extras para que a solução do @Olivier Verdier funcione.

  1. Baixar CoreUtils para Windows
  2. Após a instalação, coloque o local de instalação no seu PATH ( Como adicionar uma variável de caminho )
  3. Renomeei o arquivo expand.exe para gexpand.exe, pois já existe um utilitário de expansão do Windows.
odyth
fonte