Pregunta

Me ha molestado el problema de final de línea de Windows/Linux con git.Parece, a través de GitHub, MSysGit y otras fuentes, que la mejor solución es configurar sus repositorios locales para usar finales de línea de estilo Linux, pero configurar core.autocrlf a true.Desafortunadamente, no hice esto con suficiente antelación, por lo que ahora, cada vez que hago cambios, los finales de línea se modifican.

Pensé que había encontrado una respuesta aquí pero no consigo que funcione para mí.Mi conocimiento de la línea de comandos de Linux es, en el mejor de los casos, limitado, por lo que ni siquiera estoy seguro de qué hace la línea "xargs fromdos" en su script.Sigo recibiendo mensajes acerca de que no existe tal archivo o directorio, y cuando logro señalarlo a un directorio existente, me dice que no tengo permisos.

Probé esto con MSysGit en Windows y mediante la terminal Mac OS X.

¿Fue útil?

Solución

La documentación git para gitattributes ahora documenta otro enfoque para "fijar" o la normalización de toda la línea terminaciones en su proyecto. Aquí está el quid de la cuestión:

$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status        # Show files that will be normalized
$ git commit -m "Introduce end-of-line normalization"
  

Si los archivos que no se debe   normalizado aparecer en git status,   desarmar su atributo de texto antes   ejecutar git add -u.

     

manual.pdf -text

     

A la inversa, archivos de texto que hace git   No puede tener detectar la normalización   habilitado manualmente.

     

weirdchars.txt text

Esto aprovecha una nueva bandera --renormalize añadido en v2.16.0 git, publicado Ene 2018. Para versiones anteriores de Git, hay algunos más pasos:

$ echo "* text=auto" >>.gitattributes
$ rm .git/index     # Remove the index to force git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

Otros consejos

La forma más fácil de solucionar este problema es hacer un commit que corrige todos los finales de línea. Suponiendo que usted no tiene los archivos modificados, entonces usted puede hacer esto de la siguiente manera.

# From the root of your repository remove everything from the index
git rm --cached -r .

# Change the autocrlf setting of the repository (you may want 
#  to use true on windows):
git config core.autocrlf input

# Re-add all the deleted files to the index
# (You should get lots of messages like:
#   warning: CRLF will be replaced by LF in <file>.)
git diff --cached --name-only -z | xargs -0 git add

# Commit
git commit -m "Fixed crlf issue"

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .

Mi procedimiento para tratar con los finales de línea es la siguiente (batalla probado en muchos repos):

Cuando se crea una nueva operación:

  • .gitattributes poner en el primer cometer junto con otros archivos típicos como .gitignore y README.md

Cuando se trata de una cesión temporal existente:

  • Crear / modificar en consecuencia .gitattributes
  • git commit -a -m "Modified gitattributes"
  • git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
    • -n (--no-verify es saltarse pre-cometer ganchos)
    • Tengo que hacerlo con la suficiente frecuencia que he definido como un alias fixCRLF="..." alias
  • repetir el comando anterior
    • Sí, es vudú, pero en general tengo que ejecutar el comando dos veces, la primera vez que normaliza algunos archivos, por segunda vez, incluso más archivos. En general, es probablemente mejor que repetir hasta que no se crea nuevo commit:)
  • volver atrás y hacia adelante entre las viejas (justo antes de la normalización) y la nueva rama de un par de veces. Después de cambiar la rama, a veces git encontrar aún más archivos que necesitan ser renormalizado!

En .gitattributes Declaro todos los archivos de texto de forma explícita como tener LF EOL ya que generalmente las herramientas de Windows es compatible con LF, mientras que no es de Windows herramientas no es compatible con CRLF (incluso muchas herramientas de línea de comando nodejs asumen LF y por lo tanto, puede cambiar la EOL en sus archivos).

Contenido de .gitattributes

Mi .gitattributes general se parece a:

*.html eol=lf
*.js   eol=lf
*.json eol=lf
*.less eol=lf
*.md   eol=lf
*.svg  eol=lf
*.xml  eol=lf

Para averiguar qué extensiones distintas son rastreados por git en el repositorio actual, mira aquí

Problemas después de la normalización

Una vez hecho esto, hay una advertencia más común sin embargo.

Digamos que su master ya está en marcha al día y normalizado, y luego outdated-branch pago y envío. Muy a menudo justo después de la salida de esa rama, git marca tantos archivos como modificado.

La solución es hacer una falsificación cometer (git add -A . && git commit -m 'fake commit') y luego git rebase master. Después de que el rebase, la falsa cometer debe desaparecer.

git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos

Explicación:

  • git status --short

    Esto muestra cada línea que git es y no es consciente de. Los archivos que no están bajo el control git están marcados al comienzo de la línea con un '?'. Los archivos que se modificaron están marcados con una M.

  • grep "^ *M"

    Esta filtra sólo aquellos archivos que han sido modificados.

  • awk '{print $2}'

    Esta muestra sólo el nombre de archivo sin marcadores.

  • xargs fromdos

    Esto toma los nombres de archivo de la orden anterior y los ejecuta a través de 'fromdos' la utilidad para convertir los finales de línea.

Así es como arreglé todos los finales de línea en todo el historial usando git filter-branch.El ^M El carácter debe ingresarse usando CTRL-V + CTRL-M.solía dos2unix para convertir los archivos ya que esto omite automáticamente los archivos binarios.

$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'

Los "| xargs fromdos" lee desde la entrada estándar (archivos del find encuentra) y lo utiliza como argumentos para el comando fromdos, que convierte los finales de línea. (Is fromdos estándar en esos ambientes? Estoy acostumbrado a dos2unix). Tenga en cuenta que se puede evitar el uso de xargs (especialmente útil si tiene suficientes archivos que la lista de argumentos es demasiado largo para xargs):

find <path, tests...> -exec fromdos '{}' \;

o

find <path, tests...> | while read file; do fromdos $file; done

No estoy totalmente seguro acerca de sus mensajes de error. I probado con éxito este método. ¿Qué programa está produciendo cada uno? ¿Qué archivos / directorios es lo que no tiene permisos para? Sin embargo, aquí está una puñalada en adivinar lo que su podría ser:

Una manera fácil de obtener un error 'archivo no encontrado' para la secuencia de comandos es mediante el uso de una ruta relativa - utilizar un absoluto. Del mismo modo se puede obtener un error de permisos si no lo ha hecho su script ejecutable (chmod + x).

Añadir comentarios y voy a tratar de ayudarle a trabajar hacia fuera!

bien ... bajo Cygwin no tenemos fromdos fácilmente disponibles, y que substeb awk golpes en la cara si tiene espacios en rutas a los archivos modificados (que teníamos), así que tuve que hacer eso un poco de otra manera:

git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix

felicitaciones a @lloyd para la mayor parte de esta solución

Siga estos pasos si ninguno de otras respuestas que funciona para usted:

  1. Si está en Windows, haga git config --global core.autocrlf true; si usted está en Unix, hacer git config core.autocrlf input
  2. git rm --cached -r . Ejecutar
  3. Eliminar el archivo .gitattributes
  4. git add -A Ejecutar
  5. git reset --hard Ejecutar

A continuación, el local debe estar limpio ahora.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top