понедельник, 7 мая 2012 г.

Кроссплатформная проблема длинных имен файлов (Crossplatform long file name problem)


Хотя я демонстрирую ошибку на примере работы с системами контроля версий для MacOsX и Windows - это проблема более глобальная и поймать её вы можете в любой другой комбинации софта (да хоть в той же Samba).
Используемый подход решения проблемы наверняка не единственный, но, при этом, довольно универсален.

Различные файловые системы по разному хранят информацию об имени файла.
Из-за чего возникают коллизии если разработка ведётся многими людьми и у всех разные ОС.
В моём случае получилось так, что другой разработчик закоммитил в репозиторий файл длиной 180 русских букв.

$ echo "яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяяяяяяяяяяя яяяяяяяя яяяяя яяяяяя я яяя яяяяя яяя" | wc -m

180


Но

$ echo "яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяяяяяяяяяяя яяяяяяяя яяяяя яяяяяя я яяя яяяяя яяя" | wc -c

334

Русские буквы занимают два байта вместо одного.
При попытке создать такой файл под MacOsX на диске со стандартной файловой системой HFS+

$ touch "яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяяяяяяяяяяя яяяяяяяя яяяяя яяяяяя я яяя яяяяя яяя"

Получим странное

$ ls я*

яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяя#299CD031

Несмотря на заявляемые 255 знаков в кодировке UTF-16 (точно также в NTFS).
А если такой файл попробовать отредактировать, например с помощью vim, то после сохранения и выхода
:wq
файл исчезает.

Кстати, несмотря на то, что некоторые ФС поддерживают ещё более длинные имена, штатные утилиты linux, по всей вероятности, всё равно оперируют байтами и поэтому комманда touch мне стабильно выдавала ошибку: “File name too long”
Я, например, пробовал ReiserfFS под Ubuntu 12.04 LTS.

Возвращаясь к MacOs. Именно эту ошибку я поймал при попытке получить последние изменения из репозитория.
$ git svn rebase
First, rewinding head to replay your work on top of it...
error: cannot stat '$73_chars_4_deep_levels_path_with_spaces/$180_chars_file_name_with_spaces_too': File name too long
error: cannot stat '$73_chars_4_deep_levels_path_with_spaces/$180_chars_file_name_with_spaces_too': File name too long
error: cannot stat '$73_chars_4_deep_levels_path_with_spaces/$180_chars_file_name_with_spaces_too': File name too long
could not detach HEAD
rebase refs/remotes/git-svn: command returned error: 1

Первой моей идеей стало установить Windows внутри VirtualBox и там настроить Cygwin, т.к. в этой экосистеме файлы с длинными именами чувствуют себя вольготно.
Но, всё-таки, ОС внутри виртуальной машины - это довольно тяжелая штука в плане потребления ресурсов.
К тому же, Cygwin/MSysGit имеют и другие проблемы, с которыми приходится периодически бороться.

И, вот, после неудачи с Windows и Ubuntu, ко мне пришла идея попробовать создать образ диска с подходящей ФС средствами MacOS.

Хотя Linux и позволяет создавать и монтировать образы дисков даже более гибко, но надо что-то в нём докручивать, либо чтобы ядро поддерживало длинные уникодные имена, либо выставлять однобайтную локаль и на лету конвертировать файлы с помощью чего-то вроде iconv или средствами самого гита.

В комплекте с макосью идёт инструмент DiskUtility.
Где я для начала попробовал создать DMG-образы с NTFS.
Но, вероятно, имеющиеся у меня драйверы NTFS-3G и Tuxero, содержат ошибку.
В обоих случаях я получал до боли знакомый “File name too long”.

Удача меня ждала с ФС ExFat.



$ touch "яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяяяяяяяяяяя яяяяяяяя яяяяя яяяяяя я яяя яяяяя яяя"

И, ву-а-ля

$ ls я*

яяяяяяяяя яя яяяя яя яяяяяяяяяя яяяяяяяяя я яяяяяя я яяя яяяяяяяяя яяяяяяяяяяяяя яяяяяяяя я яяяяяяяяяяяяяяяяяя яяяяяя яя яяяяяя яяяяяяяяяяяяя яяяяяяяя яяяяя яяяяяя я яяя яяяяя яяя


После перемещения своего проекта в новый раздел, вся остальная операция прошла как по-маслу.

Далее, можно почитать про Unicode в названиях файлов в HFS.

Комментариев нет: