Al hacer un git diff
, dice "No hay nueva línea al final del archivo" .
Ok, no hay nueva línea al final del archivo. ¿Cual es el problema?
¿Cuál es el significado del mensaje y qué intenta decirnos?
Al hacer un git diff
, dice "No hay nueva línea al final del archivo" .
Ok, no hay nueva línea al final del archivo. ¿Cual es el problema?
¿Cuál es el significado del mensaje y qué intenta decirnos?
Respuestas:
Indica que no tiene una nueva línea (generalmente '\n'
, también conocida como CR o CRLF) al final del archivo.
Es decir, simplemente hablando, el último byte (o bytes si está en Windows) en el archivo no es una nueva línea.
El mensaje se muestra porque, de lo contrario, no hay forma de distinguir entre un archivo donde hay una nueva línea al final y uno donde no. Diff tiene que generar una nueva línea de todos modos, o el resultado sería más difícil de leer o procesar automáticamente.
Tenga en cuenta que es un buen estilo colocar siempre la nueva línea como último carácter si el formato de archivo lo permite. Además, por ejemplo, para los archivos de encabezado C y C ++ es requerido por el estándar de lenguaje.
No es solo un mal estilo, puede conducir a un comportamiento inesperado al usar otras herramientas en el archivo.
Aqui esta test.txt
:
first line
second line
No hay caracteres de nueva línea en la última línea. Veamos cuántas líneas hay en el archivo:
$ wc -l test.txt
1 test.txt
Tal vez eso es lo que quieres, pero en la mayoría de los casos probablemente esperarías que haya 2 líneas en el archivo.
Además, si desea combinar archivos, es posible que no se comporte de la manera esperada:
$ cat test.txt test.txt
first line
second linefirst line
second line
Finalmente, haría que sus diferencias fueran un poco más ruidosas si tuviera que agregar una nueva línea. Si agrega una tercera línea, mostrará una edición en la segunda línea, así como la nueva adición.
La única razón es que Unix históricamente tenía una convención de todos los archivos de texto legibles por humanos que terminaban en una nueva línea. En ese momento, esto evitó el procesamiento adicional al mostrar o unir archivos de texto, y evitó tratar los archivos de texto de manera diferente a los archivos que contienen otros tipos de datos (por ejemplo, datos binarios sin procesar que no son legibles para los humanos).
Debido a esta convención, muchas herramientas de esa época esperan el final de la nueva línea, incluidos los editores de texto, las diferentes herramientas y otras herramientas de procesamiento de texto. Mac OS X se creó en BSD Unix y Linux se desarrolló para ser compatible con Unix, por lo que ambos sistemas operativos han heredado la misma convención, comportamiento y herramientas.
Windows no fue desarrollado para ser compatible con Unix, por lo que no tiene la misma convención, y la mayoría del software de Windows funcionará bien sin una nueva línea final.
Pero, dado que Git se desarrolló primero para Linux, y una gran cantidad de software de código abierto se basa en sistemas compatibles con Unix como Linux, Mac OS X, FreeBSD, etc., la mayoría de las comunidades de código abierto y sus herramientas (incluidos los lenguajes de programación) continúan seguir estas convenciones.
Hay razones técnicas que tuvieron sentido en 1971, pero en esta era es principalmente convencional y mantener la compatibilidad con las herramientas existentes.
Si agrega una nueva línea de texto al final del archivo existente que aún no tiene unnewline character
al final, el diff mostrará la última línea anterior como modificada, aunque conceptualmente no lo fue.
Esta es al menos una buena razón para agregar un newline character
al final.
Un archivo contiene:
A() {
// do something
}
Hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
Ahora lo editas en
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..
El git diff mostrará:
-}
\ No newline at end of file
+}
+// Useful comment.
En otras palabras, muestra una diferencia mayor que la ocurrida conceptualmente. Muestra que eliminó la línea }
y agregó la línea }\n
. Esto es, de hecho, lo que sucedió, pero no es lo que sucedió conceptualmente , por lo que puede ser confuso.
La razón por la que esta convención entró en práctica es porque en los sistemas operativos tipo UNIX, un carácter de nueva línea se trata como un terminador de línea y / o límite de mensaje (esto incluye la conexión entre procesos, almacenamiento en línea, etc.).
Considere, por ejemplo, que un archivo con solo un carácter de nueva línea se trata como una sola línea vacía. Por el contrario, un archivo con una longitud de cero bytes es en realidad un archivo vacío con cero líneas. Esto se puede confirmar de acuerdo con el wc -l
comando.
En conjunto, este comportamiento es razonable porque no habría otra forma de distinguir entre un archivo de texto vacío versus un archivo de texto con una sola línea vacía si el \n
carácter fuera simplemente un separador de línea en lugar de un terminador de línea. Por lo tanto, los archivos de texto válidos siempre deben terminar con un carácter de nueva línea. La única excepción es si el archivo de texto está vacío (sin líneas).
Hay una cosa que no veo en las respuestas anteriores. La advertencia de no final de línea podría ser una advertencia cuando una parte de un archivo se ha truncado. Podría ser un síntoma de datos faltantes.
El problema central es qué define la línea y si la secuencia de caracteres de final de línea es parte de la línea o no. Los editores basados en UNIX (como VIM) o las herramientas (como Git) usan la secuencia de caracteres EOL como terminador de línea, por lo tanto, es parte de la línea. Es similar al uso de punto y coma (;) en C y Pascal. En C el punto y coma termina las declaraciones, en Pascal las separa.
En realidad, esto causa un problema porque los finales de línea se modifican automáticamente archivos sucios sin hacer ningún cambio en ellos. Ver esta publicación para su resolución.
Los archivos de origen a menudo están concatenados por herramientas (C, C ++: archivos de encabezado, Javascript: paquetes). Si omite el carácter de nueva línea, podría introducir errores desagradables (donde la última línea de una fuente se concatena con la primera línea del siguiente archivo fuente). Afortunadamente, todas las herramientas de concat del código fuente por ahí insertan una nueva línea entre archivos concatenados de todos modos, pero ese no siempre parece ser el caso.
El quid de la cuestión es: en la mayoría de los idiomas, las nuevas líneas tienen un significado semántico y el final del archivo no es una alternativa definida por el idioma para el carácter de nueva línea. Por lo tanto, debe terminar cada declaración / expresión con un carácter de nueva línea, incluida la última.
//
estilo de comentarios en el medio del código.
Su archivo original probablemente no tenía carácter de nueva línea.
Sin embargo, algunos editores como gedit en linux agregan en silencio nueva línea al final del archivo. No puede deshacerse de este mensaje mientras usa este tipo de editores.
Lo que intenté superar este problema es abrir el archivo con el editor de código visual studio
Este editor muestra claramente la última línea y puede eliminar la línea como lo desee.
Por lo que vale, me encontré con esto cuando creé un proyecto IntelliJ en una Mac, y luego moví el proyecto a mi máquina Windows. Tuve que abrir manualmente cada archivo y cambiar la configuración de codificación en la parte inferior derecha de la ventana IntelliJ. Probablemente no le pase a la mayoría de los que leyeron esta pregunta, pero eso podría haberme ahorrado un par de horas de trabajo ...