¿Cómo fuerzo a git a usar LF en lugar de CR + LF en Windows?

335

Quiero forzar a git a pagar archivos en Windows usando simplemente LFnoCR+LF . Verifiqué las dos opciones de configuración pero no pude encontrar la combinación correcta de configuraciones.

Quiero que convierta todos los archivos LFy mantenga elLF en los archivos.

Observación: solía autocrlf = inputpero esto solo repara los archivos cuando los confirma. Quiero forzarlo para que los useLF .

Probablemente no estaba tan claro: el repositorio ya está usando LFpero los archivos desprotegidos usando msysgit están usando CR+LFy quiero forzar a msysgit a obtenerlos LF: forzando las terminaciones de línea de Unix .

>git config --list | grep crlf
core.autocrlf=input
Sorin
fuente
2
autocrlf=inputEs la opción correcta. Por supuesto, no lo protege de los archivos que realmente tienen cr+lfen el repositorio o crea archivos con cr+lfotra herramienta antes de agregarlos a git. ¿Qué problemas tienes que esto no funciona?
CB Bailey
2
Los archivos en el repositorio ya solo se usan, LFpero cuando los obtengo en Windows msysgit los convierte CR+LF.
sorin
Debe haber algo con tu configuración; Acabo de probar esto en mi instalación de msysgit. Con autocrlfset to input, git deja lfsolo saltos de línea. ¿Puedes publicar la salida de git config?
CB Bailey
1
En ese caso, le sugiero que registre un error; preferiblemente apuntando a un repositorio de prueba que muestre su problema e incluyendo pasos para reproducirlo ya que el comportamiento que está viendo es definitivamente incorrecto (pero no puedo reproducirlo).
CB Bailey
1
Un pequeño consejo es también asegurarse de que está ejecutando los comandos git en el 'git' que cree que es. Por ejemplo, puede tener git instalado en Windows y git instalado en Cygwin, así que asegúrese de haber configurado la configuración git correcta.
lfred

Respuestas:

106

El OP agregó en su pregunta:

los archivos desprotegidos usando msysgit están usando CR+LFy quiero forzar a msysgit a obtenerlos conLF

Un primer paso simple aún estaría en un .gitattributesarchivo:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(como se señala en los comentarios de nieto , refiriéndose a la .gitattributesconversión de fin de línea ), para evitar cualquier CRLFconversión de archivos con correcta eol.

Y siempre he recomendado git config --global core.autocrlf false deshabilitar cualquier conversión (que se aplicaría a todos los archivos versionados)

¿Ver las mejores prácticas para la configuración git multiplataforma?

Desde Git 2.16 (Q1 2018), puede usar git add --renormalize .para aplicar esa .gitattributesconfiguración de inmediato.


Pero un segundo paso más poderoso implica un controlador de filtro gitattribute y agrega un paso de mancha

controlador de filtro

Cada vez que actualice su árbol de trabajo, un script podría, solo para los archivos que ha especificado en .gitattributes, forzar la LF eoly cualquier otra opción de formato que desee aplicar.
Si el clearscript " " no hace nada, habrá (después de la confirmación) transformado sus archivos, aplicando exactamente el formato que necesita que sigan.

VonC
fuente
Una pregunta: * .txt se refiere a todos los archivos con extensión .txt o a todos los archivos de texto (no binarios)? No puedo hacer una lista con todo tipo de extensión de archivo que tendré en el proyecto.
sorin
1
@Sorin: todos los archivos con .txtextensión. Es preferible establecer esto primero y probarlo en un grupo específico, antes de generalizar a *, y agregar una regla negativa !*.xyz ...para excluir algunos pocos archivos de esa regla.
VonC
1
A estas alturas las .gitattributeslíneas deberían leer: *.txt text eol=lfsegún git-scm.com/docs/gitattributes
nieto
@grandchild Gracias. He incluido tu comentario en la respuesta para mayor visibilidad.
VonC
Supongo que después de agregar .gitattributestenemos que hacergit add --renormalize .
shuva
461

La forma más adecuada para obtener terminaciones LF en Windows es primer conjunto core.autocrlfde false:

git config --global core.autocrlf false

Debe hacer esto si está utilizando msysgit, porque lo configura trueen la configuración del sistema.

Ahora git no hará ninguna línea que finalice la normalización. Si desea que los archivos que registre estén normalizados, haga lo siguiente: Configure text=autoen su .gitattributespara todos los archivos:

* text=auto

Y establecer core.eola lf:

git config --global core.eol lf

Ahora también puede cambiar repositorios individuales a crlf (en el directorio de trabajo) ejecutando

git config core.eol crlf

Después de haber realizado la configuración, es posible que desee que git normalice todos los archivos en el repositorio . Para hacer esto, vaya a la raíz de su repositorio y ejecute estos comandos:

git rm --cached -rf .
git diff --cached --name-only -z | xargs -n 50 -0 git add -f

Si ahora desea que git también normalice los archivos en su directorio de trabajo , ejecute estos comandos:

git ls-files -z | xargs -0 rm
git checkout .
Crónica
fuente
3
Me estoy volviendo fatal pathpec '' no coincidía con ningún archivo, justo despuésgit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai
3
¿Cuál es la salida de git diff --cached --name-only?
Crónica
1
Vale la pena mencionar que puede establecer esta configuración mientras clona el repositorio en cuestión, por ejemplo git clone --config core.autocrlf=false <repo path>.
Chris Long
240

Vuelvo a esta respuesta con bastante frecuencia, aunque ninguno de estos es el adecuado para mí. Dicho esto, la respuesta correcta para mí es una mezcla de los demás.

Lo que encuentro funciona es lo siguiente:

 git config --global core.eol lf
 git config --global core.autocrlf input

Para los repositorios que se verificaron después de que se establecieron esas configuraciones globales, todo se verificará como lo que sea que esté en el repositorio, con suerte LF( \n). Cualquiera CRLFse convertirá a solo LFen el registro.

Con un repositorio existente que ya ha extraído, que tiene las terminaciones de línea correctas en el repositorio pero no su copia de trabajo, puede ejecutar los siguientes comandos para solucionarlo:

git rm -rf --cached .
git reset --hard HEAD

Esto eliminará ( rm) recursivamente ( r) sin prompt ( -f), todos los archivos excepto los que ha editado ( --cached), desde el directorio actual ( .). losreset continuación, se recuperan todos los archivos a un estado en el que tienen sus verdaderos finales de línea (que coinciden con lo que hay en el repositorio).

Si necesita arreglar las terminaciones de línea de los archivos en un repositorio, le recomiendo que tome un editor que le permita hacerlo de forma masiva como IntelliJ o Sublime Text, pero estoy seguro de que cualquiera bueno lo admitirá.

Ben Liyanage
fuente
1
Tenemos un repositorio único con subdirectorios que requieren un manejo de final de línea diferente. Por lo tanto, establecer una opción global no funciona para esto. Ni siquiera en el repositorio individual. ¿Cómo se aplican estas mismas configuraciones en .gitattributes?
RobG
Notepad++también muestra el final de línea del archivo abierto en la esquina inferior derecha. Un clic derecho en ese campo le permitirá cambiar las terminaciones de línea.
winklerrr
1
La core.autocrlf inputopción anula la core.eolconfiguración, por lo que la configuración de ambos es redundante. (Ver git-scm.com/docs/git-config )
Andrew Marshall
1
Gracias, con tu ayuda he conquistado pelusa y Linux. Y ahora puede registrar archivos.
GC_
57

Contexto

Si tu

  1. desea obligar a todos los usuarios a tener terminaciones de línea LF para archivos de texto y
  2. no puedes asegurarte de que todos los usuarios cambien su configuración de git,

puedes hacerlo comenzando con git 2.10. Se requiere 2.10 o posterior, porque 2.10 arregló el comportamiento de text = auto junto con eol = lf . Fuente .

Solución

Coloque un .gitattributesarchivo en la raíz de su repositorio git que tenga los siguientes contenidos:

* text=auto eol=lf

Compromételo

Ajustes opcionales

También puede agregar una .editorconfigen la raíz de su repositorio para asegurarse de que las herramientas modernas crean nuevos archivos con las terminaciones de línea deseadas.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
koppor
fuente
3
Esta fue la mejor solución para mí. También combiné esto con editorconfig.org para que cuando escribiera en Intellij escribiera LF EOLs.
Jazzepi
Esta es, de lejos, la mejor solución. ¡No es necesario ejecutar manualmente ningún comando de configuración!
Cameron Tacklind
26

core.autocrlf=inputes la configuración correcta para lo que desea, pero es posible que tenga que hacer ay git update-index --refresh/ o git reset --hardpara que el cambio surta efecto.

Con core.autocrlfset to input, git no aplicará la conversión de nueva línea al finalizar la compra (por lo tanto, si tiene LF en el repositorio, obtendrá LF), pero se asegurará de que en caso de que se equivoque e introduzca algunos CRLF en funcionamiento copia de alguna manera, no entrarán en el repositorio.

kusma
fuente
19
Los comandos deben ser git rm --cached -r. && git reset --hard
koppor
0

Puede encontrar la solución a este problema en: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Descripción simplificada de cómo puede resolver este problema en Windows:

Configuración global para finales de línea El comando git config core.autocrlf se usa para cambiar cómo Git maneja las terminaciones de línea. Se necesita un solo argumento.

En Windows, simplemente pasa fiel a la configuración. Por ejemplo: C:> git config --global core.autocrlf true

Buena suerte, espero haberte ayudado.

c-santana
fuente