tag remove qué practices oneline log hace crear best git unicode character-encoding diff utf-16

remove - ¿Puedo hacer que Git reconozca un archivo UTF-16 como texto?



git tag best practices (6)

¿Has intentado configurar tus .gitattributes para tratarlo como un archivo de texto?

p.ej:

*.vmc diff

Más detalles en http://www.git-scm.com/docs/gitattributes.html .

Estoy rastreando un archivo de máquina virtual de Virtual PC (* .vmc) en git, y después de hacer un cambio, git identificó el archivo como binario y no lo haría por mí. Descubrí que el archivo estaba codificado en UTF-16.

¿Se puede enseñar a Git reconocer que este archivo es texto y manejarlo apropiadamente?

Estoy usando git en Cygwin, con core.autocrlf establecido en falso. Podría usar mSysGit o git en UNIX, si es necesario.


Hay una solución muy simple que funciona de forma predeterminada en Unices.

Por ejemplo, con los archivos .strings de Apple solo:

  1. Cree un archivo .gitattributes en la raíz de su repositorio con:

    *.strings diff=localizablestrings

  2. Agregue lo siguiente a su archivo ~/.gitconfig :

    [diff "localizablestrings"] textconv = "iconv -f utf-16 -t utf-8"

Fuente: archivos Diff .strings en Git (y publicaciones anteriores desde 2010).


He escrito un pequeño controlador git-diff, to-utf8 , que debería facilitar la diferenciación de cualquier archivo no codificado en ASCII / UTF-8. Puede instalarlo usando las instrucciones aquí: https://github.com/chaitanyagupta/gitutils#to-utf8 (el script to-utf8 está disponible en el mismo repositorio).

Tenga en cuenta que este script requiere que los comandos file e iconv estén disponibles en el sistema.


He estado luchando con este problema por un tiempo, y acabo de descubrir (para mí) una solución perfecta:

$ git config --global diff.tool vimdiff # or merge.tool to get merging too! $ git difftool commit1 commit2

git difftool toma los mismos argumentos que git diff would, pero ejecuta un programa de diferencias de su elección en lugar del diff GNU incorporado. Así que elija un diff multibyte-aware (en mi caso, vim en modo diff) y simplemente use git difftool lugar de git diff .

Encuentra "difftool" demasiado tiempo para escribir? No hay problema:

$ git config --global alias.dt difftool $ git dt commit1 commit2

Git rocas.


La solución es filtrar a través de cmd.exe /c "type %1" . El type interno de cmd hará la conversión, por lo que puede usarlo con la habilidad textconv de git diff para habilitar la diferencia de texto de los archivos UTF-16 (también debería funcionar con UTF-8, aunque no probado).

Citando de la página del manual de gitattributes:

Realizar diffs de texto de archivos binarios

Algunas veces es deseable ver la diferencia de una versión convertida por texto de algunos archivos binarios. Por ejemplo, un documento de procesador de textos se puede convertir a una representación de texto ASCII y la diferencia del texto que se muestra. Aunque esta conversión pierde cierta información, la diferencia resultante es útil para la visualización humana (pero no se puede aplicar directamente).

La opción de configuración textconv se usa para definir un programa para realizar dicha conversión. El programa debe tomar un solo argumento, el nombre de un archivo para convertir, y producir el texto resultante en stdout.

Por ejemplo, para mostrar la diferencia de la información exif de un archivo en lugar de la información binaria (suponiendo que tiene instalada la herramienta exif), agregue la siguiente sección a su $GIT_DIR/config (o archivo $HOME/.gitconfig ):

[diff "jpg"] textconv = exif

Una solución para mingw32 , los fans de cygwin pueden tener que modificar el enfoque. El problema es pasar el nombre del archivo para convertirlo a cmd.exe; usará barras diagonales, y cmd asume separadores del directorio barra invertida.

Paso 1:

Cree el script de un solo argumento que hará la conversión a stdout. c: / path / to / some / script.sh:

#!/bin/bash SED=''s/////////////g'' FILE=/`echo $1 | sed -e "$SED"/` cmd.exe /c "type $FILE"

Paso 2:

Configure git para poder usar el archivo de script. Dentro de su configuración de git ( ~/.gitconfig o .git/config o vea man git-config ), ponga esto:

[diff "cmdtype"] textconv = c:/path/to/some/script.sh

Paso 3:

Señale los archivos para aplicar este trabajo a mediante la utilización de archivos .gitattributes (vea man gitattributes (5)):

*vmc diff=cmdtype

luego usa git diff en tus archivos.


Por defecto, parece que git no funcionará bien con UTF-16; para dicho archivo, debe asegurarse de que no se realiza ningún procesamiento CRLF , pero desea que diff y merge funcionen como un archivo de texto normal (esto ignora si su terminal / editor puede manejar UTF-16).

Pero mirando la página de .gitattributes , aquí está el atributo personalizado que es binary :

[attr]binary -diff -crlf

Por lo tanto, me parece que podría definir un atributo personalizado en su nivel superior .gitattributes para utf16 (tenga en cuenta que agrego fusión aquí para asegurarse de que se trata como texto):

[attr]utf16 diff merge -crlf

Desde allí, podrá especificar en cualquier archivo .gitattributes algo así como:

*.vmc utf16

También tenga en cuenta que todavía debe ser capaz de diff un archivo, incluso si git piensa que es binario con:

git diff --text

Editar

Esta respuesta básicamente dice que GNU diff wth UTF-16 o incluso UTF-8 no funciona muy bien. Si quieres que git use una herramienta diferente para ver las diferencias (a través de --ext-diff ), esa respuesta sugiere a Guiffy .

Pero lo que probablemente necesite es simplemente diff un archivo UTF-16 que contiene solo caracteres ASCII. Una forma de hacer que eso funcione es usar --ext-diff y el siguiente script de shell:

#!/bin/bash diff <(iconv -f utf-16 -t utf-8 "$1") <(iconv -f utf-16 -t utf-8 "$2")

Tenga en cuenta que la conversión a UTF-8 también podría funcionar para la fusión, solo tiene que asegurarse de que se realice en ambas direcciones.

En cuanto a la salida al terminal cuando se mira un diff de un archivo UTF-16:

Tratar de diferir de esa manera da como resultado basura binaria arrojada a la pantalla. Si git está usando GNU diff, parecería que GNU diff no es consciente de unicode.

GNU diff realmente no se preocupa por el Unicode, así que cuando usas diff --text solo diffs y saca el texto. El problema es que el terminal que está utilizando no puede manejar el UTF-16 que se emite (combinado con las marcas de diferencia que son caracteres ASCII).