Показаны сообщения с ярлыком versioning. Показать все сообщения
Показаны сообщения с ярлыком versioning. Показать все сообщения

понедельник, 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.

пятница, 25 ноября 2011 г.

Как в Git игнорировать изменение прав у файлов

Работая в среде Cygwin или MSysGit, часто бывает так что права файлов изменяются, либо внешней средой, либо внутренними процессами.
У меня наиболее часто меняется признак исполнимости. И, к сожалению, пока отсутствует время чтобы разобраться в причинах.

Загадочным, для меня, образом некоторым файлам добавляется +x, некоторым -x. И Git уже начинает считает эти файлы изменёнными, которые обязательно надо закоммитить.
Т.к. происходит такое довольно часто, то это вызывает раздражение и пустую трату времени на починку с помощью chmod и/или git reset --hard.

Так, вот, если в вашем проекте не используются системные права, то можно заставить git игнорировать изменение прав у файлов.

Отключением/включением проверки управляет ключ filemode из секции core.
Его значение необходимо установить в false.

Либо прямым редактированием .gitconfig:
[core]
        filemode = false

Либо командой:
$ git config core.filemode false

Приятной разработки!