Могу ли я сделать git распознать файл UTF-16 как текст?

Я отслеживаю файл виртуальной машины виртуального компьютера (*.vmc) в git, а после внесения изменений git идентифицировал файл как двоичный файл и не хотел его разграничить. Я обнаружил, что файл был закодирован в UTF-16.

Можно ли git узнать, что этот файл является текстом и соответствующим образом обрабатывает его?

Я использую git под Cygwin, при этом core.autocrlf устанавливается в false. Я мог бы использовать mSysGit или git под UNIX, если это необходимо.

Ответ 1

Я некоторое время боролся с этой проблемой и просто открыл (для меня) идеальное решение:

$ git config --global diff.tool vimdiff      # or merge.tool to get merging too!
$ git difftool commit1 commit2

git difftool принимает те же аргументы, что и git diff, но запускает программу diff по вашему выбору вместо встроенного GNU diff. Поэтому выберите diff с несколькими байтами (в моем случае vim в режиме diff) и просто используйте git difftool вместо git diff.

Найти "diffftool" слишком долго, чтобы печатать? Нет проблем:

$ git config --global alias.dt difftool
$ git dt commit1 commit2

Git.

Ответ 2

Существует очень простое решение, которое работает в блоке Unices.

Например, с файлами Apple .strings:

  • Создайте файл .gitattributes в корневом каталоге вашего репозитория с помощью

    *.strings diff=localizablestrings
    
  • Добавьте в свой файл ~/.gitconfig следующее:

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

Источник: Diff.strings файлы в Gitстарше пост с 2010 г.).

Ответ 3

Вы пытались настроить .gitattributes для обработки его как текстового файла?

например.:

*.vmc diff

Подробнее на http://www.git-scm.com/docs/gitattributes.html.

Ответ 4

По умолчанию это выглядит так: git не будет работать с UTF-16; для такого файла вам нужно убедиться, что обработка CRLF не выполняется, но вы хотите, чтобы diff и merge работали как обычный текстовый файл (это игнорирует, может ли ваш терминал/редактор обрабатывать UTF-16).

Но если посмотреть .gitattributes manpage, вот пользовательский атрибут binary:

[attr]binary -diff -crlf

Итак, мне кажется, что вы можете определить пользовательский атрибут на верхнем уровне .gitattributes для utf16 (обратите внимание, что я добавляю слияние здесь, чтобы убедиться, что он рассматривается как текст):

[attr]utf16 diff merge -crlf

Оттуда вы сможете указать в любом файле .gitattributes что-то вроде:

*.vmc utf16

Также обратите внимание, что вы все равно можете diff файл, даже если git считает его двоичным:

git diff --text

Edit

Этот ответ в основном говорит о том, что GNU diff UTF-16 или даже UTF-8 работает не очень хорошо. Если вы хотите, чтобы git использовал другой инструмент для просмотра различий (через --ext-diff), этот ответ предлагает Guiffy.

Но вам может понадобиться только diff файл UTF-16, содержащий только символы ASCII. Для этого нужно использовать --ext-diff и следующую оболочку script:

#!/bin/bash
diff <(iconv -f utf-16 -t utf-8 "$1") <(iconv -f utf-16 -t utf-8 "$2")

Обратите внимание, что преобразование в UTF-8 может работать и для слияния, вам просто нужно убедиться, что это сделано в обоих направлениях.

Что касается вывода на терминал при просмотре diff файла UTF-16:

Попытка разобраться с подобными результатами бинарный мусор, извергнутый на экране. Если git использует GNU diff, это похоже, что GNU diff не Юникод.

GNU diff действительно не заботится о юникоде, поэтому, когда вы используете diff -text, он просто различает и выводит текст. Проблема заключается в том, что используемый вами терминал не может обрабатывать выведенный UTF-16 (в сочетании с метками различий, которые являются символами ASCII).

Ответ 5

Решение состоит в фильтрации через cmd.exe /c "type %1". cmd type builtin выполнит преобразование, и поэтому вы можете использовать это с возможностью textconv для git diff, чтобы включить текст, различающий файлы UTF-16 (также должен работать с UTF-8, хотя и не проверен).

Цитата из справочной страницы gitattributes:


Выполнение текстовых различий двоичных файлов

Иногда желательно видеть разницу в текстовой версии некоторых двоичных файлов. Например, документ текстового процессора может быть преобразован в текстовое представление ASCII и отличается от отображаемого текста. Несмотря на то, что это преобразование теряет некоторую информацию, полученный diff полезен для просмотра человеком (но не может применяться непосредственно).

Параметр textconv config используется для определения программы для выполнения такого преобразования. Программа должна принимать один аргумент, имя файла для преобразования и создавать результирующий текст в стандартном файле.

Например, чтобы показать разницу между информацией exif файла, а не двоичной информацией (при условии, что у вас установлен exif-инструмент), добавьте следующий раздел в ваш файл $GIT_DIR/config (или $HOME/.gitconfig):

[diff "jpg"]
        textconv = exif

Решение для mingw32, поклонникам cygwin, возможно, придется изменить подход. Проблема заключается в передаче имени файла для преобразования в cmd.exe - он будет использовать прямую косую черту, а cmd принимает разделители каталога обратной косой черты.

Шаг 1:

Создайте единственный аргумент script, который будет выполнять преобразование в stdout. C:\путь\к\некоторые\script.sh:

#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"

Шаг 2:

Настройте git, чтобы использовать файл script. Внутри вашего конфигуратора git (~/.gitconfig или .git/config или см. man git-config) поставьте это:

[diff "cmdtype"]
textconv = c:/path/to/some/script.sh

Шаг 3:

Укажите файлы, чтобы применить этот рабочий ресурс, используя файлы .gitattributes(см. man gitattributes (5)):

*vmc diff=cmdtype

затем используйте git diff в ваших файлах.

Ответ 6

Я написал небольшой драйвер git -diff, to-utf8, который должен упростить разбор любых кодированных файлов, отличных от ASCII/UTF-8. Вы можете установить его, используя следующие инструкции: https://github.com/chaitanyagupta/gitutils#to-utf8 (to-utf8 script доступен в том же репо).

Обратите внимание, что для этого script требуется, чтобы в системе были доступны команды file и iconv.

Ответ 7

Git недавно начал понимать такие кодировки, как utf16. Смотрите gitattributes документы, ищите working-tree-encoding

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

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

*.vmc text working-tree-encoding=UTF-16LE eol=CRLF

Если UTF-16 (с бомбой) на * nix сделает это:

*.vmc text working-tree-encoding=UTF-16 eol=LF

(замените *.vmc на *.whatever для файлов типа whatever, с которыми вам нужно работать)

См.: Поддержка кодировки рабочего дерева "UTF-16LE-BOM".

Ответ 8

В последнее время эта проблема возникала в Windows, и сработали корзины dos2unix и unix2dos, которые поставляются с git для windows. По умолчанию они находятся в C:\Program Files\Git\usr\bin\. Заметьте, это будет работать только в том случае, если ваш файл не обязательно должен быть в формате UTF-16. Например, кто-то случайно кодировал файл python как UTF-16, когда это не нужно (в моем случае).

PS C:\Users\xxx> dos2unix my_file.py
dos2unix: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 Unix format...

и

PS C:\Users\xxx> unix2dos my_file.py
unix2dos: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 DOS format...