Не могу заставить Git хорошо играть с iconv и utf-16

Я пытаюсь заставить git распознавать UTF-16 как текст, чтобы я мог различать и исправлять текст как исходный, но у меня возникают проблемы с получениемtextconv параметр для работы.

Я могу вручную позвонить

iconv -f utf-16 -t utf-8 some-utf-16-file.rc

и все хорошо. Но если я настрою свой .gitconfig следующим образом

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

и мои .gitattributes:

# Custom for MFC
*.rc text eol=crlf diff=utf16

Однако, если я тогда, если я бегуgit diffотображается следующее:

iconv: C:/Users/Mahmoud/AppData/Local/Temp/IjLBZ8_OemKey.rc:104:1: incomplete character or shift sequence

С procmon я смог отследить это как создание этого процесса:

sh -c "iconv.exe -f utf-16le -t utf-8 \"[email protected]\"" "iconv.exe -f utf-16le -t utf-8" C:/Users/Mahmoud/AppData/Local/Temp/JLOkVa_OemKey.rc

... который я действительно могу запустить нормально (хотя на самом файле).

Есть идеи?

(Обратите внимание, что я знаю о различных решениях для того, чтобы заставить git работать с UTF-16. Я специально пытаюсь ответить на этот вопрос, почему iconv сам по себе работает, но он не будет работать при вызове git. Кроме того, это Первоначально возникла ошибка при попытке одного из связанных решений из «дублирующего» вопроса. Спасибо всем вам.)

 paulsm404 июн. 2016 г., 21:05
В противном случае вы всегда можете сделать все под Linux :)
 Briana Swift04 июн. 2016 г., 20:08
Не уверен насчет этого - может ли это быть связано с тем, что iconv.exe является двоичным?
 Roman05 июн. 2016 г., 06:19
Может ли быть так, что git перезаписывает символы конца строки (которые портят utf-16) перед тем, как передать этот файл iconv?
 Mahmoud Al-Qudsi04 июн. 2016 г., 19:23
@ paulsm4 Мой вопрос на самом деле касается того, чтобы git и iconv работали хорошо, а не о том, чтобы заставить git работать с UTF-16; но спасибо!
 Mahmoud Al-Qudsi04 июн. 2016 г., 20:39
@Briana Я так не думаю, sysmon показывает, что все в порядке.
 paulsm404 июн. 2016 г., 21:02
Помните - из «командной строки» DOS / Windows, есть целая куча разных участников: включая Cygwin и Windows. Пожалуйста, прочитайте ссылки, которые я цитировал: «GNU diff на самом деле не заботится о юникоде, поэтому, когда вы используете diff --text, он просто переводит и выводит текст. Проблема в том, что используемый вами терминал не может обрабатывать UTF -16, что испускается (в сочетании с метками diff, которые являются символами ASCII). " И, пожалуйста, прочитайтемножественный разные обходные пути.

Ответы на вопрос(3)

iconv сейчас в какой-то степени встроен. Увидетьgitattributes документы, поискworking-tree-encoding

[Убедитесь, что ваша страница справочника соответствует, так как это совершенно новый!]

Если (скажем) файл на компьютере с операционной системой Windows - utf-16 без bom, добавьте его в файл gitattributes

some-utf-16-file.rc text working-tree-encoding=UTF-16LE eol=CRLF

Если utf-16 маленький endinan (с бомбой) на * nix, сделайте это

some-utf-16-file.rc text working-tree-encoding=UTF-16 eol=LF
 Mahmoud Al-Qudsi14 февр. 2019 г., 08:35
Спасибо за это обновление! Я предполагаю, что это будет работать с интерактивным патчем, так что это очень приветствуется!
Решение Вопроса

Использовать толькоdiff, он должен работать:

*.rc diff=utf16

text а такжеeol заставить git подставлять конец строк перед передачей данных в iconv, после чего он больше не является допустимым utf16, так какотмечено в комментариях.

 Mahmoud Al-Qudsi09 июн. 2016 г., 13:09
Благодарим вас за то, что вы объяснили причину проблемы и предоставили решение для продолжения использования попыток (но правильно). Жаль, что это не может работать с интерактивом / патчемgit add, но это невозможно, поскольку не существует гарантированного взаимно-однозначного сопоставления между отфильтрованным представлением и исходными материалами.

UTF-16LE-BOM: изобретен для принудительного кодирования в UTF-16 с BOM в порядке байтов с прямым порядком байтов, который не может быть напрямую сгенерирован с помощьюiconv.

Увидетьсовершить aab2a1a (30 января 2019 г.)Торстен Бёгерсхаузен (tboegi).
(ОбъединеноJunio ​​C Hamano -gitster - всовершить 0fa3cc707 февраля 2019 г.)

Поддержка рабочего дерева кодирования "UTF-16LE-BOM"

Пользователи, которые хотят файлы UTF-16 в рабочем дереве, устанавливают.gitattributes как это:

test.txt working-tree-encoding=UTF-16

Сам стандарт Unicode определяет 3 допустимых способа кодирования UTF-16. Следующие 3 версии преобразуют все обратно в 'g' 'i' 't' в UTF-8:

a) UTF-16, without BOM, big endian:
$ printf "\000g\000i\000t" | iconv -f UTF-16 -t UTF-8 | od -c
0000000    g   i   t

b) UTF-16, with BOM, little endian:
$ printf "\377\376g\000i\000t\000" | iconv -f UTF-16 -t UTF-8 | od -c
0000000    g   i   t

c) UTF-16, with BOM, big endian:
$ printf "\376\377\000g\000i\000t" | iconv -f UTF-16 -t UTF-8 | od -c
0000000    g   i   t

Git используетlibiconv конвертировать из UTF-8 в индексе в ITF-16 в рабочем дереве.
После проверки полученный файл имеет спецификацию и закодирован в «UTF-16» в версии (с) выше.
Это то, что генерирует iconv, более подробная информация приведена ниже.

iconv (а такжеlibiconv) может генерировать UTF-16, UTF-16LE или UTF-16BE:

d) UTF-16
$ printf 'git' | iconv -f UTF-8 -t UTF-16 | od -c
0000000  376 377  \0   g  \0   i  \0   t

e) UTF-16LE
$ printf 'git' | iconv -f UTF-8 -t UTF-16LE | od -c
0000000    g  \0   i  \0   t  \0

f)  UTF-16BE
$ printf 'git' | iconv -f UTF-8 -t UTF-16BE | od -c
0000000   \0   g  \0   i  \0   t

Нет способа генерировать версию (b) сверху в рабочем дереве Git, но это то, что нужно некоторым приложениям.
(Все полностью поддерживающие Unicode приложения должны быть в состоянии прочитать все 3 варианта, но на практике мы еще не там).

При производстве UTF-16 в качестве выхода,iconv генерирует версию с прямым порядком байтов с помощью спецификации. (big endian, вероятно, выбран по историческим причинам).

iconv может создавать файлы UTF-16 с небольшим порядком байтов, используя в качестве кодировки «UTF-16LE», и этот файл не имеет спецификации.

Не все пользователи (особенно под Windows) довольны этим.
Некоторые инструменты не полностью поддерживают Unicode и могут работать только с версией (b).

Сегодня нет возможности произвести версию (б) сiconv (или жеlibiconv).
Изучая историюiconvкажется, что версия (с) будет использоваться во всех будущихiconv версии (по причинам совместимости).

Решить эту дилемму и представить Git-специфичные "UTF-16LE-BOM».
libiconv не может обработать кодировку, поэтому Git берет ее, обрабатывает BOM и использует libiconv для преобразования остальной части потока. (UTF-16BE-BOM добавлен для согласованности)

 VonC03 мар. 2019 г., 21:51

Ваш ответ на вопрос