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

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

четверг, 23 декабря 2010 г.

ffmpeg (ffserver) for windows

Собрал ffmpeg (включая ffserver) под cygwin.
Был использован ключ --disable-yasm.
Версия, согласно git log

commit 390071f52d1b4a768a0083dc55f3d3e361afc06c
Author: mstorsjo
Date:   Wed Dec 22 20:00:42 2010 +0000

 
Кому надо забирайте: страница загрузки или файл.

среда, 11 ноября 2009 г.

Git для Cygwin и русские или другие национальные буквы в именах файлов

Сделал приятное открытие для себя.
Например,  представим такой сценарий:
Имеем репозиторий git, который только что создан с помощью git init.
Теперь мы хотим создать и добавить в репозиторий файлик "прочти меня.txt". И видим такую картинку:
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       "\320\277\321\200\320\276\321\207\321\202\320\270 \320\274\320\265\320\275\321\217.txt"
nothing added to commit but untracked files present (use "git add" to track)

Что, во-первых неэстетично и непонятно. А во-вторых, если закоммитить и продолжить работу, то могут обнаружаться конфликты файлов из разных веток, которые не могут быть разрешены автоматически. При этом мёржилке не получится отдать правильные имена и будет выдана ошибка, что файл не найден.

Если в .git/config в раздел [core] прописать:
quotepath = false
То происходит небольшое и ожидаемое, но всё-таки волшебство ;)
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       прочти меня.txt
nothing added to commit but untracked files present (use "git add" to track)

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

вторник, 9 июня 2009 г.

Включение поддержки UTF-8 в cygwin 1.7

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

На многих форумах пишут что для версий меньше 1.7 проблема актуальна, но я сам не проверял. Для сборки 1.5.25-15 существует специальный патч.
Который, судя по всему, был включен в основную ветку.

Итак, чтобы включить поддержку кодировки UTF-8 необходимо проделать следующие шаги:

1. Если ставите CygWin заново, то отметьте в инсталляторе пакеты интернационализации
libintl, libiconv2. Либо просто убедитесь в их наличии при уже установленном CygWin
2. Добавьте или приведите к следующему виду строки в файле /etc/inputrc или ~/.inputrc:
set input-meta on
set meta-flag on
set convert-meta off
set output-meta on

3. Добавьте или приведите к следующему виду строку в файле /etc/profile или ~/.profile:
export LANG=ru_RU.UTF-8

Или же можно создать отдельный файлик локализации в папке /etc/profile.d/. Пусть это будет, например utf-8.sh.

А теперь запускаем CygWin и видим нормальную поддержку русского языка.
В частности, теперь нормально работает git, особенно git svn rebase.

Для некоторых задач удобно использовать GitExtensions. Это довольно неплохая утилита, аналогичная TortoiseGit, но поддерживает совместную работу с Visual Studio 2005, 2008.
Первая проблема - утилита требует файл git.cmd, которого в CygWin нет. Берем его из MSysGit и кладем в c:\cygwin\cmd.
Вторая, в том, что git.cmd не учитывает свойства среды, которые мы настроили ранее, поэтому я немного подправил его до такого вида:

@echo off
set PLINK_PROTOCOL=ssh
setlocal
for /F "delims=" %%I in ("%~dp0") do @set git_install_root=%%~fI
rem set git_install_root=C:\cygwin
set path=%git_install_root%\bin;%git_install_root%\cmd;%PATH%

if "%1"=="gui" @goto gui
:default
for /f "tokens=* usebackq" %%i in (`@cygpath.exe %CD%`) do (
set HOME=%%i
)
bash.exe -lc 'git.sh --git-dir=%HOME%/.git %*'
exit /b %ErrorLevel%
:gui
if "%2"=="citool" @goto default
start wish.exe "%git_install_root%\libexec\git-core\git-gui" -- %2 %3 %4 %5 %6 %7 %8 %9


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