Deshabilitar conversiones de git EOL

100

Estoy tratando de hacer que git no cambie ningún final de línea para ninguna operación. Desafortunadamente, parece que no importa qué. Lo he reducido al siguiente caso de prueba, que tiene tantos mecanismos diferentes para deshabilitar este comportamiento como pude encontrar.


  • Comience con dos máquinas (computadora con Windows = A, computadora con Linux = B)
  • En ambas máquinas: git config --global core.autocrlf false
  • En ambas máquinas: git config --global core.eol crlf(por si acaso)

  • Cree un nuevo repositorio en A. Desde una carpeta vacía:
    • git init --shared(luego muestre el .gitdirectorio creado )
    • Crea un nuevo archivo .gitignoreen el repositorio
    • Cree un nuevo archivo .gitattributesen el repositorio con una sola línea:* -text
    • git add ., luego git commit -m "initial commit"para solucionarlo, por ejemplo, esto .
    • git branch master_recv
    • Agregar controles remotos
  • Cree un nuevo archivo document.txten el repositorio que contenga CRLF
  • Comprometerse:, git add -Aluegogit commit -m "<something>"
  • Tenga en cuenta que A document.txttodavía contiene CRLF (y eliminarlo y restablecer con --harddevuelve la versión todavía con CRLF)

  • SCP todo el directorio a la computadora B
  • Agregar un nuevo archivo que new filecontenga CRLF
  • Comprometerse:, git add -Aluegogit commit -m "<something>"
  • Tenga en cuenta que B document.txty B new filetodavía contienen CRLF

  • Lleva el maestro de B a A: git pull <remote> master:master_recv
  • A document.txtha cambiado a LF. El archivo agregado new filetambién contiene LF.

El problema no ocurre si B es una máquina con Windows.

imallett
fuente
¿ core.autocrlf Siempre ha sido falso? ¿Parece que ya tienes \nfinales de línea en tu repositorio? No hay ninguna configuración para cambiar \nen su repositorio \r\nen su directorio de trabajo.
Edward Thomson
No siempre se ha configurado (por ejemplo, cuando se creó originalmente el repositorio). Sin embargo, no debería haber ningún final de línea CR en el repositorio. Además, de nuevo, no quiero que ocurra ningún cambio en absoluto.
imallett
Lo pregunto porque su configuración debe preservar sus finales de línea como CRLF. ¿Podría publicar algún archivo en su repositorio con su ID de objeto solo para mi (ciertamente, probablemente molesto) edificación?
Edward Thomson
@EdwardThomson ¿qué quieres decir? El repositorio no es público (ya que la máquina Linux no lo es). Asumiré que quiere un archivo de ejemplo. Ver editar.
imallett
Sí, estoy de acuerdo en que ese archivo tiene terminaciones de línea CRLF. ¿Puede aclarar una cosa: mencionó que "las nuevas líneas de la máquina de Windows cambian a CR!" Seguramente fue un error tipográfico, ¿o realmente está obteniendo finales de línea de retorno de carro al estilo de Mac OS 9?
Edward Thomson

Respuestas:

74

Dentro de su proyecto, debería haber un .gitattributesarchivo. La mayoría de las veces, debería verse como a continuación (o esta captura de pantalla ):

# Handle line endings automatically for files detected as text 
# and leave all files detected as binary untouched.
* text=auto

# Never modify line endings of our bash scripts
*.sh -crlf

#
# The above will handle all files NOT found below
#
# These files are text and should be normalized (Convert crlf => lf)
*.css           text
*.html          text
*.java          text
*.js            text
*.json          text
*.properties    text
*.txt           text
*.xml           text

# These files are binary and should be left untouched
# (binary is macro for -text -diff)
*.class         binary
*.jar           binary
*.gif           binary
*.jpg           binary
*.png           binary

Cambie * text=autoa * text=falsepara deshabilitar el manejo automático (ver captura de pantalla ).

Me gusta esto:

ingrese la descripción de la imagen aquí

Si su proyecto no tiene un archivo .gitattributes, los finales de línea los establecen sus configuraciones de git. Para cambiar sus configuraciones de git, haga esto:

Vaya al archivo de configuración en este directorio:

1) C: \ ProgramData \ Git \ config

2) Abra el archivo de configuración en Notepad ++ (o cualquier editor de texto que prefiera)

3) Cambie "autocrlf =" a falso.

ingrese la descripción de la imagen aquí

Gene
fuente
31
¿Por qué utilizar imágenes en lugar de etiquetas de código? Muy inconveniente
Clint
31
Porque puedo agregar un gran cuadro rojo en la imagen para resaltar cosas.
Gene
21
El uso * text=falseno desarma el texto: deja el texto configurado con el valor de cadena falso. Esto tiene el mismo efecto que dejar el texto sin especificar (no específicamente sin definir). El uso * -textle da la configuración especial de desarmado. Desmarcar el atributo de texto en una ruta le dice a git que no intente ninguna conversión de final de línea al registrarse o al finalizar la compra.
JustAMartin
Gracias @Gene por esta respuesta. Esto me ha estado volviendo loco todo el día, ¡y este me lo resolvió!
LeopardSkinPillBoxHat
7
Lamento decir que no puedo agradecer esta respuesta. Me costó medio día descubrir que alguien había seguido el consejo engañoso. Como señaló @JustAMartin * text=falseno tiene efecto. ¡Por favor arregle la respuesta!
Paul B.
47

Una solución simple es:

  • asegúrese de que core.autocrlf esté configurado en falso para todos los repositorios:
    git config --global core.autocrlf false
  • Vuelva a clonar su repositorio y verifique que no se haya realizado ninguna conversión EOL.
  • o, desde Git 2.16 (Q1 2018) , mantenga su repositorio actual y haga ungit add --renormalize .

Si se realizan conversiones automáticamente, eso significa que hay una .gitattributes core.eoldirectiva dentro del repositorio.

Con Git 2.8+ (marzo de 2016) , verifique si todavía hay transformación eol con:

git ls-files --eol
VonC
fuente
2
¡NO LO USE autocrlfHOY! unsetted autocrlfes equivalente a false. Te quedaste detrás de los movimientos de moda en Git
Lazy Badger
1
Como antes, había intentado esto (aunque no con la bandera global) y no funcionó. La versión de git es 1.8.5.2.
imallett
@IanMallett "En este punto, parece que la máquina Linux todavía tiene CRLF": lo hará hasta que vuelva a normalizar su contenido o lo clone (como lo hizo en Windows)
VonC
11

Me lo imaginé. Parece que el programa SCP estaba convirtiendo los finales de línea. Me di cuenta de esto cuando intenté crear deliberadamente un archivo con terminaciones LF y luego observé que aparecía como CRLF cuando lo descargué.

Dado que esta fue la solución para mí, acepto esta respuesta, pero las personas del futuro también deberían consultar las otras respuestas para obtener una solución más general.

imallett
fuente
1
Buena captura, más específica que mi respuesta. +1
VonC
4

Del tema "Efectos" de la página del manual de gitattributes (5)

text

Este atributo habilita y controla la normalización de fin de línea. Cuando se normaliza un archivo de texto, sus finales de línea se convierten a LF en el repositorio. Para controlar qué estilo de final de línea se usa en el directorio de trabajo, use el eolatributo para un solo archivo y la core.eol variable de configuración para todos los archivos de texto.

Set

Establecer el atributo de texto en una ruta habilita la normalización de final de línea y marca la ruta como un archivo de texto. La conversión de final de línea se lleva a cabo sin adivinar el tipo de contenido.

Unset La desactivación del atributo de texto en una ruta le dice a Git que no intente ninguna conversión de final de línea al registrarse o al finalizar la compra.

core.autocrlfen el nuevo (1.7.2+) Git no se usa, core.eoly la configuración correcta | desarmado del atributo de texto se considera una forma más confiable

Tejón perezoso
fuente
Sin .gitattributesembargo, en el archivo, había deshabilitado explícitamente todo como texto, ¿verdad? Además, no lo veo con una opción para que no haga conversión (aunque crlfpodría no tener ningún efecto).
imallett
6
Cosa importante que a menudo se confunde: para desarmar texty evitar cualquier conversión, debe establecer .gitattributes en * -text y no en * text=false. falseno es un valor válido para el textatributo; git no lo reconocerá y, en su lugar, volverá a su configuración predeterminada de autocrlf. Además, después de cambiar el textvalor, debe hacer una copia de seguridad de todos los archivos de su repositorio local, hacer una confirmación, luego restaurar los archivos con el final de línea correcto según los necesite y volver a confirmarlos. Entonces, git no volverá a modificar el final de las líneas.
JustAMartin