Reescribiendo el historial de git para hacer que el crlf sea consistente

Tengo un repository git que tiene una fina variación de files LF y CRLF.

Antes de hacer un posible cambio, quiero reescribir commits donde el padre y el commit actual tienen diferentes codificaciones LR / CRLF.

Así que probé el siguiente "one-liner" (ligeramente editado) donde trato de ejecutar todos si la versión principal de un file contiene un CR.

 $ git filter-branch --tree-filter ' echo P=$GIT_COMMIT^; FILES=$(git diff --name-only $P); for a in $FILES; do if ! git cat-file -e $P:$a; then echo "no parent"; continue; fi; if git show $:$a | grep -qUP '\r'; then echo "parent is dos"; todos $a; else echo "parent is unix"; fromdos $a; fi; done' 23498f..HEAD 

No funciona ¿Alguien puede detectar el error o dar una solución a este problema?

Estoy respondiendo mi propia pregunta. El error en mi solución original es que el set de FILES está equivocado porque la diferencia no se toma entre el padre reescrito y la confirmación actual, sino entre el padre original y la confirmación actual.

Al recorrer un set de confirmaciones como este, los files que deben modificarse no son el set de files afectados por una confirmación, sino también el set de files en los que algunos padres cometen errores en las terminaciones de línea.

Esto significa que no obtengo el set correcto de files. Hay una function de map proporcionada a las expresiones de la twig de filter que puede transformar una revolución "original" en la revolución reescrita. Cuando uso esa function, funciona correctamente.

El resultado "one-liner" se ve así:

 $ git filter-branch -f --tree-filter ' echo "\n $GIT_COMMIT"; P=$(git rev-parse $GIT_COMMIT^); echo $P; P=$(map $P); echo $P; git cat-file commit $GIT_COMMIT; FILES=$(git diff --name-only $GIT_COMMIT $P); echo "FILES:\n$FILES"; for a in $FILES; do git cat-file -e $P:$a > /dev/null 2>&1 || continue; if git show $P:$a | grep -qUP '\r'; then echo "parent is dos $a"; todos $a; else echo "parent is unix $a"; fromdos $a; fi; done; git add $FILES;' a6d9e..HEAD 

La mayoría de las respuestas no creo que se necesite el último 'git add $ FILES', pero ese es el command que utilicé y no deseo proporcionar una respuesta incorrecta.

Nota: También debería ser posible definir FILES=$(git diff --name-only a6d9e HEAD) y, por lo tanto, usar un set fijo al atravesar las confirmaciones. Eso es probablemente mucho más simple, pero yo no hice eso.

¿Realmente quieres volver a escribir la historia?

Usar la opción de configuration incorporada ayuda a que estas cosas sean transparentes. He hecho algo similar a esto, y durante los últimos años, trabajar con personas en sistemas Windows, Mac y Linux aún no ha tenido un problema con los finales de línea.

Mira cómo lidiar con los finales de línea de GitHub.

Esto es lo que tienen que decir sobre los files de configuration:

Aquí hay un ejemplo de file .gitattributes, puede usarlo como plantilla para todos sus repositorys:

 # Set default behaviour, in case users don't have core.autocrlf set. * text=auto # Explicitly declare text files we want to always be normalized and converted # to native line endings on checkout. *.c text *.h text # Declare files that will always have CRLF line endings on checkout. *.sln text eol=crlf # Denote all files that are truly binary and should not be modified. *.png binary *.jpg binary The advantage of this is that your end of line configuration now travels with your repository and you don't need to worry about whether or not collaborators have the proper global settings. 

Continúan hablando acerca de lo que puede hacer si tiene un repository actual y necesita aplicar esta configuration.

Re-normalización de un repository

Una vez que haya configurado la opción core.autocrlf y haya asignado un file .gitattributes, es posible que git desee confirmar los files que no haya modificado. Esto es porque git quiere normalizar los finales de línea para ti. La mejor manera de hacerlo es borrar su tree de trabajo (todos los files excepto el directory .git) y luego restaurarlos. Asegúrese de haber realizado algún trabajo antes de hacer esto, o se perderá.

 git rm --cached -r . # Remove everything from the index. git reset --hard # Write both the index and working directory from git's database. git add . # Prepare to make a commit by staging all the files that will get normalized. # This is your chance to inspect which files were never normalized. You should # get lots of messages like: "warning: CRLF will be replaced by LF in file." git commit -m "Normalize line endings" # Commit 
    Intereting Posts