Подтвердить что ты не робот

Получение читаемых дисплеев diff в Mercurial в файлах Unicode (MS Windows)

Я пытаюсь сохранить некоторые сценарии Windows PowerShell в репозитории Mercurial. Кажется, редактор PowerShell любит сохранять файлы как Unicode UTF-16. Это означает, что существует много байтов \0, что Mercurial использует для различения "текстовых" и "двоичных" файлов. Я понимаю, что это не имеет никакого значения, как Mercurial хранит данные, но это означает, что он отображает двоичные разности, которые трудно читать. Есть ли способ сказать Mercurial, что это действительно текстовые файлы? Предположительно, мне нужно будет убедить Mercurial использовать внешнюю Unicode-совместимую программу diff для определенных типов файлов.

4b9b3361

Ответ 1

Это не относится к вам; прочитайте последний абзац, если он не похож на него.

Я не уверен, что это то, что вам нужно, но мне нужно было разграничить содержимое UTF-16LE больше, чем просто "двоичные файлы разные" - когда я искал несколько месяцев назад, я нашел поток и ошибка, обсуждающая его; здесь часть. Я не могу найти исходный источник этого мини-расширения (хотя он делает именно то, что делает этот патч), но я получил расширение, 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

Это загружается в .hgrc(или ваши пользователи \username\mercurial.ini) следующим образом:

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

Обратите внимание, что путь будет отличаться между Windows и Linux; на моей копии Windows я поместил путь как \...\whatever (он на USB-диске, где буква диска может измениться). К сожалению, относительные пути берутся относительно текущего рабочего каталога, а не корня репозитория или любой такой вещи, но если вы сохраняете его на своем диске C: вы можете просто поместить полный путь.

В Linux (моя основная среда разработки) это работает хорошо; в командной строке (который я все еще использую регулярно), он обычно работает хорошо. Я никогда не пробовал это в PowerShell, но я ожидал бы, что это будет лучше, чем Command Prompt в его поддержке произвольных нулевых байтов в командной строке.

Я не уверен, что это то, чего вы хотите вообще; кстати, вы сказали "двоичные различия". Я подозреваю, что вы уже можете либо иметь это, либо делать hg diff -a, который достигает того же самого. В этом случае все, что я могу представить, это написать другое расширение, которое берет UTF-16LE и пытается его декодировать в UTF-8. Я не уверен в синтаксисе для такого расширения, но я мог бы попробовать это.

Изменить:, теперь травляя источник mercurial с помощью команд .py, cmdutil.py, patch.py ​​и mdiff.py, я вижу, что двоичные разности выполняются с помощью кодировки base85 (patch.b85diff), а не нормальный diff. Я не знал об этом, я думал, что это просто заставило его разобраться. В этом случае, возможно, этот текст имеет значение в конце концов. Я жду ответа, чтобы убедиться, что это!

Ответ 2

Я работал над этим, создав новый файл с NotePad ++ и сохраняя его как файл PowerShell (расширение .ps1). NotePad ++ создаст файл как обычный ANSI файл. После создания я могу открыть файл в редакторе PowerShell и внести необходимые изменения, если редактор не изменил кодировку файла.

Отказ от ответственности: я столкнулся с этим всего несколько минут назад, и поэтому я не уверен, есть ли какие-либо последствия, но до сих пор мои сценарии работают нормально, и мои различия проявляются хорошо.

Ответ 3

Если мой другой ответ не сделает то, что вы хотите, я думаю, что это возможно; хотя я еще не тестировал его на Windows, но он хорошо работает в Linux. Он делает то, что потенциально является неприятным, обертывая mercurial.mdiff.unidiff новой функцией, которая преобразует utf-16le в utf-8. Это не повлияет на hg st, но повлияет на hg diff. Одна потенциальная ошибка заключается в том, что спецификация также будет изменена с спецификации UTF-16LE на спецификацию UTF-8.

В любом случае, я думаю, что это может быть полезно для вас, так что вот оно.

Файл расширения 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 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

В .hgrc:

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

(или эквивалентные пути.)