windows unicode mercurial diff tortoisehg

Obtiene visualizaciones de diff legibles en Mercurial en archivos Unicode(MS Windows)



tortoisehg (3)

He solucionado esto creando un nuevo archivo con NotePad ++ y guardándolo como un archivo de PowerShell (extensión .ps1). NotePad ++ creará el archivo como un archivo ANSI de texto sin formato. Una vez creado, puedo abrir el archivo en el editor de PowerShell y hacer los cambios necesarios sin que el editor modifique la codificación del archivo.

Descargo de responsabilidad: me encontré con esto hace unos momentos, por lo que no estoy seguro de si hay alguna repercusión, pero hasta ahora mis scripts parecen funcionar de manera normal y mis diferencias se muestran muy bien.

Intento almacenar algunos scripts de Windows PowerShell en un repositorio de Mercurial. Parece que al editor de PowerShell le gusta guardar archivos como UTF-16 Unicode. Esto significa que hay muchos /0 bytes, que es lo que Mercurial usa para distinguir entre archivos "de texto" y "binarios". Entiendo que esto no cambia la forma en que Mercurial almacena los datos, pero sí significa que muestra diferencias binarias, que son difíciles de leer. ¿Hay alguna manera de decirle a Mercurial que estos realmente son archivos de texto? Presumiblemente necesitaría convencer a Mercurial para que use un programa externo de diff compatible con Unicode para tipos de archivos particulares.


Si mi otra respuesta no hace lo que desea, creo que esta puede; aunque todavía no lo he probado en Windows, está funcionando bien en Linux. Hace lo que es potencialmente desagradable, al envolver mercurial.mdiff.unidiff con una nueva función que convierte utf-16le a utf-8. Esto no afectará hg st , pero afectará a hg diff . Una posible trampa es que la BOM también cambiará de la BOM UTF-16LE a la BOM UTF-8.

De todos modos, creo que puede ser útil para ti, así que aquí está.

Archivo de extensión utf16decodediff.py :

import codecs from mercurial import mdiff unidiff = mdiff.unidiff def new_unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=mdiff.defaultopts): """ A simple wrapper around mercurial.mdiff.unidiff which first decodes UTF-16LE text. """ if a.startswith(codecs.BOM_UTF16_LE): try: # Gets reencoded as utf-8 to be a str rather than a unicode; some # extensions may expect a str and may break if it''s wrong. a = a.decode(''utf-16le'').encode(''utf-8'') except UnicodeDecodeError: pass if b.startswith(codecs.BOM_UTF16_LE): try: b = b.decode(''utf-16le'').encode(''utf-8'') except UnicodeDecodeError: pass return unidiff(a, ad, b, bd, fn1, fn2, r, opts) mdiff.unidiff = new_unidiff

En .hgrc :

[extensions] utf16decodediff = ~/.hgexts/utf16decodediff.py

(O caminos equivalentes)


Esto puede no ser relevante para usted; lea el último párrafo si no suena como es.

No estoy seguro de si esto es lo que necesita, pero he necesitado diffs con contenido UTF-16LE más que solo "los archivos binarios son diferentes", cuando busqué hace algunos meses, encontré un hilo y error al discutirlo; aquí hay una parte . No puedo encontrar la fuente original de esta mini-extensión ahora (aunque está haciendo exactamente lo que hace ese parche), pero lo que obtuve fue una extensión, BOM.py :

#!/usr/bin/env python from mercurial import hg, util import codecs boms = [ codecs.BOM_UTF8, codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE, codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE ] def binary(s): if s: for bom in boms: if s.startswith(bom): return False return ''/0'' in s return False def reposetup(ui, repo): util.binary = binary

Esto se carga en .hgrc (o tus usuarios / nombre de usuario / mercurial.ini) de esta manera:

[extensions] bom = ~/.hgexts/BOM.py

Tenga en cuenta que la ruta variará entre Windows y Linux; en mi copia de Windows coloco la ruta como /.../whatever (está en un disco USB donde la letra de la unidad puede cambiar). Lamentablemente, las rutas relativas se toman en relación con el directorio de trabajo actual en lugar de la raíz del repositorio o cualquier cosa similar, pero si lo está guardando en su unidad C: puede simplemente poner la ruta completa.

En Linux (mi entorno de desarrollo principal), esto funciona bien; en el símbolo del sistema (que todavía uso regularmente), generalmente funciona bien. Nunca lo intenté en PowerShell, pero espero que sea mejor que Command Prompt en su soporte para bytes nulos arbitrarios en la línea de comando.

No estoy seguro de si esto es lo que quieres en absoluto; por cierto, usted ha dicho "diferencias binarias", sospecho que ya puede tener esto o estar haciendo hg diff -a que está logrando lo mismo. En ese caso, todo lo que puedo pensar es escribir otra extensión que tome el UTF-16LE e intente descifrarlo en UTF-8. No estoy seguro de la sintaxis para dicha extensión, pero podría intentarlo.

Editar: ahora que ha rastreado la fuente mercurial a través de commands.py, cmdutil.py, patch.py ​​y mdiff.py, veo que las diferencias binarias se realizan con una codificación base85 (patch.b85diff) en lugar de la diferencia normal. No estaba al tanto de eso, pensé que solo lo forzaba a diferirlo. En ese caso, tal vez este texto sea relevante después de todo. ¡Espero una respuesta para ver si lo es!