¿Por qué debería usar core.autocrlf = true en Git?

296

Tengo un repositorio de Git al que se accede desde Windows y OS X, y que sé que ya contiene algunos archivos con terminaciones de línea CRLF. Por lo que puedo decir, hay dos formas de lidiar con esto:

  1. Establecer core.autocrlfen falsetodas partes,

  2. Siga las instrucciones aquí (se hizo eco en las páginas de ayuda de GitHub) para convertir el repositorio para contener solamente terminaciones de líneas LF, y posteriormente ajustado core.autocrlfa trueen Windows y inputen OS X. El problema con esto es que si tengo los archivos binarios en el repositorio ese:

    1. no están marcados correctamente como binarios en gitattributes, y
    2. puede contener CRLF y LF,

    Serán corrompidos. Es posible que mi repositorio contenga tales archivos.

Entonces, ¿por qué no debería simplemente desactivar la conversión de final de línea de Git? Hay muchas advertencias vagas en la web sobre la core.autocrlfdesconexión que causa problemas, pero muy pocas específicas ; lo único que he encontrado hasta ahora es que kdiff3 no puede manejar las terminaciones de CRLF (no es un problema para mí), y que algunos editores de texto tienen problemas de final de línea (tampoco es un problema para mí).

El repositorio es interno de mi empresa, por lo que no necesito preocuparme por compartirlo con personas con diferentes configuraciones de autocrlf o requisitos de final de línea.

¿Hay algún otro problema con solo dejar las terminaciones de línea tal como las desconozco?

Rico
fuente
1
¿ Stackoverflow.com/questions/2333424/… ayuda? Tengo un enlace a razones específicas para dejarlo autocrlfen falso.
VonC
3
@VonC Gracias, pero ya puedo dictar que todos los usuarios de la compañía establezcan <code> autocrlf </code> en falso y actualmente creo que esa es la mejor opción. Pero quiero saber si hay alguna razón por la que no debería hacer eso, porque puedo encontrar que hay muchas personas (por ejemplo, GitHub) que dicen que se debe configurar Autocrlf , pero no hay detalles específicos de por qué.
Rico
3
@VonC, es decir, no estoy buscando razones para establecer autocrlfen falso. Estoy buscando razones para ponerlo en verdad.
Rico
99
Por qué no usar autocrlf = input: parece ser la resolución perfecta entre los dos extremos: mantiene su repositorio limpio de basura CRLF, y localmente los desarrolladores de Windows pueden usar lo que quieran sin que sus archivos locales tengan algo mágico hecho automáticamente. (Es posible que quieran LF localmente por varias razones, por lo que truees malo, en mi opinión). No puedo ver ninguna desventaja de usar autocrlf = input.
iconoclasta
77
@iconclast, una razón por la que me he encontrado es si construye distribuciones que incluyen tanto archivos por lotes de Windows como scripts de shell de Unix. Desea usar la línea correcta que termina en cada caso, y esto es más difícil de hacer si Git está cambiando las cosas incluso después de que las establezca explícitamente de una manera u otra.
user1809090

Respuestas:

227

Las razones específicas solamente para configurar autocrlfa trueson:

  • evite git statusmostrar todos sus archivos modifieddebido a la conversión automática de EOL al clonar un repositorio EOL Git basado en Unix en uno de Windows (consulte el problema 83, por ejemplo)
  • y sus herramientas de codificación de alguna manera dependen de un estilo EOL nativo presente en su archivo:

A menos que pueda ver un tratamiento específico que debe tratar con la EOL nativa, es mejor que se vaya autocrlfafalse ( git config --global core.autocrlf false).

Tenga en cuenta que esta configuración sería local (porque la configuración no se transfiere de repositorio a repositorio)

Si desea la misma configuración para todos los usuarios que clonan ese repositorio, consulte " ¿Cuál es la mejor CRLFestrategia de manejo con git? ", Utilizando el textatributo en el .gitattributesarchivo .

Ejemplo:

*.vcproj    text eol=crlf
*.sh        text eol=lf

Nota: a partir de git 2.8 (marzo de 2016), los marcadores de combinación ya no introducirán el final de línea mixta (LF) en un archivo CRLF.
Consulte " Hacer que Git use CRLF en sus líneas de fusión" <<<<<<< HEAD " "

VonC
fuente
55
@VonC ¡Gracias! Eso me ayuda a sentirme más seguro de que es seguro usarlo autocrlf=false. Por interés, ¿sabe por qué git todavía realiza la conversión eol incluso si tiene autocrlf configurado en falso?
Rico
14
@VonC: No creo que esta respuesta sea correcta. Usar core.autocrlf = true en Windows funciona como se esperaba. Todos los archivos del repositorio (que deberían tener terminaciones de línea LF en este escenario) se convierten en terminaciones de línea CRLF al finalizar la compra en una PC con Windows. Todos los archivos se vuelven a convertir a finales de línea LF al confirmar desde una PC con Windows. La forma de meterse en problemas es pagar inicialmente en una PC con Windows con la configuración core.autocrlf incorrecta (que es demasiado fácil de hacer).
Michael Maddox
3
@Michael Entonces, ¿en ese caso, la única razón para no usar core.autocrlf=falseen mi escenario es si tuviera alguna herramienta / editor que se confundiría con los finales de línea?
Rich
49
Definitivamente lo usaría false, nunca he sido un gran fanático de las cosas automáticas o mágicas que ocurren en segundo plano. Solo use \ny en UTF-8todas partes y estará bien. Si alguna tuerca de cabeza no entiende que hay reglas y convenciones y se olvida de utilizar UTF-8o \n, entonces alguien convertidos de forma manual y se golpea la cara.
Torre
55
@ Pauld'Aoust Todavía preferiría especificar el tipo de archivo que necesita ese CRLF a través de core.eolatributos en un .gitattributesarchivo, en lugar de utilizar esta core.autocrlfconfiguración global que se aplica indiscriminadamente a todos los archivos.
VonC
40

Soy un desarrollador de .NET y he usado Git y Visual Studio durante años. Mi fuerte recomendación es establecer los finales de línea en verdadero. Y hágalo lo antes posible en la vida de su Repositorio.

Dicho esto, ODIO que Git cambie mis finales de línea. Un control de origen solo debe guardar y recuperar el trabajo que hago, NO debe modificarlo. Nunca. Pero lo hace.

Lo que sucederá si no tiene todos los desarrolladores configurados como verdaderos, es que UN desarrollador finalmente se configurará como verdadero. Esto comenzará a cambiar las terminaciones de línea de todos sus archivos a LF en su repositorio. Y cuando los usuarios se configuran como falsos, échales un vistazo, Visual Studio te advertirá y te pedirá que los cambies. Tendrás 2 cosas que suceden muy rápidamente. Uno, obtendrá más y más de esas advertencias, cuanto más grande sea su equipo, más obtendrá. La segunda, y lo peor, es que mostrará que todas las líneas de cada archivo modificado fueron cambiadas (porque las terminaciones de cada línea serán cambiadas por el tipo verdadero). Eventualmente, ya no podrá seguir los cambios en su repositorio de manera confiable. Es MUCHO más fácil y más limpio hacer que todos mantengan la verdad, que tratar de mantener a todos falsos. Tan horrible como es vivir con el hecho de que su control de fuente confiable está haciendo algo que no debería. Nunca.

JGTaylor
fuente
Mi compañía es lo suficientemente pequeña como para que podamos exigir fácilmente que falso se use en todas partes, y hubiera pensado que las compañías más grandes podrían hacerlo a través de una política, pero supongo que esta es una razón legítima para usar "verdadero", así que estoy votando de todas formas. ¡Gracias!
Rico
1
El problema al hacer esto con una política (archivo forzado) es que en una máquina Windows puede tener un archivo de configuración local, global y oculto (ProgramData / Git / Confg). Puede imponer lo local registrándolo en el repositorio, pero lo global y los archivos ocultos tienen prioridad. También es posible que lo local y lo global (u oculto) sean diferentes. Si lo están, entrarán en conflicto entre sí en la MISMA máquina, causando errores de finalización de línea donde no los hay. Es un dolor rastrearlo. :(
JGTaylor
77
exactamente lo que pienso. no es el trabajo de un control de código fuente alterar los archivos de código como le plazca. Los finales de línea deberían ser simplemente una preocupación de las herramientas de edición, nada más.
Tuncay Göncüoğlu
66
Si su proyecto es solo para Windows, entonces no hay problema. Sin embargo, si usted o sus colegas trabajan en una plataforma * nix, entonces su "recomendación fuerte" causará problemas. Intente ejecutar un script bash, perl o python con el shebang que termina en \r\ny verá.
phuclv
66
La situación que describió no es un problema de GIT, establezca la configuración en FALSO como debería ser y desaparecerá. Instad, es un problema en el trabajo en equipo. ¿Qué significa "eventualmente un desarrollador establece true"? ¿Por qué les permitirías eso en primer lugar? cuando los configura para acceder al repositorio de git, al igual que no permite contaminar ciertas áreas con diferentes langs (para que cualquiera que trabaje en eso pueda leerlo), o simplemente mantenga ramas / fusiones / rebases / etc. a lo largo del elegido política, deben obtener una regla clara: establecer crlf correcto.
quetzalcoatl
12

Actualización 2 :

Xcode 9 parece tener una "característica" donde ignorará las terminaciones de línea actuales del archivo y, en su lugar, solo usará su configuración predeterminada de finalización de línea al insertar líneas en un archivo, lo que dará como resultado archivos con terminaciones de línea mixtas.

Estoy bastante seguro de que este error no existía en Xcode 7; no estoy seguro acerca de Xcode 8. La buena noticia es que parece estar arreglado en Xcode 10.

Por el tiempo que existió, este error causó una pequeña cantidad de hilaridad en la base de código a la que me refiero en la pregunta (que hasta el día de hoy usa autocrlf=false), y condujo a muchos mensajes de confirmación "EOL" y, finalmente, a que escribiera un pre-commitgancho git para verificar para / evitar la introducción de terminaciones de línea mixtas.

Actualización :

Nota: Como se ha señalado por VonC, a partir de Git 2.8, marcadores de combinación será no introducir estilo Unix el fin de línea en un archivo de estilo de Windows .

Original :

Un pequeño inconveniente que he notado con esta configuración es que cuando hay conflictos de fusión, las líneas que agrega git para marcar las diferencias no tienen terminaciones de línea de Windows, incluso cuando el resto del archivo sí, y puede terminar con un archivo con terminaciones de línea mixtas, por ejemplo:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

Esto no nos causa ningún problema (imagino que cualquier herramienta que pueda manejar ambos tipos de terminaciones de línea también se ocupará de las terminaciones de línea mixtas, sin duda todas las que usamos), pero es algo a tener en cuenta.

La otra cosa * que hemos encontrado es que cuando se usa git diffpara ver los cambios en un archivo que tiene finales de línea de Windows, las líneas que se han agregado muestran sus retornos de carro, por lo tanto:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

* Realmente no merece el término: "problema".

Rico
fuente
2
Nota: cuando Visual Studio encuentra un archivo de este tipo, le ofrece la normalización de los finales de línea. Elegir los finales de línea de Windows o elegir no normalizar los finales de línea funciona bien (como VS todavía lo muestra correctamente, las líneas ofensivas se habrán eliminado una vez que se haya resuelto el conflicto).
Rico
2
Lamentablemente, los nazis de control de versiones corporativas no están de acuerdo con esto (LF en marcadores de conflicto de fusión) no es un problema.
Ilia G
1
Estoy de acuerdo en que LF en marcadores de conflicto de fusión no debería ser un problema. Esas líneas no deberían comprometerse con el repositorio de todos modos.
robar
1
Nota: a partir de git 2.8 (marzo de 2016), los marcadores de combinación en realidad tendrán un final de línea CRLF. Ver stackoverflow.com/a/35474954/6309
VonC