Получение читаемых различий отображается в Mercurial на Unicode-файлах (MS Windows) - PullRequest
24 голосов
/ 10 июня 2010

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

Ответы [ 3 ]

3 голосов
/ 15 ноября 2010

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

Я не уверен, что это то, что вам нужно, но мне нужны различия в содержании 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, но я ожидаю, что он будет лучше, чем командная строка, для поддержки произвольных нулевых байтов в командной строке.

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

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

2 голосов
/ 14 ноября 2010

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

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

1 голос
/ 15 ноября 2010

Если мой другой ответ не делает то, что вы хотите, я думаю, что этот может;хотя я еще не тестировал его на 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'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

In .hgrc:

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

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

...