Я пытаюсь сохранить скрипты Windows PowerShell в репозитории Mercurial. Похоже, что редактор PowerShell любит сохранять файлы как UTF-16 Unicode. Это означает, что существует много \0
байтов, которые Mercurial использует, чтобы различать «текстовые» и «двоичные» файлы. Я понимаю, что это не имеет значения для того, как Mercurial хранит данные, но это означает, что он отображает двоичные различия, которые довольно трудно читать. Есть ли способ сообщить Mercurial, что это действительно текстовые файлы? По-видимому, мне нужно было бы убедить Mercurial использовать внешнюю программу сравнения с Unicode для определенных типов файлов.
Получение удобочитаемых дисплеев различий в Mercurial в файлах Unicode (MS Windows)
Ответы (3)
Возможно, это не имеет отношения к вам; прочтите последний абзац, если он не звучит так, как есть.
Я не уверен, что это то, что вам нужно, но мне нужны различия с содержимым 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 (или в ваши users \ 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. Я не знал об этом, я думал, что это просто заставило его изменить это. В таком случае, возможно, этот текст все-таки уместен. Жду ответа, чтобы убедиться, что это так!
qnew
.
- person jwd; 12.06.2012
Я работал над этим, создав новый файл с помощью NotePad ++ и сохранив его как файл PowerShell (с расширением .ps1). NotePad ++ создаст файл как обычный текстовый файл ANSI. После создания я могу открыть файл в редакторе PowerShell и внести необходимые изменения без изменения редактором кодировки файла.
Отказ от ответственности: я столкнулся с этим всего несколько минут назад, поэтому я не уверен, есть ли какие-либо последствия, но пока мои скрипты работают нормально, а мои различия отображаются хорошо.
Если мой другой ответ не дает того, что вы хотите, я думаю, что это возможно; хотя я еще не тестировал его в 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
(Или эквивалентные пути.)
--config diff.nobinary=True
(по личному опыту я знаю, что это испортит патчи mq, поэтому я не рекомендую постоянно держать его включенным), чтобы добраться до оболочки.
- person bambams; 05.11.2015
if isinstance(a, str):
и if isinstance(b, str)
, потому что при выполнении сравнения, когда в одной версии отсутствуют файлы, в другой есть эти переменные, могут быть NoneType и вызывать сбой расширения mercurial
- person Scoopta; 23.08.2017