Переносимость файлов

К радости пользователей Subversion, регулярно работающих с различными компьютерами и операционными системами, утилита командной строки Subversion везде работает практически одинаково. Если вы знаете, как обращаться с svn на одной платформе, вы справитесь с ней и на любой другой платформе.

Однако, это не всегда справедливо для других классов программного обеспечения, а также для конкретных файлов, хранящихся в Subversion. Например, на компьютере под управлением Windows «текстовые файлы» выглядят почти так же как и в Linux, но при этом есть одно существенное отличие — последовательность символов, используемая для маркировки конца строки в таких файлах. Имеются и другие различия. Unix-платформы имеют символьные ссылки (и Subversion их поддерживает), а Windows — не имеет. На Unix-платформах исполнимость файла определяется с помощью прав доступа на уровне файловой системы; Windows использует для этого расширения имен файлов.

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

Тип содержимого файла

Subversion принадлежит к многочисленному семейству приложений, распознающих и использующих для типизации содержимого многоцелевые расширения интернет-почты (Multipurpose Internet Mail Extensions — MIME). Свойство svn:mime-type не только является универсальным местом хранения информации о типе содержимого файла, но и определяет некоторые особенности поведения Subversion.

Например, одной из полезных возможностей Subversion является контекстное, построчное слияние изменений, полученных от сервера во время обновления, с рабочей копией. Однако, для файлов, не содержащих текстовых данных, как правило, не существует понятия «строки». Поэтому для версионированных файлов, чье свойство svn:mime-type указывает на нетекстовый MIME-тип (как правило, это все, что не начинается с text/, хотя есть несколько исключений), Subversion не будет пытаться провести контекстное слияние во время обновления. Вместо этого, каждый раз когда вы локально модифицируете рабочую копию бинарного файла, и выполняете после этого обновление, файл будет переименован с добавлением расширения .orig, после чего Subversion запишет под оригинальным именем новый файл рабочей копии, c изменениями, полученными в процессе обновления, но без ваших локальных исправлений. Такое поведение призвано защитить пользователя от неудачных попыток выполнить контекстное слияние для файлов, к которым его нельзя применить.

Кроме того, если для файла определено свойство svn:mime-type, Apache-модуль Subversion будет использовать его значение при формировании HTTP-заголовка Content-type: в ответ на GET-запросы. Благодаря этому ваш браузер (в том случае, если он будет использоваться для просмотра содержимого Subversion-хранилища) будет знать, как правильно отобразить этот файл.

Исполнимость файла

На многих операционных системах возможность выполнения файла как команды определяется битом разрешения выполнения. Обычно по умолчанию этот бит не задан; он должен быть явно установлен пользователем для тех файлов, которым это необходимо. Однако, было бы слишком сложным запоминать, какие именно файлы в только что созданной рабочей копии должны иметь установленный бит выполнения, и устанавливать этот бит. Поэтому Subversion поддерживает свойство svn:executable, позволяющее указать, для каких файлов должен быть установлен бит исполнения. При создании рабочей копии Subversion самостоятельно установит этот бит для таких файлов.

Это свойство не оказывает никакого эффекта на файловых системах, не использующих бита разрешения выполнения, таких как FAT32 и NTFS. [16]. Кроме того, хотя значение этого свойства не задано, Subversion принудительно устанавливает ему значение *. Наконец, это свойство действительно только для файлов, но не для каталогов.

Символы конца строки

Subversion считает, что файл содержит читаемые данные, если на обратное не указывает версионированное свойство файла svn:mime-type. В общем-то, Subversion необходимо знать об этом только для того, чтобы определить возможность построения контекстного отчета о различиях. В противном случае Subversion будет воспринимать файл лишь как набор байтов.

Сказанное означает, что по умолчанию Subversion не уделяет никакого внимания используемой в файлах разновидности маркера конца строки (EOL). К сожалению, различные операционные системы используют различные соглашения о том, какая последовательность символов означает конец текстовой строки в файле. Например, программы под Windows обычно используют в качестве признака конца строки последовательность из двух управляющих символов ASCII — возврата каретки (CR) и перевода строки (LF). В то же время программы под Unix для обозначения конца строки используют единственный символ LF.

Далеко не все програмы способны понимать файлы, в которых признак конца строки отличается по формату от принятого стиля завершения строк в данной операционной системе. Обычным делом является ситуация, когда программы под Unix рассматривают символ CR, присутствующий в файлах Windows, как обычный символ (часто представляя его как ^M), или когда программы под Windows слепляют все строки файла Unix в одну гигантскую строку, поскольку в нем отсутствуют комбинации символов возврата каретки и перевода строки (или CRLF), обозначающие концы строк.

Такая чувствительность к чужеродным EOL-маркерам может стать серьезной проблемой для людей, совместно использующих одни и те же файлы в различных операционных системах. Возьмем для примера файл с исходным кодом программы и разработчиков, редактирующих этот файл как под Windows, так и под Unix. Если все разработчики будут всегда использовать инструменты, сохраняющие в файле прежний стиль завершения строк, проблем не возникнет.

Но на практике многие распространенные утилиты либо не умеют правильно считывать файлы с чужеродными EOL-маркерами, либо конвертируют концы строк в файле к родному стилю при сохранении файла. Если разработчик сталкивается с первым случаем, он оказывается вынужденным пользоваться внешними утилитами конвертации (такими как dos2unix или ее аналоги, unix2dos), чтобы подготовить файл к редактированию. Во втором случае дополнительная подготовка файлов не требуется. Однако, в обоих случаях получается файл, каждая строка в котором отличается от исходной! Прежде чем фиксировать свои изменения, пользователь может сделать одно из двух. Он может либо использовать утилиту конвертации, чтобы восстановить в модифицированном файле прежний стиль завершения строк; либо просто зафиксировать файл с новыми EOL-маркерами.

Результатом такого сценария станут напрасная трата времени и нежелательные изменения в фиксируемых файлах. Напрасная трата времени сама по себе обходится довольно дорого. А когда фиксация вносит изменения в каждую строку файла, становится невозможным определить, какие строки файла действительно изменились по существу. Был ли устранен тот самый баг? В какой строке имелась синтаксическая ошибка?

Данную проблему решает свойство svn:eol-style. Когда этому свойству задано одно из допустимых значений, Subversion использует его для того, чтобы определить вариант специальной обработки файла, производимой для того, чтобы стиль завершения строки не изменялся туда-сюда при каждой фиксации, выполняемой из другой операционной системы. Допустимы следующие значения:

native

Файл будет содержать EOL-маркеры, принятые в той операционной системе, на которой работает Subversion. Иными словами, если пользователь на машине с Windows создает рабочую копию файла, у которого свойство svn:eol-style установлено в native, этот файл будет содержать EOL-маркеры CRLF. Пользователь Unix, создавая рабочую копию того же самого файла, увидит в нем EOL-маркер LF.

Учтите, что на самом деле Subvversion будет записывать файл в хранилище, используя нормализованный EOL-маркер LF, вне зависимости от операционной системы. Хотя обычно это прозрачно для пользователя.

CRLF

Файл будет содержать в качестве EOL-маркеров последовательность CRLF, независимо от используемой операционной системы.

LF

Файл будет содержать в качестве EOL-маркера символ LF, независимо от используемой операционной системы.

CR

Файл будет содержать в качестве EOL-маркера символ CR, независимо от используемой операционной системы. Данный стиль завершения строки не слишком распространен. Он использовался на устаревших платформах Macintosh (на которых Subversion даже никогда не запускался).



[15] Вы думаете, это всё? В тот же самый период времени WordPerfect также предпочитал использовать расширение .DOC для своего собственного закрытого формата файлов!

[16] Для указания исполняемых файлов файловая система Windows использует расширения файлов (а именно .EXE, .BAT и .COM).