Qual é a melhor CRLF (retorno de carro, alimentação de linha) manipulação estratégia com Git?
-
05-07-2019 - |
Pergunta
Eu tentei cometer arquivos com linhas CRLF-finais, mas falhou.
Eu passei um dia inteiro de trabalho no meu computador com Windows tentando estratégias diferentes e quase foi desenhado para parar de tentar usar o Git e em vez de tentar Mercurial .
Por favor, compartilhe apenas uma melhor prática por resposta.
Solução
Quase quatro anos depois de fazer esta pergunta, tenho finalmente encontrados uma resposta que me completamente satisfaz !
Veja os detalhes em github: ajuda 's guia para Lidar com fins de linha .
Git permite que você defina a linha que termina propriedades de um repo diretamente usando o texto do atributo na
.gitattributes
arquivo. Este arquivo está empenhada em o reporte e substitui a configuraçãocore.autocrlf
, permitindo-lhe garantir um comportamento consistente para todos os usuários, independentemente de suas configurações Git.
E assim
A vantagem disto é que o seu fim de linha configuração de agora viaja com seu repositório e você não precisa se preocupar se ou não colaboradores ter as definições globais adequadas.
Aqui está um exemplo de um .gitattributes
arquivo
# Auto detect text files and perform LF normalization
* text=auto
*.cs text diff=csharp
*.java text diff=java
*.html text diff=html
*.css text
*.js text
*.sql text
*.csproj text merge=union
*.sln text merge=union eol=crlf
*.docx diff=astextplain
*.DOCX diff=astextplain
# absolute paths are ok, as are globs
/**/postinst* text eol=lf
# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf
Há um coleção de pronto para usar .gitattributes arquivos para a maioria das linguagens de programação populares. É útil para você começar.
Depois de criar ou ajustado o seu .gitattributes
, você deve executar uma vez-e-for-all final de linha re-normalização .
Note que a GitHub desktop aplicativo pode sugerir e criar um .gitattributes
arquivo depois de abrir repo Git do seu projeto no aplicativo. Para tentar isso, clique no ícone de engrenagem (no canto superior direito)> Configurações do Repositório ...> terminações e atributos de linha. Você será solicitado para adicionar o recomendado .gitattributes
e, se concordar, o aplicativo irá também realizar uma normalização de todos os arquivos em seu repositório.
Finalmente, o Mente No final do artigo a sua linha fornece mais fundo e explica como Git tem evoluído sobre as matérias em questão. Eu considero este leitura obrigatória .
Você provavelmente os usuários em sua equipe que usam EGit ou JGit (ferramentas como Eclipse e TeamCity usá-los) para submeter as suas alterações tem. Então você está fora de sorte, como @gatinueta explicou em comentários deste resposta:
Esta definição não irá satisfazê-lo completamente se você tem pessoas que trabalham com EGit ou JGit em sua equipe, uma vez que essas ferramentas vão simplesmente ignorar .gitattributes e, felizmente, o check-in arquivos CRLF https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372
Um truque poderia ser a de tê-los submeter as suas alterações em outro cliente, dizer SourceTree . Nossa equipe de volta, então preferido que ferramenta para EGit do Eclipse para muitos casos de uso.
Quem disse que o software é fácil? : - /
Outras dicas
Do not converter finais de linha. Não é o trabalho do VCS para interpretar os dados - apenas loja e versão-lo. Cada editor de texto moderno pode ler ambos os tipos de finais de linha de qualquer maneira.
Você quase sempre quer autocrlf=input
a menos que você realmente saiba o que está fazendo.
Alguns contexto adicional abaixo:
Deve ser
core.autocrlf=true
se você gosta DOS terminando oucore.autocrlf=input
se preferir unix-novas linhas. Em ambos os casos, a sua vontade repositório Git têm apenas LF, que é a coisa certa. O único argumento paracore.autocrlf=false
foi que automática heurística pode detectar incorretamente alguns binários como texto e, em seguida, sua telha será corrompido. Assim, opçãocore.safecrlf
foi introduzido para avisar um usuário se uma mudança irreversível acontece. Na verdade, existem dois possibilidades de mudanças irreversível - Misto alinham-terminando em arquivo de texto, neste normalização é desejável, de modo que este aviso pode ser ignorado, ou (Muito improvável) que Git incorretamente detectado o arquivo binário como texto. Então você precisa usar atributos para dizer Git que este arquivo é binário.
O parágrafo acima foi originalmente retirado de um segmento em gmane.org, mas desde então tem ido para baixo.
Duas estratégias alternativas para obter consistente sobre as quebras de linha em ambientes mistos (Microsoft + Linux + Mac):
A. Mundial por todos os repositórios de configuração
1) Convert tudo para um formato
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) Conjunto core.autocrlf
para input
em Linux / Unix ou true
em MS Windows (repositório ou global)
git config --global core.autocrlf input
3) [Opcional] conjunto core.safecrlf
para true
(a parada) ou warn
(a cantar :) adicionar guarda adicional comparando se a transformação de nova linha invertida resultaria no mesmo arquivo
git config --global core.safecrlf true
B. Ou per Configuração do repositório
1) Convert tudo para um formato
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) Adicionar ficheiro .gitattributes
ao seu repositório
echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'
Não se preocupe com seus arquivos binários - Git deve ser inteligente o suficiente sobre eles
. Tente configurar a opção de configuração core.autocrlf
para true
. Também ter um olhar para a opção core.safecrlf
.
Na verdade, soa como core.safecrlf
já pode ser definido em seu repositório, porque (grifo meu):
Se isto não é o caso para a configuração atual de core.autocrlf, git irá rejeitar o arquivo .
Se este for o caso, então você pode querer verificar se o seu editor de texto está configurado para fins de linha uso consistente. Você provavelmente vai ter problemas se um arquivo de texto contém uma mistura de LF e CRLF final de linha.
Finalmente, sinto que a recomendação de simplesmente "use o que você está dado" e usar LF encerrado linhas sobre o Windows irá causar mais problemas do que resolve. Git tem as opções acima para tentar finais de linha alça de uma forma sensível, por isso faz sentido usá-los.
Usando core.autocrlf=false
parou de todos os arquivos de ser marcado atualizado assim que eu verifiquei-los na minha Visual studio 2010 projeto . Os outros dois membros da equipe de desenvolvimento também estão usando sistemas Windows para um ambiente misto não entram em jogo, mas as configurações padrão que veio com o repositório sempre marcado todos os arquivos como atualizada imediatamente após a clonagem.
Eu acho que a linha de fundo é encontrar o ajuste CRLF trabalha para o seu ambiente. Especialmente desde que em muitos outros repositórios em nossas caixas de Linux configuração autocrlf = true
produz melhores resultados.
20 anos mais tarde e ainda estamos lidando com linha que termina disparidades entre sistemas operacionais ... triste.
Estas são as duas opções para Windows e o Visual Studio usuários que compartilhar código com Mac ou Linux usuários . Para obter uma explicação estendida, leia a gitattributes manual.
Texto * = auto
No arquivo .gitattributes
add do seu repo:
* text=auto
Isto irá normalizar todos os arquivos com fins de linha LF
no repo.
E dependendo do seu sistema operacional (configuração core.eol
), os arquivos na árvore de trabalho será normalizado para LF
para sistemas baseados em Unix ou CRLF
para sistemas Windows.
Esta é a configuração que repos Microsoft .NET usar.
Exemplo:
Hello\r\nWorld
será normalizado no repo sempre como:
Hello\nWorld
No check-out, a árvore de trabalho no Windows será convertido em:
Hello\r\nWorld
No check-out, a árvore de trabalho no Mac será deixado como:
Hello\nWorld
Nota: Se o seu repo já contém arquivos não normalizados,
git status
vai mostrar esses arquivos como completamente modificado na próxima vez que você fizer qualquer alteração neles, e que poderia ser uma dor para outros usuários para fundir as suas alterações mais tarde. Consulte refrescante uma repositório depois de mudar finais de linha para mais informações.
core.autocrlf = true
Se text
não é especificado no arquivo .gitattributes
, Git usa a variável de configuração core.autocrlf
para determinar se o arquivo deve ser convertido.
Para usuários do Windows, git config --global core.autocrlf true
é uma ótima opção porque:
- Os arquivos são normalizados para fins de linha
LF
apenas quando adicionado para o repo. Se houver arquivos não normalizados no repo, esta definição não irá tocá-los. - Todos arquivos de texto são convertidos para fins de linha
CRLF
no diretório de trabalho.
O problema com esta abordagem é que:
- Se você é um usuário do Windows com
autocrlf = input
, você vai ver um monte de arquivos com fins de linhaLF
. Não é um perigo para o resto da equipe, porque seus commits ainda vai ser normalizada com fins de linhaLF
. - Se você é um usuário do Windows com
core.autocrlf = false
, você vai ver um monte de arquivos com fins de linhaLF
e você pode introduzir arquivos com fins de linhaCRLF
para o repo. - A maioria dos usuários de Mac usar
autocrlf = input
e pode obter arquivos com terminações de arquivoCRLF
, provavelmente de usuários do Windows comcore.autocrlf = false
.
Este é apenas um Solução Solução:
Em casos normais, use as soluções que são enviados com o git. Estes grande trabalho na maioria dos casos. Força para LF se você compartilhar o desenvolvimento em sistemas baseados em Windows e Unix por definição .gitattributes .
No meu caso houve> 10 programadores a desenvolver um projecto no Windows. Este projeto foi verificado com CRLF e não havia nenhuma opção para forçar a LF.
Algumas definições foram escritos internamente na minha máquina, sem qualquer influência sobre o formato LF; assim, alguns arquivos foram globalmente alterado para LF em cada pequena mudança de arquivo.
A minha solução:
Windows-Machines: Deixe tudo como está. Cuidado sobre nada, já que você é 'lobo solitário' desenvolvedor de um padrão janelas e você tem que lidar com como esta: "Não há nenhum outro sistema no mundo inteiro, é"
Unix-Machines
-
Adicione as seguintes linhas à secção
[alias]
de uma configuração. Este comando lista tudo mudou (/ novos ou seja modificado) arquivos:lc = "!f() { git status --porcelain \ | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \ | cut -c 4- ; }; f "
-
Converter todos aqueles mudado arquivos em formato DOS:
unix2dos $(git lc)
-
Opcionalmente ...
-
Criar um git ligar para este ação para automatizar esse processo
-
Use params e incluí-lo e modificar a função
grep
para corresponder apenas nomes de arquivos específicos, por exemplo .:... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
-
Sinta-se livre para fazê-lo ainda mais conveniente usando um atalho adicionais:
c2dos = "!f() { unix2dos $(git lc) ; }; f "
... e fogo o material convertido por digitação
git c2dos
-
Eu passei horas para chegar com a melhor utilização possível dos .gitattributes
, para finalmente perceber, que eu não posso contar com ele.
Infelizmente, desde que existem editores baseados em JGit (que não pode lidar com .gitattributes
corretamente), a solução segura é forçar LF em todos os lugares, mesmo em nível editor.
Use as seguintes desinfetantes anti-CRLF
.
-
Windows / Linux clientes:
core.autocrlf=input
-
.gitattributes
comprometido:* text=auto eol=lf
-
comprometidos
.editorconfig
( http://editorconfig.org/ ) que é tipo de formato padronizado, combinado com plugins editor:
--- --- UPDATE 2
Os dafaults de cliente git irá funcionar na maioria dos casos. Mesmo que você só têm janelas apenas clientes, linux somente clientes ou ambos. Estes são:
- janelas:. meio
core.autocrlf=true
converter linhas em CRLF no check-out e converter linhas em LF ao adicionar arquivos - linux:. meio
core.autocrlf=input
não se convertem linhas no check-out (não é necessário já que os arquivos deverão ser comprometida com LF) e linhas de converter para LF (se necessário) ao adicionar arquivos
A propriedade pode ser definida em diferentes âmbitos. Gostaria de sugerir explicitamente a criação no âmbito --global
, para evitar alguns problemas de IDE descritos no final.
git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf
Também eu gostaria altamente desencorajar usando git config --global core.autocrlf false
(no caso de você ter janelas apenas clientes) em contraste com o que é proposto para git documentação . Configuração para false irá comprometer os arquivos com CRLF no repo. Mas não há realmente nenhuma razão. Você nunca sabe se você vai precisar para compartilhar o projeto com os usuários do Linux. Além disso, é um passo extra para cada cliente que se junta o projeto em vez de usar o padrão.
Agora, para alguns casos especiais de arquivos (por exemplo *.bat
*.sh
) que você deseja que sejam verificados-out com LF ou com CRLF você pode usar .gitattributes
Para resumir-se para mim, o melhores práticas é a seguinte:
- Certifique-se de que cada arquivo não-binário está comprometida com LF em repo git (comportamento padrão).
- Use este comando para certificar-se de que nenhum arquivo são cometidos com CRLF:
git grep -I --files-with-matches --perl-regexp '\r' HEAD
( Nota: no Windows clientes funciona apenas atravésgit-bash
e em clientes Linux somente se compilado usando--with-libpcre
em./configure
). - Se você encontrar qualquer um desses arquivos, executando o comando acima, corrigi-los.
- Use apenas o
.gitattributes
mínimo - Instrua os usuários para definir o
core.autocrlf
descrito acima para seus valores padrão. - Não conte 100% na presença de
.gitattributes
. git-clientes de IDEs pode ignorá-los ou tratá-los differrently.
Como disse algumas coisas podem ser adicionados em atributos git:
# Always checkout with LF
*.sh text eol=lf
# Always checkout with CRLF
*.bat text eol=crlf
Eu acho que algumas outras opções seguras para .gitattributes
em vez de usar a detecção automática para arquivos binários:
-
-text
(por exemplo para arquivos*.zip
ou*.jpg
:.. Não vai ser tratado como texto, portanto, não conversões de delimitação de linhas será tentada Diff pode ser possível através de programas de conversão) -
text !eol
(por exemplo, para*.java
,*.html
: tratado como texto,mas a preferência estilo eol não está definido. Então definição do cliente é usado.) -
-text -diff -merge
(por exemplo para*.hugefile
:. Não tratado como texto No diff / merge possível)
--- --- actualização anterior
Um doloroso exemplo de um cliente que irá comprometer os arquivos de forma errada:
netbeans 8.2 (no Windows), vai erroneamente confirmar todos os arquivos de texto com CRLFs, a menos você tem explicitamente set core.autocrlf
como mundial . Isto contradiz ao comportamento do cliente git padrão e causa muitos problemas mais tarde, quando a atualização / fusão. Isto é o que faz com que alguns arquivos aparecem diferente (embora eles não são) mesmo quando você revert .
O mesmo comportamento no netbeans acontece mesmo se tiver adicionado .gitattributes
correto para o seu projeto.
Usando o seguinte comando após um commit, vai pelo menos ajudar a detectar mais cedo se o seu repositório git tem linha que termina questões: git grep -I --files-with-matches --perl-regexp '\r' HEAD