Git и проблема Umlaut в Mac OS X

Сегодня я обнаружил ошибку для Git на Mac OS X.

Например, я сначала передам файл с именем überschrift.txt с немецким специальным символом Ü. Из команды git status я получаю следующий вывод.

Users-iMac: user$ git status

On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   "U\314\210berschrift.txt"
nothing added to commit but untracked files present (use "git add" to track)

Кажется, что Git 1.7.2 имеет проблемы с немецкими специальными символами на Mac OS X X. Есть ли решение получить Git правильно прочитать имена файлов?

Ответ 1

Включить core.precomposeunicode на mac

git config --global core.precomposeunicode true

Для этого вам нужно иметь как минимум Git 1.8.2.

Горный лев корабли с 1.7.5. Чтобы получить новый Git, используйте git-osx-installer или homebrew (требуется Xcode).

Что это.

Ответ 2

Причиной является различная реализация того, как файловая система сохраняет имя файла.

В Юникоде, Ü можно представить двумя способами: один - только с помощью Ü, другой - с помощью U + ", объединяющего символ умлаута". Строка Unicode может содержать обе формы, но, поскольку она запутывает их, файловая система нормализует строку юникода, устанавливая каждый umlauted-U на Ü или U +, комбинируя символ умлаута.

Linux использует прежний метод, называемый Normal-Form-Composed (или NFC), и Mac OS X использует последний метод, называемый Normal-Form-Decomposed (NFD).

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

В списке рассылки Git, в Mac OS X и немецких специальных символах есть патч, чтобы Git сравнивал имена файлов после нормализации.

Ответ 3

Чтобы сделать git add file работу с umlauts в именах файлов в Mac OS X, вы можете преобразовать строки пути файла из сложенных в канонически разложенные UTF-8 с помощью iconv.

# test case

mkdir testproject
cd testproject

git --version    # git version 1.7.6.1
locale charmap   # UTF-8

git init
file=$'\303\234berschrift.txt'    # composed UTF-8 (Linux-compatible)
touch "$file"
echo 'Hello, world!' > "$file"

# convert composed into canonically decomposed UTF-8
# cf. http://codesnippets.joyent.com/posts/show/12251
# printf '%s' "$file" | iconv -f utf-8 -t utf-8-mac | LC_ALL=C vis -fotc 
#git add "$file"
git add "$(printf '%s' "$file" | iconv -f utf-8 -t utf-8-mac)"  

git commit -a -m 'This is my commit message!'
git show
git status
git ls-files '*'
git ls-files -z '*' | tr '\0' '\n'

touch $'caf\303\251 1' $'caf\303\251 2' $'caf\303\251 3'
git ls-files --other '*'
git ls-files -z --other '*' | tr '\0' '\n'

Ответ 4

Следующая запись в ~/.gitconfig работает для меня на 10.12.1 Sierra для имен UTF-8:

precomposeunicode = true
quotepath = false

Первый параметр необходим, чтобы git "понимал" UTF-8 и второй, чтобы он не пропускал символы.

Ответ 5

Изменить репозиторий на OSX-специфический флаг core.precomposeunicode на true:

git config core.precomposeunicode.true

Чтобы убедиться, что новые репозитории получают этот флаг, также выполните:

git config --global core.precomposeunicode true

Вот соответствующий фрагмент из man-страницы:

Этот параметр используется только для реализации Mac OS Git. когда core.precomposeunicode = true, Git возвращает разложение в unicode имена файлов, сделанные Mac OS. Это полезно при совместном использовании репозитория между Mac OS и Linux или Windows. (Git для Windows 1.7.10 или выше или Git под cygwin 1.7). Когда false, имена файлов обрабатывается полностью прозрачно с помощью Git, который обратно совместим с более старые версии Git.

Ответ 6

Это правильно.

Ваше имя файла находится в UTF-8, и представляется как LATIN CAPITAL LETTER U + COMBINING DIAERESIS (Unicode 0x0308, utf8 0xcc 0x88) вместо ЛАТИНСКОГО КАПИТАЛА ПИСЬМА U С ДИАЕРЕЗОМ (Юникод 0x00dc, utf8 0xc3 0x9c). Файловая система Mac OS X HFS разлагает Unicode таким образом. Git, в свою очередь, отображает восьмеричную форму байта имени файла, отличного от ASCII.

Обратите внимание, что имена файлов Unicode могут сделать ваш репозиторий не переносимым. Например, msysgit имел проблемы с именами файлов Unicode.

Ответ 7

У меня была аналогичная проблема с моим личным репозиторием, поэтому я написал вспомогательный script с Python 3. Вы можете просмотреть его здесь: https://github.com/sjtoik/umlaut-cleaner

script требует немного ручного труда, но не много.