Ao fazer um git diff
, diz "Sem nova linha no final do arquivo" .
Ok, não há nova linha no final do arquivo. Qual é o grande problema?
Qual é o significado da mensagem e o que ela está tentando nos dizer?
Ao fazer um git diff
, diz "Sem nova linha no final do arquivo" .
Ok, não há nova linha no final do arquivo. Qual é o grande problema?
Qual é o significado da mensagem e o que ela está tentando nos dizer?
Respostas:
Indica que você não possui uma nova linha (geralmente '\n'
, também conhecida como CR ou CRLF) no final do arquivo.
Ou seja, simplesmente, o último byte (ou bytes, se você estiver no Windows) no arquivo não é uma nova linha.
A mensagem é exibida porque, caso contrário, não há como diferenciar um arquivo em que existe uma nova linha no final e uma em que não existe. Diff precisa gerar uma nova linha de qualquer maneira, ou o resultado seria mais difícil de ler ou processar automaticamente.
Observe que é um bom estilo sempre colocar a nova linha como último caractere, se for permitido pelo formato do arquivo. Além disso, por exemplo, para arquivos de cabeçalho C e C ++, é exigido pelo padrão da linguagem.
Não é apenas um estilo ruim, pode levar a um comportamento inesperado ao usar outras ferramentas no arquivo.
Aqui está test.txt
:
first line
second line
Não há caracteres de nova linha na última linha. Vamos ver quantas linhas estão no arquivo:
$ wc -l test.txt
1 test.txt
Talvez seja isso que você deseja, mas na maioria dos casos você provavelmente esperaria haver duas linhas no arquivo.
Além disso, se você quiser combinar arquivos, pode não se comportar da maneira que você esperaria:
$ cat test.txt test.txt
first line
second linefirst line
second line
Finalmente, isso tornaria suas diferenças um pouco mais barulhentas se você adicionasse uma nova linha. Se você adicionou uma terceira linha, ela mostrará uma edição na segunda linha e também na nova adição.
A única razão é que o Unix historicamente tinha uma convenção de todos os arquivos de texto legíveis por humanos, terminando em uma nova linha. Na época, isso evitava processamento extra ao exibir ou ingressar em arquivos de texto e tratava os arquivos de texto de maneira diferente dos arquivos que continham outros tipos de dados (por exemplo, dados binários brutos que não são legíveis por humanos).
Por causa dessa convenção, muitas ferramentas daquela época esperam a nova linha final, incluindo editores de texto, ferramentas de difusão e outras ferramentas de processamento de texto. O Mac OS X foi desenvolvido no BSD Unix e o Linux foi desenvolvido para ser compatível com o Unix; portanto, ambos os sistemas operacionais herdaram a mesma convenção, comportamento e ferramentas.
O Windows não foi desenvolvido para ser compatível com Unix, portanto, não possui a mesma convenção, e a maioria dos softwares do Windows lida perfeitamente sem nenhuma nova linha.
Mas, desde que o Git foi desenvolvido primeiro para Linux, e muitos softwares de código aberto são criados em sistemas compatíveis com Unix, como Linux, Mac OS X, FreeBSD, etc., a maioria das comunidades de código aberto e suas ferramentas (incluindo linguagens de programação) continuam seguir essas convenções.
Existem razões técnicas que faziam sentido em 1971, mas nesta época é principalmente convenção e manutenção da compatibilidade com as ferramentas existentes.
Se você adicionar uma nova linha de texto no final do arquivo existente que ainda não possui um newline character
no final, o diff mostrará a última linha antiga como tendo sido modificada, mesmo que conceitualmente não fosse.
Esse é pelo menos um bom motivo para adicionar um newline character
no final.
Um arquivo contém:
A() {
// do something
}
Hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
Agora você o edita para
A() {
// do something
}
// Useful comment
Hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d0a 2f2f 2055 something.}.// U
00000020: 7365 6675 6c20 636f 6d6d 656e 742e 0a seful comment..
O diff do git mostrará:
-}
\ No newline at end of file
+}
+// Useful comment.
Em outras palavras, mostra uma diferença maior do que conceitualmente ocorreu. Isso mostra que você excluiu a linha }
e a adicionou }\n
. Isso foi, de fato, o que aconteceu, mas não foi o que aconteceu conceitualmente , portanto pode ser confuso.
A razão pela qual essa convenção entrou em prática é porque, em sistemas operacionais do tipo UNIX, um caractere de nova linha é tratado como um terminador de linha e / ou limite de mensagem (isso inclui canalização entre processos, buffer de linha, etc.).
Considere, por exemplo, que um arquivo com apenas um caractere de nova linha seja tratado como uma única linha vazia. Por outro lado, um arquivo com comprimento de zero bytes é na verdade um arquivo vazio com zero linhas. Isso pode ser confirmado de acordo com o wc -l
comando.
No total, esse comportamento é razoável, porque não haveria outra maneira de distinguir entre um arquivo de texto vazio e um arquivo de texto com uma única linha vazia se o \n
caractere fosse apenas um separador de linhas em vez de um terminador de linha. Portanto, os arquivos de texto válidos sempre devem terminar com um caractere de nova linha. A única exceção é se o arquivo de texto estiver vazio (sem linhas).
Há uma coisa que não vejo nas respostas anteriores. Aviso sobre nenhum final de linha pode ser um aviso quando uma parte de um arquivo for truncada. Pode ser um sintoma de falta de dados.
O principal problema é o que você define linha e se a sequência de caracteres final on-line faz parte da linha ou não. Editores baseados em UNIX (como VIM) ou ferramentas (como Git) usam a seqüência de caracteres EOL como terminador de linha, portanto, isso faz parte da linha. É semelhante ao uso de ponto e vírgula (;) em C e Pascal. No ponto-e-vírgula C termina as instruções, em Pascal as separa.
Na verdade, isso causa um problema, porque as terminações de linha são modificadas automaticamente e sujam os arquivos sem fazer nenhuma alteração neles. Veja este post para resolução.
Os arquivos de origem geralmente são concatenados por ferramentas (C, C ++: arquivos de cabeçalho, Javascript: empacotadores). Se você omitir o caractere de nova linha, poderá introduzir erros desagradáveis (onde a última linha de uma fonte é concatenada com a primeira linha do próximo arquivo de origem). Felizmente, todas as ferramentas de concatenação do código-fonte por aí inserem uma nova linha entre os arquivos concatenados, mas isso nem sempre parece ser o caso.
O cerne da questão é - na maioria dos idiomas, as novas linhas têm significado semântico e o final do arquivo não é uma alternativa definida pelo idioma para o caractere da nova linha. Portanto, você deve encerrar cada declaração / expressão com um caractere de nova linha - incluindo o último.
//
comentário de estilo no meio do código.
Seu arquivo original provavelmente não tinha nenhum caractere de nova linha.
No entanto, alguns editores como o gedit no linux silenciosamente adicionam nova linha no final do arquivo. Você não pode se livrar dessa mensagem enquanto estiver usando esse tipo de editor.
O que tentei superar esse problema é abrir um arquivo com o editor de código do visual studio
Este editor mostra claramente a última linha e você pode excluir a linha como desejar.
Pelo que vale, eu encontrei isso quando criei um projeto IntelliJ em um Mac e depois mudei o projeto para a minha máquina Windows. Eu tive que abrir manualmente todos os arquivos e alterar a configuração de codificação na parte inferior direita da janela do IntelliJ. Provavelmente não está acontecendo com a maioria, se alguém que leu esta pergunta, mas que poderia ter me poupado algumas horas de trabalho ...