Диакритические знаки в именах файлов, вызывающие различия между subversion и git (MacOS) - PullRequest
0 голосов
/ 05 марта 2019

У меня есть имена файлов с диакритическими знаками (например, Exposé.pdf).

$ svn stat
!    Exposé.pdf
?    Exposé.pdf

Я использую Subversion и Git рядом друг с другом (не Git-SVN).Я перехожу из subversion в git и хочу какое-то время сосуществовать.Поэтому у меня есть большие репозитории на нескольких устройствах.Когда я клонирую репозиторий с помощью git и добавляю в репозиторий уже существующую папку Subversion .svn, я получаю различия Subversion (! Item отсутствует,? Item не относится к vcs), но имена файлов выглядят точно так же, но подкапота у них нет!Я пробовал (см. https://www.git -tower.com / help / mac / faq-and-tips / faq / unicode-filenames )

git config --global core.precomposeunicode true 

, но это не даетразница.Есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 05 марта 2019

Вероятно, проблема в «нескольких устройствах».Точно, что может быть исправление или обходной путь, не ясно.См. Технические подробности ниже.

В общем, вы не должны устанавливать core.precomposeunicode самостоятельно, так же, как вы не должны устанавливать core.ignorecase сами. 1 Эти настройки - наряду с core.symlnks - это то, что Git устанавливает для себя для записи того, как ваш компьютер ведет себя во время выполнения git init илиgit clone. 2 Если вы установили это с помощью --global, я бы порекомендовал вам удалить настройку из вашей личной конфигурации Git:

git config --global --unset core.precomposeunicode

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

Когда включен автоматический выбор, вы всегда можете клонировать существующий репозиторий вновая копия.Новый клон будет иметь правильные (локальные) настройки для непосредственных локальных условий.Этот новый клон нельзя переносить с одной машины на другую любым другим способом, кроме git clone.


1 Они могут быть написаны с любой случайной заглавной буквы, которая вам нравится.Документация Git делает это, используя camelCase , называя их core.precomposeUnicode и core.ignoreCase.Вы можете установить их для определенных целей тестирования или для странных крайних случаев, когда вы хотите иметь дело с хранилищем, которое было построено каким-то нежелательным образом.Но это равносильно лжи Git, так что будьте осторожны с этим!Сделайте это локально (не глобально) во время экспериментов.

2 Здесь есть еще один особый случай.Операционные системы, которые имеют эти ... «особенности» нанесения вреда именам ваших файлов, во имя защиты от уродливой реальности, часто фактически делают это на основе для файловой системы .Например, возможность сворачивания кейсов в MacOS может изменяться во время создания образа диска.Поддержка Symlink в Windows зависит от версии Windows и нескольких дополнительных элементов.Таким образом, можно подобрать Git-репозиторий без изменений, переместить его в другую файловую систему и затем изменить настройки.Это одна из причин, по которой часто разумнее git clone переходить из одной файловой системы в другую, а не использовать tar, или rar, или zip, или даже cp -r для перемещения Git-репозитория: клон установит настройки правильнов то время как операция копирования без клонирования не будет.


Имена файлов являются байтовыми строками, за исключением случаев, когда они не

Основная проблема здесь заключается в том, что Git хочет верить, чтоИмена файлов - это не что иное, как байтовые строки с двумя или тремя ограничениями, 3 , установленными в Linux, и никакими другими ограничениями, установленными в любой другой ОС.Эти байтовые строки обычно должны быть, но не обязательно, действительными последовательностями UTF-8.В идеале ОС позволит Git использовать эти строки байтов как есть, без каких-либо ограничений.

В Windows и MacOS этот идеал сразу же врезается в реальность.Наиболее очевидная и непосредственная проблема заключается в том, что в Linux вы можете создать файл с именем README, а затем создать второй, другой файл с именем readme, и оба файла будут сосуществовать.В Windows и MacOS, когда вы создаете любой из этих файлов, вы больше не можете создавать второй файл: любая попытка сделать это просто повторно использует первый.

В другихслова Linux имеют регистрозависимые имена файлов, а Windows и MacOS - нет.Это означает, что пользователь Linux может свободно создавать файлы README.txt и readme.txt и помещать оба в один репозиторий.Пользователь Windows или MacOS, который клонирует этот репозиторий, не может работать с обоими файлами одновременно.

Тем не менее, пользователь Git в Windows или MacOS может работать с этими файлами.Это просто больно.Я показываю метод в своем ответе на «Изменения, не подготовленные для фиксации», даже после того, как git commit -am b / c origin имеет файл с заглавными буквами в имени файла . Этот тот же метод будет применяться здесь с равными суммамиболи.

Это то же правило применяется к определенным именам файлов Unicode. В частности, Unicode имеет несколько способов написания некоторых акцентированных символов, таких как á, ü и т. Д.Например, если у нас есть файл с именем schön (довольно), мы можем записать это, используя последовательность букв:

s c h umlaut-o n

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

s c h o combining-umlaut n

Это разные последовательности байт-кода и поэтому должны - по крайней мере, согласно Git - отличатьсяфайлы , хотя оба будут отображать как имя schön на вашем экране.

MacOS говорит эти два имени будут отображаться одинаково, и поэтому я не позволюодин из них .Если вы введете «неправильное» написание для ОС, оно либо исправит его, либо просто отклонит.Обратите внимание, что это несколько отличается от ситуации со сложением регистра: MacOS позволит вам создать либо readme или README, но не оба.Это разрешит только одну форму schön.

Поскольку Git создает новые коммиты из index , а не из файловой системы, а индекс является обычным файлом данных, вы может добавить в индекс желаемое правописание или даже оба.Это означает, что вы можете поместить один или оба в новые коммиты. Любые существующие коммиты имеют существующие орфографии и не могут быть изменены.

Загрузка существующих коммитов (через git checkout) копирует зафиксированное написание в индекс, где оно остается как есть.,Параметр core.precomposeunicode сообщает Git, будет ли ваша ОС изменять имя (и) файла (файлов), когда Git пытается скопировать файл из индекса до рабочего дерева.Git может затем попытаться отменить любой ущерб, если это необходимо.Но не все случаи могут быть обработаны, особенно те, где файл появляется в коммите с обоими написаниями, очень похоже на свертывание регистра в README vs readme.

(См. Также внутреннюю само-запись Gitтест для MacOS precompose-unicode, в t / t3910-mac-os-precompose.sh .)


3 Ограничения:

  • ни одна строка не начинается и не заканчивается косой чертой (последняя довольно просто обрабатывается тем фактом, что Git не будет хранить каталог, а первая просто не использует начальную косую черту, если она есть);
  • ни одна строка не имеет двух косых черт подряд;и
  • ни одна строка не имеет встроенного байта NUL (это правило взято из языка C, на котором написан Git, и поддерживается этими ОС, так что на самом деле это не проблема).

Правила слеша заключаются в том, что Linux рассматривает слеш как разделитель каталога / подкаталога или каталога / имени файла.MacOS, конечно, делает то же самое, и Windows поддерживает это с большинством своих интерфейсов, несмотря на внутреннюю обратную косую черту.Таким образом, все три системы довольны ограничением косой черты.Однако некоторые файловые системы Windows также используют UTF-16-LE внутри, что создает дополнительное минное поле вокруг так называемых суррогатных побегов.Я не знаю, как Windows справляется с этим.В идеале минное поле не проникает от внутренних к внешним интерфейсам, но с другой стороны, в идеале, Windows будет использовать косую черту и UTF-8.: -)

...