Могу ли я заставить git распознавать файл UTF-16 как текст? - PullRequest
126 голосов
/ 22 апреля 2009

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

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

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

Ответы [ 8 ]

76 голосов
/ 19 августа 2009

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

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

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

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

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

Git пород.

58 голосов
/ 09 января 2014

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

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

  1. Создайте файл .gitattributes в корне хранилища с помощью:

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

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

Источник: Разные файлы .strings в Git более старая запись от 2010 г.).

36 голосов
/ 22 апреля 2009

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

например:.

*.vmc diff

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

28 голосов
/ 22 апреля 2009

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

Но, глядя на справочную страницу .gitattributes , вот пользовательский атрибут binary:

[attr]binary -diff -crlf

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

[attr]utf16 diff merge -crlf

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

*.vmc utf16

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

git diff --text

Редактировать

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

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

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

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

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

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

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

8 голосов
/ 09 июля 2009

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

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


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

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

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

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

[diff "jpg"]
        textconv = exif

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

Шаг 1:

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

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

Шаг 2:

Настройте git, чтобы иметь возможность использовать файл скрипта. Внутри вашего git config (~/.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 для ваших файлов.

4 голосов
/ 02 апреля 2013

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

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

2 голосов
/ 14 февраля 2019

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
1 голос
/ 24 июля 2018

В последнее время эта проблема возникла в 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...
...