tipos tag remove practices etiquetas crear best git cross-platform newline eol

tag - ¿Cuál es la mejor estrategia de manejo de CRLF(retorno de carro, avance de línea) con Git?



git tag best practices (9)

Intenté enviar archivos con líneas CRLF-final, pero falló.

Pasé todo un día de trabajo en mi computadora con Windows probando diferentes estrategias y casi me detuve para dejar de usar Git y, en cambio, probar Mercurial .

Por favor comparta solo una buena práctica por respuesta.


Casi cuatro años después de hacer esta pregunta, ¡finalmente encontré una respuesta que me satisface completamente !

Vea los detalles en github: guía de ayuda para tratar con los finales de línea .

Git le permite establecer las propiedades de fin de línea para un repositorio directamente usando el atributo de texto en el archivo .gitattributes . Este archivo se confirma en el repositorio y anula la configuración core.autocrlf , lo que le permite garantizar un comportamiento coherente para todos los usuarios, independientemente de su configuración de git.

Y por lo tanto

La ventaja de esto es que su configuración de final de línea ahora viaja con su repositorio y no tiene que preocuparse de si los colaboradores tienen la configuración global adecuada.

Aquí hay un ejemplo de un archivo .gitattributes

# 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

Hay una colección conveniente de archivos .gitattributes listos para usar para los lenguajes de programación más populares. Es útil para comenzar.

Una vez que haya creado o ajustado sus .gitattributes , debe realizar una re-normalización de los finales de línea de una vez por todas.

Tenga en cuenta que la aplicación GitHub Desktop puede sugerir y crear un archivo .gitattributes después de abrir el repositorio Git de su proyecto en la aplicación. Para intentarlo, haga clic en el icono de engranaje (en la esquina superior derecha)> Configuración del repositorio ...> Finales de línea y atributos. Se le pedirá que agregue los .gitattributes recomendados y, si está de acuerdo, la aplicación también realizará una normalización de todos los archivos en su repositorio.

Finalmente, el artículo Mind the End of Your Line proporciona más antecedentes y explica cómo Git ha evolucionado en los asuntos que nos ocupan. Considero que esto requiere lectura .

Probablemente tenga usuarios en su equipo que usen EGit o JGit (herramientas como Eclipse y TeamCity los usan) para confirmar sus cambios. Entonces no tienes suerte, como @gatinueta explicó en los comentarios de esta respuesta:

Esta configuración no lo satisfará completamente si tiene personas que trabajan con Egit o JGit en su equipo, ya que esas herramientas simplemente ignorarán .gitattributes y alegremente revisarán los archivos CRLF https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372

Un truco podría ser hacer que confirmen sus cambios en otro cliente, por ejemplo, SourceTree . En aquel entonces, nuestro equipo prefería esa herramienta a EGit de Eclipse para muchos casos de uso.

¿Quién dijo que el software es fácil? : - /


Dos estrategias alternativas para ser coherentes con los finales de línea en entornos mixtos (Microsoft + Linux + Mac):

A. Configuración global por todos los repositorios

1) Convertir todo a un formato

find . -type f -not -path "./.git/*" -exec dos2unix {} /; git commit -a -m ''dos2unix conversion''

2) Establezca core.autocrlf para input en Linux / UNIX o true en MS Windowns (repositorio o global)

git config --global core.autocrlf input

3) [Opcional] establezca core.safecrlf en true (para detener) o warn (para cantar :) para agregar protección adicional si la transformación de nueva línea invertida resultaría en el mismo archivo

git config --global core.safecrlf true


B. O por configuración del repositorio

1) Convertir todo a un formato

find . -type f -not -path "./.git/*" -exec dos2unix {} /; git commit -a -m ''dos2unix conversion''

2) agregue el archivo .gitattributes a su repositorio

echo "* text=auto" > .gitattributes git add .gitattributes git commit -m ''adding .gitattributes for unified line-ending''

No te preocupes por tus archivos binarios: Git debería ser lo suficientemente inteligente como para hacerlo.

Más sobre safecrlf / autocrlf variables


El uso de core.autocrlf=false todos los archivos se core.autocrlf=false como actualizados tan pronto como los verifiqué en mi proyecto de Visual Studio 2010 . Los otros dos miembros del equipo de desarrollo también están usando sistemas Windows, por lo que no entró en juego un entorno mixto, pero la configuración predeterminada que viene con el repositorio siempre marcó todos los archivos como actualizados inmediatamente después de la clonación.

Supongo que la conclusión es encontrar qué configuración de CRLF funciona para su entorno. Especialmente porque en muchos otros repositorios en nuestros cuadros de Linux, la configuración de autocrlf = true produce mejores resultados.

Más de 20 años después, todavía estamos lidiando con las diferencias de final de línea entre sistemas operativos ... triste.


Esta es solo una solución alternativa :

En casos normales, use las soluciones que se envían con git. Estos funcionan muy bien en la mayoría de los casos. Forzar a LF si comparte el desarrollo en sistemas basados ​​en Windows y Unix configurando .gitattributes .

En mi caso hubo más de 10 programadores desarrollando un proyecto en Windows. Este proyecto se registró con CRLF y no había ninguna opción para forzar a LF.

Algunas configuraciones fueron escritas internamente en mi máquina sin ninguna influencia en el formato LF; por lo tanto, algunos archivos se cambiaron globalmente a LF en cada cambio de archivo pequeño.

Mi solución:

Windows-Machines: deja todo como está. No te preocupes por nada, ya que eres un desarrollador predeterminado de Windows ''Lone Wolf'' y tienes que manejarlo así: "No hay otro sistema en el mundo, ¿verdad?"

Unix-Machines

  1. Agregue las siguientes líneas a la sección [alias] una configuración. Este comando enumera todos los archivos modificados (es decir, modificados / nuevos):

    lc = "!f() { git status --porcelain / | egrep -r /"^(/?| )./*//(.[a-zA-Z])*/" / | cut -c 4- ; }; f "

  2. Convierte todos esos archivos modificados en formato DOS:

    unix2dos $(git lc)

  3. Opcionalmente ...

    1. Crea un hook git para esta acción para automatizar este proceso.

    2. Use params e inclúyalo y modifique la función grep para que coincida solo con nombres de archivos particulares, por ejemplo:

      ... | egrep -r "^(/?| ).*/.(txt|conf)" | ...

    3. Siéntase libre de hacerlo aún más conveniente usando un atajo adicional:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "

      ... y dispara las cosas convertidas escribiendo

      git c2dos


Estas son las dos opciones para usuarios de Windows y Visual Studio que comparten código con usuarios de Mac o Linux . Para una explicación extendida, lea el manual de atributos de gitat .

* texto = auto

En el archivo .gitattributes tu repositorio agrega:

* text=auto

Esto normalizará todos los archivos con finales de línea LF en el repositorio.

Y dependiendo de su sistema operativo (configuración core.eol ), los archivos en el árbol de trabajo se normalizarán a LF para sistemas basados ​​en Unix o CRLF para sistemas Windows.

Esta es la configuración que utilizan los repositorios de Microsoft .NET .

Ejemplo:

Hello/r/nWorld

Se normalizará en el repo siempre como:

Hello/nWorld

Al finalizar la compra, el árbol de trabajo en Windows se convertirá a:

Hello/r/nWorld

Al finalizar la compra, el árbol de trabajo en Mac se dejará como:

Hello/nWorld

Nota: si su repo ya contiene archivos no normalizados, git status mostrará estos archivos como completamente modificados la próxima vez que realice algún cambio en ellos, y podría ser un dolor para otros usuarios fusionar sus cambios más adelante. Consulte la actualización de un repositorio después de cambiar los finales de línea para obtener más información.

core.autocrlf = true

Si el text no se especifica en el archivo .gitattributes , Git usa la variable de configuración core.autocrlf para determinar si el archivo debe convertirse.

Para los usuarios de Windows, git config --global core.autocrlf true es una excelente opción porque:

  • Los archivos se normalizan a los finales de línea LF solo cuando se agregan al repositorio. Si hay archivos que no están normalizados en el repositorio, esta configuración no los tocará.
  • Todos los archivos de texto se convierten a finales de línea CRLF en el directorio de trabajo.

El problema con este enfoque es que:

  • Si es un usuario de Windows con autocrlf = input , verá un montón de archivos con finales de línea LF . No es un peligro para el resto del equipo, ya que sus compromisos aún se normalizarán con los finales de línea LF .
  • Si es un usuario de Windows con core.autocrlf = false , verá un montón de archivos con finales de línea LF y puede introducir archivos con finales de línea CRLF en el repositorio.
  • La mayoría de los usuarios de Mac utilizan autocrlf = input y pueden obtener archivos con terminaciones de archivos CRLF , probablemente de usuarios de Windows con core.autocrlf = false .

He pasado horas para encontrar el mejor uso posible de .gitattributes , para finalmente darme cuenta de que no puedo contar con ello.
Desafortunadamente, mientras existan editores basados ​​en JGit (que no puedan manejar .gitattributes correctamente), la solución segura es forzar a LF en todas partes, incluso en el nivel de editor.

Use los siguientes desinfectantes anti-CRLF .

--- Actualización ---

Incluso si no desea utilizar la estrategia anterior, el siguiente comando es su amigo ( Nota: en los clientes de Windows solo funciona a través de git-bash y en los clientes de Linux solo si se compila con --with-libpcre en ./configure ).

# Print all files that have been committed with CRLF (more correctly that contain CR), so that you normalize them. git grep -I --files-with-matches --perl-regexp ''/r'' HEAD

Un ejemplo doloroso :

Netbeans 8.2 (en Windows), confirmará incorrectamente todos los archivos de texto con CRLF en el repositorio , a menos que haya establecido explícitamente core.autocrlf como global . Esto contradice el comportamiento estándar de git client y causa muchos problemas más adelante, al actualizar / fusionar. Esto es lo que hace que algunos archivos parezcan diferentes (aunque no lo sean) incluso cuando se revierte .
El mismo comportamiento en netbeans ocurre incluso si ha agregado .gitattributes correctos a su proyecto.

Al usar el comando anterior después de una confirmación, al menos le ayudará a detectar antes si su git repo tiene problemas de final de línea.


Intente establecer la opción de configuración core.autocrlf en true . También eche un vistazo a la opción core.safecrlf .

En realidad, parece que core.safecrlf ya podría estar configurado en su repositorio, porque (el énfasis es mío):

Si este no es el caso de la configuración actual de core.autocrlf, git rechazará el archivo .

Si este es el caso, entonces es posible que desee verificar que su editor de texto esté configurado para usar los finales de línea de manera consistente. Es probable que tenga problemas si un archivo de texto contiene una combinación de finales de línea LF y CRLF.

Finalmente, creo que la recomendación de simplemente "usar lo que se te da" y usar líneas terminadas en LF en Windows causará más problemas de los que resuelve. Git tiene las opciones anteriores para tratar de manejar los finales de línea de una manera sensata, por lo que tiene sentido usarlos.


No convierta los finales de línea. El trabajo de VCS no es interpretar los datos, solo almacenarlos y versionarlos. Cada editor de texto moderno puede leer ambos tipos de finales de línea de todos modos.


Casi siempre quieres autocrlf=input menos que realmente sepas lo que estás haciendo.

Un poco de contexto adicional a continuación:

Debe ser core.autocrlf=true si te gusta el final de DOS o core.autocrlf=input si prefieres las líneas nuevas de Unix. En ambos casos, su repositorio Git tendrá solo LF, que es lo correcto. El único argumento para core.autocrlf=false fue que la heurística automática puede detectar incorrectamente algunos binarios como texto y luego su mosaico se corromperá. Entonces, se core.safecrlf opción core.safecrlf para advertir a un usuario si ocurre un cambio irreversible. De hecho, hay dos posibilidades de cambios irreversibles: el final de línea mixto en el archivo de texto, en esta normalización es deseable, por lo que esta advertencia puede ignorarse o (muy poco probable) que Git detecte incorrectamente su archivo binario como texto. Entonces necesitas usar atributos para decirle a Git que este archivo es binario.

El párrafo anterior fue originalmente sacado de un hilo en gmane.org, pero desde entonces ha caído.