Como forçar o git a usar LF em vez de CR + LF no Windows?

335

Eu quero forçar o git a fazer checkout de arquivos no Windows usando apenas LFnão CR+LF. Verifiquei as duas opções de configuração, mas não consegui encontrar a combinação certa de configurações.

Quero que ele converta todos os arquivos LFe os mantenha LFnos arquivos.

Observação: usei, autocrlf = inputmas isso apenas repara os arquivos quando você os confirma. Eu quero forçá-lo a fazê-los usar LF.

Provavelmente eu não estava tão claro: o repositório já está usando, LFmas os arquivos retirados usando o msysgit estão usando CR+LFe eu quero forçar o msysgit a obtê-los com LF: forçar finais de linha do Unix .

>git config --list | grep crlf
core.autocrlf=input
sorin
fonte
2
autocrlf=inputé a opção correta. Obviamente, ele não protege você de arquivos que realmente possuem cr+lfno repositório ou a criação de arquivos com cr+lfoutra ferramenta antes de adicioná-los ao git. Para quais problemas você está enfrentando isso não funciona?
CB Bailey
2
Os arquivos no repositório já estão usando apenas, LFmas quando os obtenho no Windows, o msysgit os converte em CR+LF.
sorin
Deve haver algo com sua configuração; Acabei de testar isso na minha instalação do msysgit. Com autocrlfdefinido como input, git está deixando os lffeeds de linha em paz. Você pode postar a saída de git config?
CB Bailey
11
Nesse caso, sugiro que você registre um bug; de preferência apontando para um repositório de teste que exiba seu problema e incluindo etapas para reproduzir, pois o comportamento que você está vendo está definitivamente errado (mas não posso reproduzi-lo).
CB Bailey
11
Uma pequena dica é também garantir que você esteja executando os comandos git no 'git' que pensa estar. Por exemplo, você pode ter o git instalado no Windows e o git instalado no cygwin, portanto, certifique-se de ter definido a configuração correta do git.
Lfred 26/03/2015

Respostas:

106

O OP acrescentou em sua pergunta:

os arquivos retirados usando o msysgit estão usando CR+LFe quero forçar o msysgit a obtê-los comLF

Um primeiro passo simples ainda estaria em um .gitattributesarquivo:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(conforme observado nos comentários do neto , referindo-se à .gitattributesconversão de fim de linha ), para evitar qualquer CRLFconversão para arquivos com a correta eol.

E sempre recomendei git config --global core.autocrlf false desativar qualquer conversão (que se aplicaria a todos os arquivos com versão)

Consulte Práticas recomendadas para configuração git de plataforma cruzada?

Desde o Git 2.16 (primeiro trimestre de 2018), você pode git add --renormalize .aplicar essas .gitattributesconfigurações imediatamente.


Mas um segundo passo mais poderoso envolve um driver de filtro gitattribute e adiciona um passo borrado

driver de filtro

Sempre que você atualizasse sua árvore de trabalho, um script poderia, apenas para os arquivos especificados em .gitattributes, forçar a LF eole qualquer outra opção de formatação que você deseja impor.
Se o clearscript " " não fizer nada, você (depois do commit) transformará seus arquivos, aplicando exatamente o formato que você precisa seguir.

VonC
fonte
Uma pergunta: * .txt refere-se a todos os arquivos com extensão .txt ou a todos os arquivos de texto (não binários)? Não consigo fazer uma lista com todos os tipos de extensão de arquivo que terei no projeto.
sorin
11
@ Sorin: todos os arquivos com .txtextensão. É preferível estabelecer isso primeiro e testá-lo em um grupo específico, antes de generalizar para *, e adicionar uma regra negativa !*.xyz ...para excluir alguns poucos arquivos dessa regra.
VonC 26/03/10
11
Até agora, as .gitattributeslinhas devem ler: *.txt text eol=lfconforme git-scm.com/docs/gitattributes
neto
@grandchild Obrigado. Incluímos seu comentário na resposta para obter mais visibilidade.
VonC 9/01
Acho que depois de adicionarmos .gitattributestemos que fazergit add --renormalize .
shuva
460

A maneira correta de obter terminações LF no Windows é primeiro definir core.autocrlfcomo false:

git config --global core.autocrlf false

Você precisa fazer isso se estiver usando o msysgit, porque ele o define truenas configurações do sistema.

Agora o git não fará nenhuma linha finalizando a normalização. Se você deseja que os arquivos com check-in sejam normalizados, faça o seguinte: Configure text=autoem .gitattributespara todos os arquivos:

* text=auto

E defina core.eolpara lf:

git config --global core.eol lf

Agora você também pode alternar repositórios únicos para crlf (no diretório de trabalho!) Executando

git config core.eol crlf

Depois de fazer a configuração, você pode querer que o git normalize todos os arquivos no repositório . Para fazer isso, vá para a raiz do seu repositório e execute estes comandos:

git rm --cached -rf .
git diff --cached --name-only -z | xargs -n 50 -0 git add -f

Se agora você deseja que o git também normalize os arquivos em seu diretório de trabalho , execute estes comandos:

git ls-files -z | xargs -0 rm
git checkout .
Chronial
fonte
3
Estou ficando pathspec fatal '' não encontrou nenhum arquivos, logo depoisgit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai
3
qual é a saída git diff --cached --name-only?
Cronial
11
Vale ressaltar que você pode definir essa configuração enquanto clona o repositório em questão, por exemplo git clone --config core.autocrlf=false <repo path>.
Chris Long
240

Volto a essa resposta com bastante frequência, embora nenhuma delas seja certa para mim. Dito isto, a resposta certa para mim é uma mistura dos outros.

O que eu acho que funciona é o seguinte:

 git config --global core.eol lf
 git config --global core.autocrlf input

Para repos que foram retirados após a definição dessas configurações globais, tudo será verificado como o que estiver no repositório - espero LF( \n). Qualquer CRLFserá convertido para apenas LFno check-in.

Com um repo existente que você já efetuou check-out - que possui as terminações de linha corretas no repo, mas não sua cópia de trabalho - você pode executar os seguintes comandos para corrigi-lo:

git rm -rf --cached .
git reset --hard HEAD

Isso excluirá ( rm) recursivamente ( r) sem aviso ( -f), todos os arquivos, exceto aqueles que você editou ( --cached), do diretório atual ( .). Em resetseguida, todos esses arquivos retornam a um estado em que eles têm suas terminações de linha verdadeiras (correspondendo ao que está no repositório).

Se você precisar corrigir as terminações de linha de arquivos em um repositório, recomendo pegar um editor que permita fazer isso em massa, como IntelliJ ou Sublime Text, mas tenho certeza de que qualquer um bom provavelmente suportará isso.

Ben Liyanage
fonte
11
Temos um único repositório com subdiretórios que requerem tratamento de final de linha diferente. Portanto, definir uma opção global não funciona para isso. Nem no único repositório. Como você aplica essas mesmas configurações nos atributos .gitat?
RobG
Notepad++também mostra o final da linha do arquivo aberto atualmente no canto inferior direito. Um clique direito nesse campo permitirá alterar as terminações da linha.
winklerrr
11
A core.autocrlf inputopção substitui a core.eolconfiguração, portanto, a configuração de ambos é redundante. (Veja git-scm.com/docs/git-config )
Andrew Marshall
11
Obrigado, com sua ajuda, conquistei o fiapo e o Linux. E agora pode fazer o check-in de arquivos.
GC_ 04/04
57

Contexto

Se vocês

  1. deseja forçar todos os usuários a terem terminações de linha LF para arquivos de texto e
  2. você não pode garantir que todos os usuários alterem sua configuração do git,

você pode fazer isso começando com o git 2.10. 2.10 ou posterior é necessário, porque 2.10 corrigiu o comportamento de text = auto juntamente com eol = lf . Fonte .

Solução

Coloque um .gitattributesarquivo na raiz do seu repositório git com o seguinte conteúdo:

* text=auto eol=lf

Comprometa-o.

Ajustes opcionais

Você também pode adicionar um .editorconfigna raiz do seu repositório para garantir que as ferramentas modernas criem novos arquivos com as terminações de linha desejadas.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
koppor
fonte
3
Esta foi a melhor solução para mim. Também combinei isso com o editorconfig.org para que, ao escrever no Intellij, escrevesse LOL EOLs .
Jazzepi
Esta é de longe a melhor solução. Não há necessidade de executar manualmente nenhum comando de configuração!
Cameron Tacklind
26

core.autocrlf=inputé a configuração certa para o que você deseja, mas pode ser necessário fazer um git update-index --refreshe / ou um git reset --hardpara que a alteração seja efetivada.

Com core.autocrlfdefinido como input, o git não aplicará a conversão de nova linha no check-out (portanto, se você tiver LF no repositório, receberá LF), mas garantirá que, no caso de você estragar e introduzir alguns CRLFs no trabalho copiar de alguma forma, eles não vão entrar no repositório.

kusma
fonte
19
Os comandos devem ser git rm --cached -r. && git reset --hard
koppor
0

Você pode encontrar a solução para esse problema em: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Descrição simplificada de como você pode resolver esse problema no Windows:

Configurações globais para finais de linha O comando git config core.autocrlf é usado para alterar como o Git lida com finais de linha. É preciso um único argumento.

No Windows, você simplesmente passa fiel à configuração. Por exemplo: C:> git config --global core.autocrlf true

Boa sorte, espero ter ajudado.

c-santana
fonte