Смешивание правок имеет ограничения
Несмотря на то, что в рабочей копии можно использовать смешивание правок, у этой гибкости существуют ограничения.
Во-первых, нельзя зафиксировать удаление устаревшего файла или каталога. Если в хранилище существует более новая версия элемента, попытка удаления будет отклонена для предотвращения возможности непреднамеренного уничтожения изменений о которых вы не в курсе.
Во-вторых, нельзя зафиксировать изменение метаданных для не обновленного каталога. О присвоении «свойств» к элементам вы узнаете в Главе 6. Рабочая правка каталога определяет конкретный набор входящих в нее элементов и свойств, поэтому фиксация изменений свойств для устаревшего каталога может привести к уничтожению свойств о которых вы не знаете.
Пред. | Уровень выше | След. |
Модели версионирования | Содержание | Подводя итоги |
Смешивание правок — это нормально
Фактически, каждый раз при выполнении svn commit правки рабочей копии смешиваются. Только что зафиксированные элементы отмечаются как имеющие больший номер рабочей правки, чем все остальные. После нескольких фиксаций (без выполнения обновлений между ними) правки рабочей копии будут полностью перемешаны. Даже если вы являетесь единственным пользователем хранилища, вы все равно с этим столкнетесь. Для просмотра этой смеси рабочих правок воспользуйтесь командой svn status --verbose (см. «svn status»).
Часто новые пользователи даже не подозревают о том, что их рабочая копия содержит смешанные правки. Это может сбить с толку, так как многие команды клиента чувствительны к рабочей правке элемента, с которым он работает. Например, команда svn log используется для вывода истории изменения файла или каталога (см. «svn log»). Когда пользователь вызывает эту команду применительно к объекту рабочей копии, он ожидает увидеть полную историю этого объекта. Однако если рабочая правка объекта очень старая (из-за того, что команда svn update долго не выполнялась) будет показана история для более старой версии этого объекта.
Смешивание правок — это полезно
Если у вас очень большой проект, вы можете найти полезным, время от времени принудительно «возвращать» части рабочей копии к более ранним правкам; как это делается, вы узнаете в Главе 3. Возможно вы захотите протестировать более раннюю версию модуля, находящегося в подкаталоге или точно узнать, когда в конкретном файле появилась ошибка. Это — «машина времени» — тот аспект системы управления версиями, который позволяет перемещать в истории любую часть рабочей копии вперед и назад.
Смешивание правок в рабочих копиях
Subversion старается быть гибкой настолько, насколько это возможно. Например, существует возможность иметь рабочую копию, содержащую файлы и каталоги, имеющие смешанные номера рабочих правок. Но, к сожалению, эта гибкость иногда смущает некоторых новых пользователей. Если раньше примеры, показывающие смешанные правки, вызывали у вас чувство растерянности, то это руководство, которое рассказывает для чего такая возможность существует и как ее использовать, для вас.
Соглашения, принятые в книге
В этом разделе приводятся соглашения, принятые в книге.
Создание комплексной метки
Иногда вам будет необходим более сложный «снимок», чем одна единственная директория в одной правке.
Например, представим, что ваш проект гораздо больше, чем наш пример calc: допустим он содержит несколько поддиректорий и на много больше файлов. В процессе работе вам может понадобиться создать рабочую копию, содержащую конкретную функциональность и исправленные ошибки. Добиться этого вы можете выборочно возвращая файлы или директории к конкретной правке (используя svn update -r по мере необходимости) или переключая файлы или директории на отдельные ветки (применяя svn switch). По завершении рабочаяя копия будет представлять собой мешанину различных директорий и правок хранилища. После проверки вы поймете, что вам нужна именно такая комбинация.
Время создавать снимок. Копирование одного URL в другой здесь не пройдет. Здесь нужно сделать и сохранить в хранилище снимок именно такой структуры которую имеет рабочая копия. К счастью, svn copy имеет четыре способа использования (о которых вы можете прочитать в Главе 9), включая возможность копировать в хранилище дерево рабочей копии:
$ ls my-working-copy/ $ svn copy my-working-copy http://svn.example.com/repos/calc/tags/mytag Committed revision 352.Теперь в хранилище есть новая директория /calc/tags/mytag которая является полным отражением рабочей копии — смешанные правки, URL, и тому подобное.
Некоторые пользователи находят интересное применение этой возможности. Иногда возникают ситуации, когда в вашей рабочей копии содержаться изменения, которые вы не хотите показывать соразработчику. Вместо запуска svn diff и передачи патч-файла (который не сможет отразить изменения в структуре файлов, измененные символьные ссылки или свойства), вы можете воспользоваться svn copy для «загрузки» рабочей копии в отдельную область хранилища. Ваш соразработчик может сделать либо чистую копию вашей рабочей копии, либо воспользоваться svn merge для получения именно ваших изменений.
Пред. | Уровень выше | След. |
Переключение рабочей копии | Содержание | Поддержка веток |
Создание простой метки
И снова приходит на помощь svn copy. Если вам нужно сделать снимок /calc/trunk в точно таком виде как в правке HEAD, сделайте копию этой директории:
$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/tags/release-1.0 \ -m "Tagging the 1.0 release of the 'calc' project." Committed revision 351.В этом примере предполагается, что директория /calc/tags существует. (Если нет, обратитесь к svn mkdir). После того как сделана копия, новая директория release-1.0 навсегда сохранит состояние проекта в таком виде в каком он существовал в правке HEAD на момент создания копии. Конечно, можно более точно указать какую именно правку копировать, возможна ситуация, когда кто-то другой зафиксировал изменения в проекте с которыми вы еще не успели познакомиться. Поэтому, если вы знаете, что правка 350 /calc/trunk это именно тот снимок который вам нужен, можете указать ее передав -r 350 команде svn copy.
Постойте: ведь процедура создания метки такая же как процедура использованная нами при создании ветки? Да, фактически, это так. Subversion не разделяет ветки и метки. И то и другое является обычными директориями, созданными копированием. Как и в случае с ветками, скопированная директория становиться «меткой» только потому, что человек считает ее таковой: если никто не делает фиксаций в эту директорию она будет оставаться снимком. Если в эту директорию начнут делать фиксации она превратится в ветку.
Если вы администрируете хранилище, есть два возможных подхода управления метками. Первый подход «ручной»: в соответствии с правилами проекта решите, где будут находиться метки и убедитесь в том, что все пользователи знают как рассматривать директории скопированные сюда. (То есть убедитесь, что они знают о том что в них нельзя выполнять фиксации.) Второй подход более параноидальный: вы можете воспользоваться одним из скриптов для контроля доступа, поставляемым с Subversion для того, что бы никто ничего другого кроме создания копий в области для создания меток сделать не мог. (См. Глава 6, Настройка сервера.) Однако обычно в параноидальном подходе необходимости нет. Если пользователь непреднамеренно зафиксирует изменения в директорию с меткой, вы можете просто отменить изменения, как это было рассмотрено в предыдущем разделе. Как ни как, это управление версиями.
Создание ветки
Создать ветку очень просто — при помощи команды svn copy делаете в хранилище копию проекта. Subversion может копировать не только отдельные файлы но и директории. Итак, вам нужно сделать копию директории /calc/trunk. Где эта новая копия будет находится? Где угодно — этот вопрос определяется правилами проекта. Допустим, что правилами вашей команды определено создание веток в директории /calc/branches хранилища, и свою ветку вы хотите назвать my-calc-branch. Вам необходимо создать новую директорию /calc/branches/my-calc-branch которая будет являться копией /calc/trunk.
Есть два способа создания копии. Сначала мы покажем неудачный способ, просто для того, что бы прояснить основные моменты. Для начала, создается рабочая копия корневой директории проекта /calc:
$ svn checkout http://svn.example.com/repos/calc bigwc A bigwc/trunk/ A bigwc/trunk/Makefile A bigwc/trunk/integer.c A bigwc/trunk/button.c A bigwc/branches/ Checked out revision 340.Теперь создание копии заключается в простой передаче двух путей в пределах рабочей копии команде svn copy:
$ cd bigwc $ svn copy trunk branches/my-calc-branch $ svn status A + branches/my-calc-branchВ этом случае, команда svn copy рекурсивно копирует рабочую директорию trunk в новую рабочую директорию branches/my-calc-branch. Теперь команда svn status покажет, что новая директория запланирована для добавления в хранилище. Обратите внимание на знак «+» после буквы А. Это означает, что то что запланировано для добавления является копией чего-то, а не чем-то новым. При следующей фиксации, Subversion создаст в хранилище путем копирования директории /calc/trunk директорию /calc/branches/my-calc-branch, вместо повторного отправления через сеть всей информации рабочей копии:
$ svn commit -m "Creating a private branch of /calc/trunk." Adding branches/my-calc-branch Committed revision 341.А теперь, простой способ создания ветки, о котором мы говорили раньше: команда svn copy может оперировать с двумя URL напрямую.
$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/branches/my-calc-branch \ -m "Creating a private branch of /calc/trunk." Committed revision 341.В сущности, между этими двумя методами нет разницы. Оба варианта создают в правке 341 новую директорию и эта новая директория является копией /calc/trunk. Это показывает Рисунок 4.3, «Хранилище, содержащее новую копию». Обратите внимание на то, что второй метод, кроме прочего, выполняет немедленную фиксацию. [13]Эта процедура более проста в использовании, так как нет необходимости в создании рабочей копии, отражающей большое хранилище. Фактически, в этом случае вам вовсе можно не иметь рабочей копии.
Рисунок 4.3. Хранилище, содержащее новую копию
Легкие копии
Хранилище Subversion спроектировано особым образом. При копировании директории, нет необходимости задумываться о большом увеличении размера хранилища — на самом деле Subversion никогда не дублирует информацию. Вместо этого, создается новая сущность директории, которая указывает на существующие дерево файлов. Если вы пользователь Unix, это тот же подход, что используется для жестких ссылок. То есть копия, так сказать, стала «ленивой». Это значит, что если вы зафиксируете изменения одного файла из скопированной директории, то изменится только этот файл — остальные файлы будут продолжать существовать как ссылки на первоначальные файлы в первоначальной директории.
Вот почему часто в разговоре пользователей Subversion можно услышать о «легких копиях». Не имеет значения, насколько директория большая — для создания копии требуется очень небольшой фиксированный промежуток времени. Фактически, на этой функции основана работа фиксаций в Subversion: каждая правка является «легкой копией» предыдущей правки, с несколькими элементами лениво измененными в ней. (Что бы прочитать больше об этом, посетите веб сайт Subversion и прочитайте в документах по архитектуре Subversion о методе «всплывающих пузырьков».)
Конечно, эти внутренние механизмы копирования и деления информации скрыты от пользователя, который видит просто копии файлов. Основное здесь, это то, что копии легкие как по времени, так и по размеру. Делайте ветки так часто, как вам необходимо.
Специальные свойства
У Subversion нет каких то отдельных правил для свойств — использовать их можно как угодно. Единственно что Subversion требует от вас не использовать в названиях свойств префикс svn:. Потому, что это пространство имен для ее личного использования. Subversion выделяет несколько свойств, имеющих особый магический эффект для файлов и директорий, для которых они установлены. В этом разделе мы раскроем тайну и расскажем, как эти специальные свойства делают жизнь немного проще.
Status
svn status prints all files that have local modifications. By default, the repository is not contacted. While this subcommand accepts a fair number of options, the following are the most commonly used ones:
-uContact the repository to determine, and then display, out-of-dateness information.
-vShow all entries under version control.
-NRun non-recursively (do not descend into subdirectories).
The status command has two output formats. In the default «short» format, local modifications look like this:
$ svn status M foo.c M bar/baz.cIf you specify the --show-updates (-u) switch, a longer output format is used:
$ svn status -u M 1047 foo.c * 1045 faces.html * bloo.png M 1050 bar/baz.c Status against revision: 1066In this case, two new columns appear. The second column contains an asterisk if the file or directory is out-of-date. The third column shows the working-copy's revision number of the item. In the example above, the asterisk indicates that faces.html would be patched if we updated, and that bloo.png is a newly added file in the repository. (The absence of any revision number next to bloo.png means that it doesn't yet exist in the working copy.)
Lastly, here's a quick summary of the most common status codes that you may see:
A Resource is scheduled for Addition D Resource is scheduled for Deletion M Resource has local Modifications C Resource has Conflicts (changes have not been completely merged between the repository and working copy version) X Resource is eXternal to this working copy (may come from another repository). See «svn:externals» ? Resource is not under version control ! Resource is missing or incomplete (removed by another tool than Subversion)For a more detailed discussion of svn status, see «svn status».
Структура хранилища
Существует несколько стандартных, рекомендуемых способов организации хранилища. Как правило, создается директория trunk, в которой находится «главная линия» разработки, директория branches для хранения веток и директория tags для хранения меток. Если хранилище содержит только один проект, обычно создают три директории верхнего уровня:
/trunk /branches /tagsЕсли хранилище содержит несколько проектов, администратор, обычно создает такую структуру для каждого проекта отдельно (за более подробной информацией о «корне проекта» обратитесь в раздел «Choosing a Repository Layout»):
/paint/trunk /paint/branches /paint/tags /calc/trunk /calc/branches /calc/tagsКонечно, вы можете не использовать такие типовые структуры. Вы можете сделать любую разновидность, которая будет удобна для вас или вашей команды. Помните о том, какой бы вы выбор не сделали, он может быть не окончательным. Хранилище можно реорганизовать в любое время. Учитывая то, что ветки и метки являются обычными директориями, команда svn move может переместить или переименовать их по вашему усмотрению. Переход от одной структуры к другой означает просто несколько последовательных передвижек на сервере; если организация хранилища вам не нравится, просто поменяйте местами директории.
Однако не забывайте о том, что несмотря на легкость перемещения директорий, нужно помнить и о других пользователях. Ваши перестановки могут дезориентировать пользователей с существующими рабочими копиями. Если у пользователя есть рабочая копия отдельной директории хранилища, то ваше использование svn move может удалить этот путь из последней правки. Когда в очередной раз пользователь запустит svn update, он будет проинформирован о том, что его рабочая копия отражает путь, который больше не существует, и пользователь будет вынужден переключиться (svn switch) на новое местоположение.
Структура книги
Приведём краткий обзор содержания отдельных глав книги.
Глава 1, ВведениеВ этой главе приводятся сведения об истории Subversion, обсуждаются её возможности, архитектура, компоненты и способы установки. Здесь же приводится краткий курс, позволяющий быстро приступить к работе с Subversion.
Глава 2, Основные понятияГлава объясняет основы управления версиями, в ней разбираются различные модели работы с версиями, а также рассказано о хранилищах, рабочих копиях и редакциях в Subversion.
Глава 3, Экскурсия по SubversionОдин день из жизни пользователя Subversion. Глава поясняет, как использовать Subversion для получения данных, внесения в них изменений и закрепления состояния данных в хранилище.
Глава 4, Ветвление и слияниеВ этой главе рассматриваются ветки, метки и слияния, показаны эффективные методы выполнения ветвления и слияний, приводятся типичные примеры использования этих возможностей, а также даются сведения об отмене внесённых изменений. Глава также показывает, как легко переключиться с одной ветки на другую.
Глава 5, Администрирование хранилищаВ главе рассматриваются основные особенности хранилища Subversion, включая использование инструментов для создания, настройки и поддержки хранилища.
Глава 6, Настройка сервераВ этой главе показано, как настроить сервер Subversion. Здесь же рассматриваются три способа организации доступа к хранилищу: HTTP, протокол svn и локальный доступ. Кроме того, в главе уделяется внимание вопросам установления личности, проверки прав доступа и организации анонимного доступа к хранилищу.
Глава 7, Профессиональное использование SubversionВ этой главе подробно рассмотрены файлы для настройки клиента Subversion, свойства файлов и каталогов, показано, как игнорировать отдельные файлы в рабочей копии, как помещать в рабочую копию внешние деревья, как работать с ветвями от сторонних поставщиков.
Глава 8, Информация для разработчиковВ этой главе обсуждается внутреннее устройство Subversion, файловая система Subversion и служебные области рабочей копии с точки зрения программиста. Здесь же разбирается использование открытых API для написания программ, использующих Subversion, а также приводится информация о том, как вы можете внести вклад в разработку Subversion.
Глава 9, Полное справочное руководство по SubversionГлава подробно объясняет использование всех подкоманд svn, svnadmin и svnlook. Все пояснения сопровождаются множеством примеров.
Приложение A, Subversion для пользователей CVSВ приложении рассматриваются сходства и различия между Subversion и CVS, приводится ряд рекомендаций, позволяющих избавиться от вредных привычек, приобретённых с годами работы с CVS. Здесь также приводится информация о номерах редакций в Subversion, рассказано о возможности управления версиями для каталогов, приводятся сведения об автономных операциях, ветках, метках и метаданных, поясняется различие между подкомандами update и status, затронуты вопросы, связанные с разрешением противоречий и установлением личности пользователя.
Приложение B, WebDAV и автоматическое управление версиямиЭто приложение подробно рассматривает WebDAV и DeltaV и показывает, как настроить хранилище Subversion для подключения в виде совместно используемого ресурса DAV.
Приложение C, Инструменты от сторонних разработчиковЗдесь представлены некоторые программы, которые используют Subversion в своей работе, включая клиенты от сторонних производителей, инструменты для просмотра содержимого хранилища и другие программы.
Пред. | Уровень выше | След. |
Соглашения, принятые в книге | Содержание | Эта книга распространяется свободно |
Структура области конфигурации
Во время первого запуска клиент для командной строки svn создает отдельную для каждого пользователя область конфигурации. На Unix-подобных системах эта директория называется .subversion и находиться в домашней директории пользователя. На Win32 системах Subversion создает папку с именем Subversion в области Application Data директории с профилем пользователя (которая, кстати говоря, обычно является скрытой директорией). Однако на этой платформе точное местоположение отличается от системы к системе и указывается в реестре Windows. [34] При обращении к пользовательской области конфигурации мы будем использовать ее Unix-название.
В дополнение к пользовательской области конфигурации, Subversion использует общесистемную область конфигурации. Это дает возможность системным администраторам устанавливать параметры по умолчанию для всех пользователей отдельно взятой машины. Помните, что системная область конфигурации не устанавливает безоговорочные правила — параметры, заданные пользовательской конфигурацией переопределяют системные параметры, а аргументы командной строки, передаваемые программе svn, имеют последнее слово. На Unix-подобных платформах ожидаемым местоположением системной области конфигурации является директория /etc/subversion; на Windows машинах ищется директория Subversion внутри общесистемной области Application Data (также определяемой реестром). В отличие от пользовательской, системную область конфигурации svn не создает.
На сегодняшний момент область конфигурации содержит три файла — два файла конфигурации (config и servers) и README.txt, который содержит описание INI формата. После их создания, эти файлы содержат значения по умолчанию для всех, поддерживаемых Subversion параметров, обычно закомментированных и объединенных с текстовым описанием значений ключей, влияющих на поведение Subversion. Для того, что бы изменить отдельный параметр все, что нужно, просто загрузить соответствующий файл в текстовый редактор и изменить значение нужного параметра. Если в какой-то момент вы захотите восстановить параметры по умолчанию, необходимо просто удалить (или переименовать) директорию с конфигурацией, после чего выполнить какую-то безобидную команду svn, например, svn --version. В результате будет создана новая директория с конфигурацией и содержимым по умолчанию.
Кроме того, пользовательская область конфигурации содержит кеш идентификационной информации. Директория auth объединяет набор поддиректорий, содержащих кешированну информацию, используемую в различных, поддерживаемых Subversion методах авторизации. Эта директория создается так, что бы только сам пользователь имел право просматривать ее содержимое.
Subversion Repository URLs
As illustrated throughout this book, Subversion uses URLs to identify versioned resources in Subversion repositories. For the most part, these URLs use the standard syntax, allowing for server names and port numbers to be specified as part of the URL:
$ svn checkout http://svn.example.com:9834/repos …But there are some nuances in Subversion's handling of URLs that are notable. For example, URLs containing the file: access method (used for local repositories) must, in accordance with convention, have either a server name of localhost or no server name at all:
$ svn checkout file:///path/to/repos … $ svn checkout file://localhost/path/to/repos …Also, users of the file: scheme on Windows platforms will need to use an unofficially «standard» syntax for accessing repositories that are on the same machine, but on a different drive than the client's current working drive. Either of the two following URL path syntaxes will work where X is the drive on which the repository resides:
C:\> svn checkout file:///X:/path/to/repos … C:\> svn checkout "file:///X|/path/to/repos" …In the second syntax, you need to quote the URL so that the vertical bar character is not interpreted as a pipe. Also, note that a URL uses ordinary slashes even though the native (non-URL) form of a path on Windows uses backslashes.
Finally, it should be noted that the Subversion client will automatically encode URLs as necessary, just like a web browser does. For example, if a URL contains a space or upper-ASCII character:
$ svn checkout "http://host/path with space/project/espana"…then Subversion will escape the unsafe characters and behave as if you had typed:
$ svn checkout http://host/path%20with%20space/project/espa%C3%B1aIf the URL contains spaces, be sure to place it within quote marks, so that your shell treats the whole thing as a single argument to the svn program.
Пред. | Уровень выше | След. |
Using External Differencing Tools | Содержание | Глава 8. Информация для разработчиков |
Subversion's use of locales
The Subversion client, svn, honors the current locale configuration in two ways. First, it notices the value of the LC_MESSAGES variable and attempts to print all messages in the specified language. For example:
$ export LC_MESSAGES=de_DE $ svn help cat cat: Gibt den Inhalt der angegebenen Dateien oder URLs aus. Aufruf: cat ZIEL[@REV]... …This behavior works identically on both Unix and Windows systems. Note, though, that while your operating system might have support for a certain locale, the Subversion client still may not be able to speak the particular language. In order to produce localized messages, human volunteers must provide translations for each language. The translations are written using the GNU gettext package, which results in translation modules that end with the .mo filename extension. For example, the German translation file is named de.mo. These translation files are installed somewhere on your system. On Unix, they typically live in /usr/share/locale/, while on Windows they're often found in the \share\locale\ folder in Subversion's installation area. Once installed, a module is named after the program it provides translations for. For example, the de.mo file may ultimately end up installed as /usr/share/locale/de/LC_MESSAGES/subversion.mo. By browsing the installed .mo files, you can see which languages the Subversion client is able to speak.
The second way in which the locale is honored involves how svn interprets your input. The repository stores all paths, filenames, and log messages in Unicode, encoded as UTF-8. In that sense, the repository is internationalized—that is, the repository is ready to accept input in any human language. This means, however, that the Subversion client is responsible for sending only UTF-8 filenames and log messages into the repository. In order to do this, it must convert the data from the native locale into UTF-8.
For example, suppose you create a file namedcaffe.txt, and then when committing the file, you write the log message as «Adesso il caffe e piu forte». Both the filename and log message contain non-ASCII characters, but because your locale is set to it_IT, the Subversion client knows to interpret them as Italian. It uses an Italian character set to convert the data to UTF-8 before sending them off to the repository.
Note that while the repository demands UTF-8 filenames and log messages, it does not pay attention to file contents. Subversion treats file contents as opaque strings of bytes, and neither client nor server makes an attempt to understand the character set or encoding of the contents.
Character set conversion errors
While using Subversion, you might get hit with an error related to character set conversions:
svn: Can't convert string from native encoding to 'UTF-8': … svn: Can't convert string from 'UTF-8' to native encoding: …Errors like this typically occur when the Subversion client has received a UTF-8 string from the repository, but not all of the characters in that string can be represented using the encoding of the current locale. For example, if your locale is en_US but a collaborator has committed a Japanese filename, you're likely to see this error when you receive the file during an svn update.
The solution is either to set your locale to something which can represent the incoming UTF-8 data, or to change the filename or log message in the repository. (And don't forget to slap your collaborator's hand—projects should decide on common languages ahead of time, so that all participants are using the same locale.)
Пред. | Уровень выше | След. |
Vendor branches | Содержание | Using External Differencing Tools |
Subversion в действии
Настало время перейти от абстракций к конкретике. В этом разделе мы покажем реальные примеры использования Subversion.
Svn:eol-style
Unless otherwise noted using a versioned file's svn:mime-type property, Subversion assumes the file contains human-readable data. Generally speaking, Subversion only uses this knowledge to determine if contextual difference reports for that file are possible. Otherwise, to Subversion, bytes are bytes.
This means that by default, Subversion doesn't pay any attention to the type of end-of-line (EOL) markers used in your files. Unfortunately, different operating system use different tokens to represent the end of a line of text in a file. For example, the usual line ending token used by software on the Windows platform is a pair of ASCII control characters—carriage return (CR) and line feed (LF). Unix software, however, just uses the LF character to denote the end of a line.
Not all of the various tools on these operating systems are prepared to understand files that contain line endings in a format that differs from the native line ending style of the operating system on which they are running. Common results are that Unix programs treat the CR character present in Windows files as a regular character (usually rendered as ^M), and that Windows programs combine all of the lines of a Unix file into one giant line because no carriage return-linefeed (or CRLF) character combination was found to denote the end of line.
This sensitivity to foreign EOL markers can become frustrating for folks who share a file across different operating systems. For example, consider a source code file, and developers that edit this file on both Windows and Unix systems. If all the developers always use tools which preserve the line ending style of the file, no problems occur.
But in practice, many common tools either fail to properly read a file with foreign EOL markers, or they convert the file's line endings to the native style when the file is saved. If the former is true for a developer, he has to use an external conversion utility (such as dos2unix or its companion, unix2dos) to prepare the file for editing. The latter case requires no extra preparation. But both cases result in a file that differs from the original quite literally on every line! Prior to committing his changes, the user has two choices. Either he can use a conversion utility to restore the modified file to the same line ending style that it was in before his edits were made. Or, he can simply commit the file—new EOL markers and all.
The result of scenarios like these include wasted time and unnecessary modifications to committed files. Wasted time is painful enough. But when commits change every line in a file, this complicates the job of determining which of those lines were changed in a non-trivial way. Where was that bug really fixed? On what line was a syntax error introduced?
The solution to this problem is the svn:eol-style property. When this property is set to a valid value, Subversion uses it to determine what special processing to perform on the file so that the file's line ending style isn't flip-flopping with every commit that comes from a different operating system. The valid values are:
nativeThis causes the file to contain the EOL markers that are native to the operating system on which Subversion was run. In other words, if a user on a Windows machine checks out a working copy that contains a file with an svn:eol-style property set to native, that file will contain CRLF EOL markers. A Unix user checking out a working copy which contains the same file will see LF EOL markers in his copy of the file.
Note that Subversion will actually store the file in the repository using normalized LF EOL markers regardless of the operating system. This is basically transparent to the user, though.
CRLFThis causes the file to contain CRLF sequences for EOL markers, regardless of the operating system in use.
LFThis causes the file to contain LF characters for EOL markers, regardless of the operating system in use.
CRThis causes the file to contain CR characters for EOL markers, regardless of the operating system in use. This line ending style is not very common. It was used on older Macintosh platforms (on which Subversion doesn't even run).
Svn:executable
Свойство svn:executable для версионированного файла контролирует в полуавтоматическом режиме бит файловой системы, разрешающий исполнение. Это свойство не имеет определенного значения — просто его наличие говорит о необходимости для Subversion выставлять бит разрешения выполнения. Удаление этого свойства востанавливает полный контроль операционной системы над битом выполнения.
На многих операционных системах возможность выполнения файла как команды определяется битом разрешения выполнения. Обычно по умолчанию этот бит не установлен и для файлов которым это необходимо, он должен быть явно установлен пользователем. Файлы в рабочей копии при обновлении создаются каждый раз заново если во время обновления получается новая версия. Это значит, что вы можете установить бит разрешения выполнения, а если при выполнении обновления обновился и этот файл, бит разрешения выполнения может оказаться опять сброшеным. Для таких случаев Subversion и предлагает использовать свойство svn:executable, как способ сохранения бита разрешения выполнения.
Это свойство не имеет ни какой силы на таких файловых системах, как FAT32 и NTFS, не имеющих понятия бита разрешения выполнения[38]. Кроме того, так как оно не имеет определенного значения, при его установке Subversion принудительно устанавливает значение *. Наконец, это свойство действительно только для файлов, не для директорий.
Svn:externals
The svn:externals property contains instructions for Subversion to populate a versioned directory with one or more other checked-out Subversion working copies. For more information on this keyword and its use, see «Externals Definitions».
Svn:ignore
The svn:ignore property contains a list of file patterns which certain Subversion operations will ignore. Perhaps the most commonly used special property, it works in conjunction with the global-ignores run-time configuration option (see «Config») to filter unversioned files and directories out of commands svn status, svn add, and svn import.
The rationale behind the svn:ignore property is easily explained. Subversion does not assume that every file or subdirectory in a working copy directory is intended for version control. Resources must be explicitly placed under Subversion's management using the svn add or svn import commands. As a result, there are often many resources in a working copy that are not versioned.
Now, the svn status command displays as part of its output every unversioned file or subdirectory in a working copy that is not already filtered out by the global-ignores option (or its built-in default value). This is done so that users can see if perhaps they've forgotten to add a resource to version control.
But Subversion cannot possibly guess the names of every resource that should be ignored. Also, quite often there are things that should be ignored in every working copy of a particular repository. To force every user of that repository to add patterns for those resources to their run-time configuration areas would be not just a burden, but has the potential to clash with the configuration needs of other working copies that the user has checked out.
The solution is to store ignore patterns that are unique to the resources likely to appear in a given directory with the directory itself. Common examples of unversioned resources that are basically unique to a directory, yet likely to appear there, include output from program compilations. Or—to use an example more appropriate to this book—the HTML, PDF, or PostScript files generated as the result of a conversion of some source DocBook XML files to a more legible output format.
Ignore Patterns for CVS Users
The Subversion svn:ignore property is very similar in syntax and function to the CVS .cvsignore file. In fact, if you are migrating a CVS working copy to Subversion, you can directly migrate the ignore patterns by using the .cvsignore file as input file to the svn propset command:
$ svn propset svn:ignore -F .cvsignore . property 'svn:ignore' set on '.' $There are, however, some differences in the ways that CVS and Subversion handle ignore patterns. The two systems use the ignore patterns at some different times, and there are slight discrepancies in what the ignore patterns apply to. Also, Subversion does not recognize the use of the ! pattern as a reset back to having no ignore patterns at all.
For this purpose, the svn:ignore property is the solution. Its value is a multi-line collection of file patterns, one pattern per line. The property is set on the directory in which you wish the patterns to be applied. [39] For example, say you have the following output from svn status:
$ svn status calc M calc/button.c ? calc/calculator ? calc/data.c ? calc/debug_log ? calc/debug_log.1 ? calc/debug_log.2.gz ? calc/debug_log.3.gzIn this example, you have made some property modifications to button.c, but in your working copy you also have some unversioned files: the latest calculator program that you've compiled from your source code, a source file named data.c, and a set of debugging output log files. Now, you know that your build system always results in the calculator program being generated. [40] And you know that your test suite always leaves those debugging log files lying around. These facts are true for all working copies, not just your own. And you know that you aren't interested in seeing those things every time you run svn status. So you use svn propedit svn:ignore calc to add some ignore patterns to the calc directory. For example, you might add this as the new value of the svn:ignore property:
calculator debug_log*After you've added this property, you will now have a local property modification on the calc directory. But notice what else is different about your svn status output:
$ svn status M calc M calc/button.c ? calc/data.cNow, all the cruft is missing from the output! Of course, those files are still in your working copy. Subversion is simply not reminding you that they are present and unversioned. And now with all the trivial noise removed from the display, you are left with more interesting items—such as that source code file that you probably forgot to add to version control.
If you want to see the ignored files, you can pass the --no-ignore option to Subversion:
$ svn status --no-ignore M calc/button.c I calc/calculator ? calc/data.c I calc/debug_log I calc/debug_log.1 I calc/debug_log.2.gz I calc/debug_log.3.gzThe list of patterns to ignore is also used by svn add and svn import. Both of these operations involve asking Subversion to begin managing some set of files and directories. Rather than force the user to pick and choose which files in a tree she wishes to start versioning, Subversion uses the ignore patterns to determine which files should not be swept into the version control system as part of a larger recursive addition or import operation.
Svn:keywords
Subversion has the ability to substitute keywords—pieces of useful, dynamic information about a versioned file—into the contents of the file itself. Keywords generally describe information about the last time the file was known to be modified. Because this information changes each time the file changes, and more importantly, just after the file changes, it is a hassle for any process except the version control system to keep the data completely up-to-date. Left to human authors, the information would inevitably grow stale.
For example, say you have a document in which you would like to display the last date on which it was modified. You could burden every author of that document to, just before committing their changes, also tweak the part of the document that describes when it was last changed. But sooner or later, someone would forget to do that. Instead simply ask Subversion to perform keyword substitution on the LastChangedDate keyword. You control where the keyword is inserted into your document by placing a keyword anchor at the desired location in the file. This anchor is just a string of text formatted as $KeywordName$.
All keywords are case-sensitive where they appear as anchors in files: you must use the correct capitalization in order for the keyword to be expanded. You should consider the value of the svn:keywords property to be case-sensitive too—certain keyword names will be recognized regardless of case, but this behavior is deprecated.
Subversion defines the list of keywords available for substitution. That list contains the following five keywords, some of which have aliases that you can also use:
DateThis keyword describes the last time the file was known to have been changed in the repository, and looks something like $Date: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $. It may also be specified as LastChangedDate.
RevisionThis keyword describes the last known revision in which this file changed in the repository, and looks something like $Revision: 144 $. It may also be specified as LastChangedRevision or Rev.
AuthorThis keyword describes the last known user to change this file in the repository, and looks something like $Author: harry $. It may also be specified as LastChangedBy.
HeadURLThis keyword describes the full URL to the latest version of the file in the repository, and looks something like $HeadURL: http://svn.collab.net/repos/trunk/README $. It may be abbreviated as URL.
IdThis keyword is a compressed combination of the other keywords. Its substitution looks something like $Id: calc.c 148 2002-07-28 21:30:43Z sally $, and is interpreted to mean that the file calc.c was last changed in revision 148 on the evening of July 28, 2002 by the user sally.
Simply adding keyword anchor text to your file does nothing special. Subversion will never attempt to perform textual substitutions on your file contents unless explicitly asked to do so. After all, you might be writing a document [41] about how to use keywords, and you don't want Subversion to substitute your beautiful examples of un-substituted keyword anchors!
To tell Subversion whether or not to substitute keywords on a particular file, we again turn to the property-related subcommands. The svn:keywords property, when set on a versioned file, controls which keywords will be substituted on that file. The value is a space-delimited list of the keyword names or aliases found in the previous table.
For example, say you have a versioned file named weather.txt that looks like this:
Here is the latest report from the front lines. $LastChangedDate$ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.With no svn:keywords property set on that file, Subversion will do nothing special. Now, let's enable substitution of the LastChangedDate keyword.
$ svn propset svn:keywords "Date Author" weather.txt property 'svn:keywords' set on 'weather.txt' $Now you have made a local property modification on the weather.txt file. You will see no changes to the file's contents (unless you made some of your own prior to setting the property). Notice that the file contained a keyword anchor for the Rev keyword, yet we did not include that keyword in the property value we set. Subversion will happily ignore requests to substitute keywords that are not present in the file, and will not substitute keywords that are not present in the svn:keywords property value.
Keywords and Spurious Differences
The user-visible result of keyword substitution might lead you to think that every version of a file with that feature in use differs from the previous version in at least the area where the keyword anchor was placed. However, this is actually not the case. While checking for local modifications during svn diff, and before transmitting those local modifications during svn commit, Subversion «un-substitutes» any keywords that it previously substituted. The result is that the versions of the file that are stored in the repository contain only the real modifications that users make to the file.
Immediately after you commit this property change, Subversion will update your working file with the new substitute text. Instead of seeing your keyword anchor $LastChangedDate$, you'll see its substituted result. That result also contains the name of the keyword, and continues to be bounded by the dollar sign ($) characters. And as we predicted, the Rev keyword was not substituted because we didn't ask for it to be.
Note also that we set the svn:keywords property to «Date Author» yet the keyword anchor used the alias $LastChangedDate$ and still expanded correctly.
Here is the latest report from the front lines. $LastChangedDate: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.If someone else now commits a change to weather.txt, your copy of that file will continue to display the same substituted keyword value as before—until you update your working copy. At that time the keywords in your weather.txt file will be re-substituted with information that reflects the most recent known commit to that file.
Svn_load_dirs.pl
Vendor drops that contain more than a few deletes, additions and moves complicate the process of upgrading to each successive version of the third-party data. So Subversion supplies the svn_load_dirs.pl script to assist with this process. This script automates the importing steps we mentioned in the general vendor branch management procedure to make sure that mistakes are minimized. You will still be responsible for using the merge commands to merge the new versions of the third-party data into your main development branch, but svn_load_dirs.pl can help you more quickly and easily arrive at that stage.
In short, svn_load_dirs.pl is an enhancement to svn import that has several important characteristics:
It can be run at any point in time to bring an existing directory in the repository to exactly match an external directory, performing all the necessary adds and deletes, and optionally performing moves, too.
It takes care of complicated series of operations between which Subversion requires an intermediate commit—such as before renaming a file or directory twice.
It will optionally tag the newly imported directory.
It will optionally add arbitrary properties to files and directories that match a regular expression.
svn_load_dirs.pl takes three mandatory arguments. The first argument is the URL to the base Subversion directory to work in. This argument is followed by the URL—relative to the first argument—into which the current vendor drop will be imported. Finally, the third argument is the local directory to import. Using our previous example, a typical run of svn_load_dirs.pl might look like:
$ svn_load_dirs.pl http://svn.example.com/repos/vendor/libcomplex \ current \ /path/to/libcomplex-1.1 …You can indicate that you'd like svn_load_dirs.pl to tag the new vendor drop by passing the -t command-line option and specifying a tag name. This tag is another URL relative to the first program argument.
$ svn_load_dirs.pl -t libcomplex-1.1 \ http://svn.example.com/repos/vendor/libcomplex \ current \ /path/to/libcomplex-1.1 …When you run svn_load_dirs.pl, it examines the contents of your existing «current» vendor drop, and compares them with the proposed new vendor drop. In the trivial case, there will be no files that are in one version and not the other, and the script will perform the new import without incident. If, however, there are discrepancies in the file layouts between versions, svn_load_dirs.pl will prompt you for how you would like to resolve those differences. For example, you will have the opportunity to tell the script that you know that the file math.c in version 1.0 of libcomplex was renamed to arithmetic.c in libcomplex 1.1. Any discrepancies not explained by moves are treated as regular additions and deletions.
The script also accepts a separate configuration file for setting properties on files and directories matching a regular expression that are added to the repository. This configuration file is specified to svn_load_dirs.pl using the -p command-line option. Each line of the configuration file is a whitespace-delimited set of two or four values: a Perl-style regular expression to match the added path against, a control keyword (either break or cont), and then optionally a property name and value.
\.png$ break svn:mime-type image/png \.jpe?g$ break svn:mime-type image/jpeg \.m3u$ cont svn:mime-type audio/x-mpegurl \.m3u$ break svn:eol-style LF .* break svn:eol-style nativeFor each added path, the configured property changes whose regular expression matches the path are applied in order, unless the control specification is break (which means that no more property changes should be applied to that path). If the control specification is cont—an abbreviation for continue—then matching will continue with the next line of the configuration file.
Any whitespace in the regular expression, property name, or property value must be surrounded by either single or double quote characters. You can escape quote characters that are not used for wrapping whitespace by preceding them with a backslash (\) character. The backslash escapes only quotes when parsing the configuration file, so do not protect any other characters beyond what is necessary for the regular expression.
[44] And entirely bug-free, of course!
Пред. | Уровень выше | След. |
Externals Definitions | Содержание | Localization |
Svn:mime-type
Свойство svn:mime-type имеет в Subversion несколько значений. Кроме общего назначения хранения информации о файле согласно Универсальному Расширению Интернет Почты (MIME), значение этого свойства определяет некоторые правила поведения самой Subversion.
Например, если у файла свойство svn:mime-type имеет не текстовый MIME-тип (проще говоря, кроме некоторых исключений, не начинается с чего то вроде text/) Subversion предпологает бинарное — не читаемое — содержимое файла. Одной из положительных характеристик, предлагаемых Subversion, является контекстное, построчное объединение изменений, полученых с сервера при обновлении, с рабочим файлом. Однако файлы, считающиеся бинарными, не имеют понятия «строка». Следовательно для таких файлов, при обновлении, Subversion не пытается выполнить контекстное объединение. Вместо этого, при локально измененной рабочей копии бинарного файла, для которого выполняется обновление, файл рабочей копии переименовывается добавлением расширения .orig, после чего, под первоначальным именем, Subversion сохраняет новую рабочую копию, содержащую изменения, полученные при обновлении и не содержащую ваших собственных изменений. Такой подход используется для того, чтобы защитить пользователя от попыток контекстного объединения файлов, которые просто не могут быть контекстно объединены.
Кроме того, если уствновлено свойство svn:mime-type, Apache-модуль будет использовать это значение при заполнении HTTP заголовка Content-type: при ответе на GET-запросы. Это имеет ключевой значение при определении того, как показывать файл при просмотре хранилища используя web-браузер.
Svn:needs-lock
This property is used to signify that the file it's attached to ought to be locked before editing. The value of the property is irrelevant; Subversion will normalize its value to *. When present, the file will be read-only unless the user has explicitly locked the file. When a lock-token is present (as a result of running svn lock), the file becomes read-write. When the lock is released, the file becomes read-only again.
To learn more about how, when, and why this property should be used, see «Lock Communication».
Svn:special
The svn:special property is the only svn: property that isn't meant to be directly set or modified by users. Subversion automatically sets this property whenever a «special» object is scheduled for addition, such as a symbolic link. The repository stores an svn:special object as an ordinary file. However, when a client sees this property during checkouts or updates, it interprets the contents of the file and translates the item back into the special type of object. In versions of Subversion current at the time of writing, only versioned symbolic links have this property attached, but in future versions of Subversion other special types of nodes will probably use this property as well.
Note: Windows clients don't have symbolic links, and thus ignore any svn:special files coming from a repository that claim to be symbolic links. On Windows, the user ends up with an ordinary versioned file in the working copy.
Svnadmin
svnadmin is the administrative tool for monitoring and repairing your Subversion repository. For detailed information, see «svnadmin».
Since svnadmin works via direct repository access (and thus can only be used on the machine that holds the repository), it refers to the repository with a path, not a URL.
Svnadmin Subcommands
Пред. | Уровень выше | След. |
svn update | Содержание | svnadmin create |
Svnadmin Switches
--bdb-log-keep
(Berkeley DB specific) Disable automatic log removal of database log files.
--bdb-txn-nosync(Berkeley DB specific) Disables fsync when committing database transactions.
--bypass-hooksBypass the repository hook system.
--clean-logsRemoves unused Berkeley DB logs.
--force-uuidBy default, when loading data into repository that already contains revisions, svnadmin will ignore the UUID from the dump stream. This switch will cause the repository's UUID to be set to the UUID from the stream.
--ignore-uuidBy default, when loading an empty repository, svnadmin will use the UUID from the dump stream. This switch will cause that UUID to be ignored.
--incrementalDump a revision only as a diff against the previous revision, instead of the usual fulltext.
--parent-dir DIRWhen loading a dump file, root paths at DIR instead of /.
--revision (-r) ARGSpecify a particular revision to operate on.
--quietDo not show normal progress—show only errors.
--use-post-commit-hookWhen loading a dump file, run the repository's post-commit hook after finalizing each newly loaded revision.
--use-pre-commit-hookWhen loading a dump file, run the repository's pre-commit hook before finalizing each newly loaded revision. If the hook fails, abort the commit and terminate the load process.
Svnlook
svnlook is a command-line utility for examining different aspects of a Subversion repository. It does not make any changes to the repository—it's just used for «peeking». svnlook is typically used by the repository hooks, but a repository administrator might find it useful for diagnostic purposes.
Since svnlook works via direct repository access (and thus can only be used on the machine that holds the repository), it refers to the repository with a path, not a URL.
If no revision or transaction is specified, svnlook defaults to the youngest (most recent) revision of the repository.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svnadmin verifyя | ‘®¤Ґа¦ ЁҐ | яsvnlook author |
Svnlook Switches
Switches in svnlook are global, just like in svn and svnadmin; however, most switches only apply to one subcommand since the functionality of svnlook is (intentionally) limited in scope.
--no-diff-deletedPrevents svnlook from printing differences for deleted files. The default behavior when a file is deleted in a transaction/revision is to print the same differences that you would see if you had left the file but removed all the content.
--revision (-r)Specify a particular revision number that you wish to examine.
--revpropOperates on a revision property instead of a Subversion property specific to a file or directory. This switch requires that you also pass a revision with the --revision (-r) switch. See «Unversioned Properties» for more details on unversioned properties.
--transaction (-t)Specify a particular transaction ID that you wish to examine.
--show-idsShow the filesystem node revision IDs for each path in the filesystem tree.
Мы уже рассмотрели как Subversion
Мы уже рассмотрели как Subversion сохраняет и получает разные версии файлов и директорий из хранилища. Целые главы были посвящены этой самой фундаментальной части функциональных возможностей этого инструмента. И если поддержка версионирования этим ограничится, Subversion все равно останется полноценным инструментом с точки зрения управления версиями. Однако версионирование этим не ограничивается.
Дополнительно к версионированнию директорий и файлов, Subversion предоставляет для каждой версионированной директории и файла интерфейс для добавления, изменения и удаления версионированных метаданных. К этим метаданным мы обращаемся как к свойствам, присоединенным к каждому элементу рабочей копии, которые можно представить в виде таблицы с двумя столбцами, которая сопоставляет имена свойств соответствующим значениям. Вообще, имена и значения свойств могут быть тем, чем вы хотите чтобы они были, за исключением того, что имена должны быть читаемым текстом. И лучшим из всего является то, что они тоже версионированы также как и текстовое содержимое файлов. Можно также просто как и для текстовых изменений изменять, фиксировать и отменять изменения свойств. При обновлении рабочей копии также получаются и изменения свойств.
Еще один тип свойств в Subversion
Подобные приведенным выше, свойства используются и Subversion. Так же как и произвольные имена свойств и соответствующие им значения, имеются у файлов и директорий, каждая правка может иметь произвольные свойства, присоединенные к ней. С теми же исключениями — читаемое, текстовое имя и любое бинарное значение — исключая версионирование свойств правок. Подробнее о таких неверсионированных свойствах см. «Unversioned Properties».
В этом разделе мы рассмотрим полезность — как для пользователя, так и для самой Subversion — поддержки свойств. Вы узнаете о командах svn, относящихся к свойствам и том как модификация свойств влияет на привычный рабочий цикл. Надеемся, вы убедитесь в том, что свойства в Subversion расширяют возможности контроля версий.
Switches
--force --force-log --message (-m) TEXT --file (-F) FILE --quiet (-q) --targets FILENAME --username USER --password PASS --no-auth-cache --non-interactive --editor-cmd EDITOR --encoding ENC --config-dir DIR
--revision (-r) REV --old OLD-TARGET --new NEW-TARGET --extensions (-x) "ARGS" --non-recursive (-N) --diff-cmd CMD --notice-ancestry --username USER --password PASS --no-auth-cache --non-interactive --no-diff-deleted --config-dir DIR
--revision (-r) REV --quiet (-q) --force --username USER --password PASS --no-auth-cache --non-interactive --non-recursive --config-dir DIR --native-eol EOL --ignore-externals
--version --quiet (-q)
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn exportя | ‘®¤Ґа¦ ЁҐ | яsvn import |
--message (-m) TEXT --file (-F) FILE --quiet (-q) --non-recursive (-N) --username USER --password PASS --no-auth-cache --non-interactive --force-log --editor-cmd EDITOR --encoding ENC --config-dir DIR --auto-props --no-auto-props --ignore-externals
--targets FILENAME --recursive (-R) --revision (-r) --config-dir DIR
--revision (-r) REV --verbose (-v) --recursive (-R) --incremental --xml --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--targets ARG --message (-m) ARG --file (-F) ARG --force-log --encoding ARG --username ARG --password ARG --no-auth-cache --non-interactive --config-dir ARG --force
--revision (-r) REV --quiet (-q) --verbose (-v) --targets FILENAME --stop-on-copy --incremental --limit NUM --xml --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--revision (-r) REV --non-recursive (-N) --quiet (-q) --force --dry-run --diff3-cmd CMD --ignore-ancestry --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--message (-m) TEXT --file (-F) FILE --quiet (-q) --username USER --password PASS --no-auth-cache --non-interactive --editor-cmd EDITOR --encoding ENC --force-log --config-dir DIR
--message (-m) TEXT --file (-F) FILE --revision (-r) REV --quiet (-q) --force --username USER --password PASS --no-auth-cache --non-interactive --editor-cmd EDITOR --encoding ENC --force-log --config-dir DIR
--quiet (-q) --recursive (-R) --revision (-r) REV --revprop --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--revision (-r) REV --revprop --username USER --password PASS --no-auth-cache --non-interactive --encoding ENC --editor-cmd EDITOR --config-dir DIR
--recursive (-R) --revision (-r) REV --revprop --strict --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--verbose (-v) --recursive (-R) --revision (-r) REV --quiet (-q) --revprop --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--file (-F) FILE --quiet (-q) --revision (-r) REV --targets FILENAME --recursive (-R) --revprop --username USER --password PASS --no-auth-cache --non-interactive --encoding ENC --force --config-dir DIR
--targets FILENAME --recursive (-R) --quiet (-q) --config-dir DIR
--targets FILENAME --recursive (-R) --quiet (-q) --config-dir DIR
--show-updates (-u) --verbose (-v) --non-recursive (-N) --quiet (-q) --no-ignore --username USER --password PASS --no-auth-cache --non-interactive --config-dir --ignore-externals
--revision (-r) REV --non-recursive (-N) --quiet (-q) --diff3-cmd CMD --relocate --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR
--targets ARG --username ARG --password ARG --no-auth-cache --non-interactive --config-dir ARG --force
--revision (-r) REV --non-recursive (-N) --quiet (-q) --diff3-cmd CMD --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --ignore-externals
--bdb-txn-nosync --bdb-log-keep --config-dir DIR --fs-type TYPE
--revision (-r) --quiet
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svnadmin createя | ‘®¤Ґа¦ ЁҐ | яsvnadmin dump |
--revision (-r) --incremental --quiet --deltas
--clean-logs
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svnadmin helpя | ‘®¤Ґа¦ ЁҐ | яsvnadmin list-dblogs |
--quiet (-q) --ignore-uuid --force-uuid --use-pre-commit-hook --use-post-commit-hook --parent-dir
None
None
--revision (-r) ARG --bypass-hooks
Synopsis
svn delete PATH...svn delete URL...
diff [-r N[:M]] [TARGET[@REV]...]diff [-r N[:M]] --old OLD-TGT[@OLDREV] [--new NEW-TGT[@NEWREV]] [PATH...]diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]
svn export [-r REV] URL[@PEGREV] [PATH]svn export [-r REV] PATH1[@PEGREV] [PATH2]
svn log [PATH]svn log URL [PATH...]
svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]svn merge -r N:M SOURCE[@REV] [WCPATH]
svn mkdir PATH...svn mkdir URL...
svn propdel PROPNAME [PATH...]svn propdel PROPNAME --revprop -r REV [URL]
svn propedit PROPNAME PATH...svn propedit PROPNAME --revprop -r REV [URL]
svn propget PROPNAME [TARGET[@REV]...]svn propget PROPNAME --revprop -r REV [URL]
svn proplist [TARGET[@REV]...]svn proplist --revprop -r REV [URL]
svn propset PROPNAME [PROPVAL | -F VALFILE] PATH...svn propset PROPNAME --revprop -r REV [PROPVAL | -F VALFILE] [URL]
svn switch URL [PATH]switch --relocate FROM TO [PATH...]
svnadmin deltify [-r LOWER[:UPPER]] REPOS_PATH
svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental]
svnadmin hotcopy REPOS_PATH NEW_REPOS_PATH
svnadmin list-dblogs REPOS_PATH
svnadmin list-unused-dblogs REPOS_PATH
svnadmin rmlocks REPOS_PATH LOCKED_PATH...
svnadmin rmtxns REPOS_PATH TXN_NAME...
svnadmin setlog REPOS_PATH -r REVISION FILE
The Apache Portable Runtime Library
Along with Subversion's own datatypes, you will see many references to datatypes that begin with apr_—symbols from the Apache Portable Runtime (APR) library. APR is Apache's portability library, originally carved out of its server code as an attempt to separate the OS-specific bits from the OS-independent portions of the code. The result was a library that provides a generic API for performing operations that differ mildly—or wildly—from OS to OS. While the Apache HTTP Server was obviously the first user of the APR library, the Subversion developers immediately recognized the value of using APR as well. This means that there are practically no OS-specific code portions in Subversion itself. Also, it means that the Subversion client compiles and runs anywhere that the server does. Currently this list includes all flavors of Unix, Win32, BeOS, OS/2, and Mac OS X.
In addition to providing consistent implementations of system calls that differ across operating systems, [48] APR gives Subversion immediate access to many custom datatypes, such as dynamic arrays and hash tables. Subversion uses these types extensively throughout the codebase. But perhaps the most pervasive APR datatype, found in nearly every Subversion API prototype, is the apr_pool_t—the APR memory pool. Subversion uses pools internally for all its memory allocation needs (unless an external library requires a different memory management schema for data passed through its API), [49] and while a person coding against the Subversion APIs is not required to do the same, they are required to provide pools to the API functions that need them. This means that users of the Subversion API must also link against APR, must call apr_initialize() to initialize the APR subsystem, and then must acquire a pool for use with Subversion API calls. See «Programming with Memory Pools» for more information.
The Entries File
Perhaps the single most important file in the .svn directory is the entries file. The entries file is an XML document which contains the bulk of the administrative information about a versioned resource in a working copy directory. It is this one file which tracks the repository URLs, pristine revision, file checksums, pristine text and property timestamps, scheduling and conflict state information, last-known commit information (author, revision, timestamp), local copy history—practically everything that a Subversion client is interested in knowing about a versioned (or to-be-versioned) resource!
Comparing the Administrative Areas of Subversion and CVS
A glance inside the typical .svn directory turns up a bit more than what CVS maintains in its CVS administrative directories. The entries file contains XML which describes the current state of the working copy directory, and basically serves the purposes of CVS's Entries, Root, and Repository files combined.
The following is an example of an actual entries file:
Пример 8.4. Contents of a Typical .svn/entries File
<?xml version="1.0" encoding="utf-8"?> <wc-entries xmlns="svn:"> <entry committed-rev="1" name="" committed-date="2005-04-04T13:32:28.526873Z" url="http://svn.red-bean.com/repos/greek-tree/A/D" last-author="jrandom" kind="dir" uuid="4e820d15-a807-0410-81d5-aa59edf69161" revision="1"/> <entry name="lambda" copied="true" kind="file" copyfrom-rev="1" schedule="add" copyfrom-url="http://svn.red-bean.com/repos/greek-tree/A/B/lambda"/> <entry committed-rev="1" name="gamma" text-time="2005-12-11T16:32:46.000000Z" committed-date="2005-04-04T13:32:28.526873Z" checksum="ada10d942b1964d359e048dbacff3460" last-author="jrandom" kind="file" prop-time="2005-12-11T16:32:45.000000Z"/> <entry name="zeta" kind="file" schedule="add" revision="0"/> <entry name="G" kind="dir"/> <entry name="H" kind="dir" schedule="delete"/> </wc-entries>As you can see, the entries file is essentially a list of entries. Each entry tag represents one of three things: the working copy directory itself (called the «this directory» entry, and noted as having an empty value for its name attribute), a file in that working copy directory (noted by having its kind attribute set to "file"), or a subdirectory in that working copy (kind here is set to "dir"). The files and subdirectories whose entries are stored in this file are either already under version control, or (as in the case of the file named zeta above) are scheduled to be added to version control when the user next commits this working copy directory's changes. Each entry has a unique name, and each entry has a node kind.
Developers should be aware of some special rules that Subversion uses when reading and writing its entries files. While each entry has a revision and URL associated with it, note that not every entry tag in the sample file has explicit revision or url attributes attached to it. Subversion allows entries to not explicitly store those two attributes when their values are the same as (in the revision case) or trivially calculable from [50] (in the url case) the data stored in the «this directory» entry. Note also that for subdirectory entries, Subversion stores only the crucial attributes—name, kind, url, revision, and schedule. In an effort to reduce duplicated information, Subversion dictates that the method for determining the full set of information about a subdirectory is to traverse down into that subdirectory, and read the «this directory» entry from its own .svn/entries file. However, a reference to the subdirectory is kept in its parent's entries file, with enough information to permit basic versioning operations in the event that the subdirectory itself is actually missing from disk.
Типографские соглашения
Моноширинный шрифт
Используется для записи команд, результатов их выполнения и параметров командной строки.
Моноширинный шрифт с курсивомИспользуется в коде и тексте для обозначения подлежащих замене элементов.
КурсивИспользуется для имён файлов и каталогов.
Типовые приемы при использовании веток
Управление версиями чаще всего используется при разработке программного обеспечения, поэтому здесь мы вкратце рассмотрим два, наиболее часто используемые командами программистов, приема ветвления/слияния. Если вы не используете Subversion для разработки программного обеспечения, можете пропустить этот раздел. Если вы разработчик программного обеспечения использующий контроль версий впервые, внимательно присмотритесь, поскольку опытные разработчики считают использование этих приемов хорошим стилем работы. Такие приемы не являются специфичными для Subversion; они применимы к любой системе управления версиями. Тем более, что это поможет увидеть их описание в терминах Subversion.
Типовые примеры использования
Для ветвления и команды svn merge существует множество применений, в этом раздели описаны наиболее типичные из тех с которыми вы можете столкнуться.
Требует доступа к хранилищу
Нет
Да
Да
Да
Нет
Да
Да, если копируемый объект или его копия расположены в хранилище, а так же если необходимо найти исходный номер редакции.
Учитывать или игнорировать происхождение
При общении разработчиков, использующих Subversion очень часто можно услышать упоминание термина происхождение. Это слово используется для описания отношений между двумя объектами хранилища: если между ними есть связь, тогда говорят, что один объект является предком другого.
Например, предположим, что фиксируется правка 100, в которой содержатся изменения файла foo.c. В этом случае файл foo.c@99 является предком файла foo.c@100. С другой стороны, можно допустить, что в правке 101 вы фиксируете удаление foo.c, а затем в правке 102 добавляете новый файл с таким же именем. В таком случае файлы foo.c@99 и foo.c@102 могут выглядеть так, как будто они имеют друг к другу отношение (у них одинаковый путь), однако на самом деле являются полностью независимыми объектами хранилища. Они не имеют ни общей истории, ни общих «предков».
Мы обращаем на это ваше внимание, для того, чтобы указать на важные отличия между svn diff и svn merge. Первая команда игнорирует происхождение, в то время, как вторая его учитывает. Например, если попросить svn diff сравнить правки 99 и 102 файла foo.c вы увидите построчное сравнение; команда diff слепо сравнивает два пути. А вот если вы попросите svn merge сравнить те же объекты, то Subversion предупредит вас о том, что они не связаны друг с другом и сначала попытается удалить старый файл, а затем добавить новый; вывод команды покажет удаление с последующим добавлением:
D foo.c A foo.cВ большинстве случаев при объединении сравниваются деревья, имеющие родственную связь и по умолчанию svn merge рассчитывает на это. Однако иногда, вам будет нужно, что бы команда merge сравнила два не связанных дерева файлов. Например, у вас может быть два импортированных дерева содержащих исходный код релизов программных проектов от сторонних поставщиков (см. «Vendor branches»). Если попросить svn merge сравнить два эти дерева, вы увидите, что первое дерево будет полностью удалено, а затем будет полностью добавлено второе!
В подобных ситуациях вам нужно, чтобы команда svn merge выполняла сравнение основанное только на пути, без учета любых отношений между файлами и директориями. Добавьте опцию --ignore-ancestry при записи команды объединения, после чего эта команда будет вести себя также как svn diff. (И наоборот, опция --notice-ancestry будет заставлять svn diff вести себя как команда merge.)
[14] В будущем, проект Subversion планирует использоваться (или изобрести) расширенным формат представления различий, который будет передавать изменения в структуре дерева файлов и свойств.
Пред. | Уровень выше | След. |
Использование веток | Содержание | Типовые примеры использования |
Understanding locales
Most modern operating systems have a notion of the «current locale»—that is, the region or country whose localization conventions are honored. These conventions—typically chosen by some runtime configuration mechanism on the computer—affect the way in which programs present data to the user, as well as the way in which they accept user input.
On Unix-like systems, you can check the values of the locale-related runtime configuration options by running the locale command:
$ locale LANG= LC_COLLATE="C" LC_CTYPE="C" LC_MESSAGES="C" LC_MONETARY="C" LC_NUMERIC="C" LC_TIME="C" LC_ALL="C"The output is a list of locale-related environment variables and their current values. In this example, the variables are all set to the default C locale, but users can set these variables to specific country/language code combinations. For example, if one were to set the LC_TIME variable to fr_CA, then programs would know to present time and date information formatted according a French-speaking Canadian's expectations. And if one were to set the LC_MESSAGES variable to zh_TW, then programs would know to present human-readable messages in Traditional Chinese. Setting the LC_ALL variable has the effect of changing every locale variable to the same value. The value of LANG is used as a default value for any locale variable that is unset. To see the list of available locales on a Unix system, run the command locale -a.
On Windows, locale configuration is done via the «Regional and Language Options» control panel item. There you can view and select the values of individual settings from the available locales, and even customize (at a sickening level of detail) several of the display formatting conventions.
Update
svn update updates your working copy, and only prints information about files that it updates.
Subversion has combined the CVS P and U codes into just U. When a merge or conflict occurs, Subversion simply prints G or C, rather than a whole sentence about it.
For a more detailed discussion of svn update, see «Обновление рабочей копии».
Пред. | Уровень выше | След. |
More Disconnected Operations | Содержание | Branches and Tags |
URL and Path Requirements
With remote version control operation as the whole point of Subversion's existence, it makes sense that some attention has been paid to internationalization (i18n) support. After all, while «remote» might mean «across the office», it could just as well mean «across the globe.» To facilitate this, all of Subversion's public interfaces that accept path arguments expect those paths to be canonicalized, and encoded in UTF-8. This means, for example, that any new client binary that drives the libsvn_client interface needs to first convert paths from the locale-specific encoding to UTF-8 before passing those paths to the Subversion libraries, and then re-convert any resultant output paths from Subversion back into the locale's encoding before using those paths for non-Subversion purposes. Fortunately, Subversion provides a suite of functions (see subversion/include/svn_utf.h) that can be used by any program to do these conversions.
Also, Subversion APIs require all URL parameters to be properly URI-encoded. So, instead of passing file:///home/username/My File.txt as the URL of a file named My File.txt, you need to pass file:///home/username/My%20File.txt. Again, Subversion supplies helper functions that your application can use—svn_path_uri_encode() and svn_path_uri_decode(), for URI encoding and decoding, respectively.
Using External Differencing Tools
The presence of --diff-cmd and --diff3-cmd options, and similarly named runtime configuration parameters (see «Config»), can lead to a false notion of how easy it is to use external differencing (or «diff») and merge tools with Subversion. While Subversion can use most of popular such tools available, the effort invested in setting this up often turns out to be non-trivial.
The interface between Subversion and external diff and merge tools harkens back to a time when Subversion's only contextual differencing capabilities were built around invocations of the GNU diffutils toolchain, specifically the diff and diff3 utilities. To get the kind of behavior Subversion needed, it called these utilities with more than a handful of options and parameters, most of which were quite specific to the utilities. Some time later, Subversion grew its own internal differencing library, and as a failover mechanism, [45] the --diff-cmd and --diff3-cmd options were added to the Subversion command-line client so users could more easily indicate that they preferred to use the GNU diff and diff3 utilities instead of the newfangled internal diff library. If those options were used, Subversion would simply ignore the internal diff library, and fall back to running those external programs, lengthy argument lists and all. And that's where things remain today.
It didn't take long for folks to realize that having such easy configuration mechanisms for specifying that Subversion should use the external GNU diff and diff3 utilities located at a particular place on the system could be applied toward the use of other diff and merge tools, too. After all, Subversion didn't actually verify that the things it was being told to run were members of the GNU diffutils toolchain. But the only configurable aspect of using those external tools is their location on the system—not the option set, parameter order, etc. Subversion continues throwing all those GNU utility options at your external diff tool regardless of whether or not that program can understand those options. And that's where things get unintuitive for most users.
The key to using external diff and merge tools (other than GNU diff and diff3, of course) with Subversion is to use wrapper scripts which convert the input from Subversion into something that your differencing tool can understand, and then to convert the output of your tool back into a format which Subversion expects—the format that the GNU tools would have used. The following sections cover the specifics of those expectations.
Using Languages Other than C and C++
If you are interested in using the Subversion libraries in conjunction with something other than a C program—say a Python or Perl script—Subversion has some support for this via the Simplified Wrapper and Interface Generator (SWIG). The SWIG bindings for Subversion are located in subversion/bindings/swig and whilst still maturing, they are in a usable state. These bindings allow you to call Subversion API functions indirectly, using wrappers that translate the datatypes native to your scripting language into the datatypes needed by Subversion's C libraries.
There is an obvious benefit to accessing the Subversion APIs via a language binding—simplicity. Generally speaking, languages such as Python and Perl are much more flexible and easy to use than C or C++. The sort of high-level datatypes and context-driven type checking provided by these languages are often better at handling information that comes from users. As you know, humans are proficient at botching up input to a program, and scripting languages tend to handle that misinformation more gracefully. Of course, often that flexibility comes at the cost of performance. That is why using a tightly-optimized, C-based interface and library suite, combined with a powerful, flexible binding language, is so appealing.
Let's look at a sample program that uses Subversion's Python SWIG bindings to recursively crawl the youngest repository revision, and print the various paths reached during the crawl.
Пример 8.2. Using the Repository Layer with Python
#!/usr/bin/python """Crawl a repository, printing versioned object path names.""" import sys import os.path import svn.fs, svn.core, svn.repos def crawl_filesystem_dir(root, directory, pool): """Recursively crawl DIRECTORY under ROOT in the filesystem, and return a list of all the paths at or below DIRECTORY. Use POOL for all allocations.""" # Print the name of this path. print directory + "/" # Get the directory entries for DIRECTORY. entries = svn.fs.svn_fs_dir_entries(root, directory, pool) # Use an iteration subpool. subpool = svn.core.svn_pool_create(pool) # Loop over the entries. names = entries.keys() for name in names: # Clear the iteration subpool. svn.core.svn_pool_clear(subpool) # Calculate the entry's full path. full_path = directory + '/' + name # If the entry is a directory, recurse. The recursion will return # a list with the entry and all its children, which we will add to # our running list of paths. if svn.fs.svn_fs_is_dir(root, full_path, subpool): crawl_filesystem_dir(root, full_path, subpool) else: # Else it's a file, so print its path here. print full_path # Destroy the iteration subpool. svn.core.svn_pool_destroy(subpool) def crawl_youngest(pool, repos_path): """Open the repository at REPOS_PATH, and recursively crawl its youngest revision.""" # Open the repository at REPOS_PATH, and get a reference to its # versioning filesystem. repos_obj = svn.repos.svn_repos_open(repos_path, pool) fs_obj = svn.repos.svn_repos_fs(repos_obj) # Query the current youngest revision. youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj, pool) # Open a root object representing the youngest (HEAD) revision. root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev, pool) # Do the recursive crawl. crawl_filesystem_dir(root_obj, "", pool) if __name__ == "__main__": # Check for sane usage. if len(sys.argv) != 2: sys.stderr.write("Usage: %s REPOS_PATH\n" % (os.path.basename(sys.argv[0]))) sys.exit(1) # Canonicalize (enough for Subversion, at least) the repository path. repos_path = os.path.normpath(sys.argv[1]) if repos_path == '.': repos_path = '' # Call the app-wrapper, which takes care of APR initialization/shutdown # and the creation and cleanup of our top-level memory pool. svn.core.run_app(crawl_youngest, repos_path)This same program in C would need to deal with custom datatypes (such as those provided by the APR library) for representing the hash of entries and the list of paths, but Python has hashes (called «dictionaries») and lists as built-in datatypes, and provides a rich collection of functions for operating on those types. So SWIG (with the help of some customizations in Subversion's language bindings layer) takes care of mapping those custom datatypes into the native datatypes of the target language. This provides a more intuitive interface for users of that language.
The Subversion Python bindings can be used for working copy operations, too. In the previous section of this chapter, we mentioned the libsvn_client interface, and how it exists for the sole purpose of simplifying the process of writing a Subversion client. The following is a brief example of how that library can be accessed via the SWIG bindings to recreate a scaled-down version of the svn status command.
Пример 8.3. A Python Status Crawler
#!/usr/bin/env python """Crawl a working copy directory, printing status information.""" import sys import os.path import getopt import svn.core, svn.client, svn.wc def generate_status_code(status): """Translate a status value into a single-character status code, using the same logic as the Subversion command-line client.""" if status == svn.wc.svn_wc_status_none: return ' ' if status == svn.wc.svn_wc_status_normal: return ' ' if status == svn.wc.svn_wc_status_added: return 'A' if status == svn.wc.svn_wc_status_missing: return '!' if status == svn.wc.svn_wc_status_incomplete: return '!' if status == svn.wc.svn_wc_status_deleted: return 'D' if status == svn.wc.svn_wc_status_replaced: return 'R' if status == svn.wc.svn_wc_status_modified: return 'M' if status == svn.wc.svn_wc_status_merged: return 'G' if status == svn.wc.svn_wc_status_conflicted: return 'C' if status == svn.wc.svn_wc_status_obstructed: return '~' if status == svn.wc.svn_wc_status_ignored: return 'I' if status == svn.wc.svn_wc_status_external: return 'X' if status == svn.wc.svn_wc_status_unversioned: return '?' return '?' def do_status(pool, wc_path, verbose): # Calculate the length of the input working copy path. wc_path_len = len(wc_path) # Build a client context baton. ctx = svn.client.svn_client_ctx_t() def _status_callback(path, status, root_path_len=wc_path_len): """A callback function for svn_client_status.""" # Print the path, minus the bit that overlaps with the root of # the status crawl text_status = generate_status_code(status.text_status) prop_status = generate_status_code(status.prop_status) print '%s%s %s' % (text_status, prop_status, path[wc_path_len + 1:]) # Do the status crawl, using _status_callback() as our callback function. svn.client.svn_client_status(wc_path, None, _status_callback, 1, verbose, 0, 0, ctx, pool) def usage_and_exit(errorcode): """Print usage message, and exit with ERRORCODE.""" stream = errorcode and sys.stderr or sys.stdout stream.write("""Usage: %s OPTIONS WC-PATH Options: --help, -h : Show this usage message --verbose, -v : Show all statuses, even uninteresting ones """ % (os.path.basename(sys.argv[0]))) sys.exit(errorcode) if __name__ == '__main__': # Parse command-line options. try: opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"]) except getopt.GetoptError: usage_and_exit(1) verbose = 0 for opt, arg in opts: if opt in ("-h", "--help"): usage_and_exit(0) if opt in ("-v", "--verbose"): verbose = 1 if len(args) != 1: usage_and_exit(2) # Canonicalize (enough for Subversion, at least) the working copy path. wc_path = os.path.normpath(args[0]) if wc_path == '.': wc_path = '' # Call the app-wrapper, which takes care of APR initialization/shutdown # and the creation and cleanup of our top-level memory pool. svn.core.run_app(do_status, wc_path, verbose)Subversion's language bindings unfortunately tend to lack the level of attention given to the core Subversion modules. However, there have been significant efforts towards creating functional bindings for Python, Perl, and Ruby. To some extent, the work done preparing the SWIG interface files for these languages is reusable in efforts to generate bindings for other languages supported by SWIG (which includes versions of C#, Guile, Java, MzScheme, OCaml, PHP, Tcl, and others). However, some extra programming is required to compensate for complex APIs that SWIG needs some help interfacing with. For more information on SWIG itself, see the project's website at http://www.swig.org/.
[48] Subversion uses ANSI system calls and datatypes as much as possible.
[49] Neon and Berkeley DB are examples of such libraries.
Пред. | Уровень выше | След. |
Глава 8. Информация для разработчиков | Содержание | Inside the Working Copy Administration Area |
Using the APIs
Developing applications against the Subversion library APIs is fairly straightforward. All of the public header files live in the subversion/include directory of the source tree. These headers are copied into your system locations when you build and install Subversion itself from source. These headers represent the entirety of the functions and types meant to be accessible by users of the Subversion libraries.
The first thing you might notice is that Subversion's datatypes and functions are namespace protected. Every public Subversion symbol name begins with svn_, followed by a short code for the library in which the symbol is defined (such as wc, client, fs, etc.), followed by a single underscore (_) and then the rest of the symbol name. Semi-public functions (used among source files of a given library but not by code outside that library, and found inside the library directories themselves) differ from this naming scheme in that instead of a single underscore after the library code, they use a double underscore (__). Functions that are private to a given source file have no special prefixing, and are declared static. Of course, a compiler isn't interested in these naming conventions, but they help to clarify the scope of a given function or datatype.
Установка Subversion
Subversion построена на портабельном слое под названием APR (the Apache Portable Runtime library). Библиотека APR предоставляет все интерфейсы, необходимые для функционирования Subversion под управлением различных операционных систем: доступ к жесткому диску, доступ к сети, управление памятью, и тому подобное. Не смотря на то, что Subversion может использовать Apache как сервер, ее зависимость от Apache не означает того, что Apache является необходимым компонентом. APR представляет собой отдельную библиотеку, которую может использовать любое приложение. Кроме прочего, это означает, что как и Apache, Subversion клиенты и серверы работают на любой операционной системе на которой работает httpd сервер Apache: Windows, Linux, все разновидности BSD, MacOS X, Netware и другие.
Наиболее простой способ получить Subversion - скачать бинарный пакет, собранный для вашей операционной системы. Как правило, эти пакеты присланные волонтерами, доступны для загрузки с веб-сайта Subversion (http://subversion.tigris.org). Сайт обычно содержит графический инсталлятор для пользователей операционных систем Microsoft. Если вы используете Unix-подобную ОС то для получения Subversion вы можете использовать пакетную систему, специфичную для вашей системы (RPM, DEB, ports tree и т. д.).
В качестве альтернативного варианта вы можете построить Subversion прямо из исходного кода. Закачайте с web-сайта Subversion последний source-code релиз. После его распаковки для его сборки следуйте инструкциям в файле INSTALL. Обратите внимание, что такой пакет содержит все необходимое для сборки CLI-клиента способного работать с удаленным хранилищем (обычно это библиотеки apr, apr-util и neon). Однако некоторые опциональные части Subversion имеют много других зависимостей, таких как Berkeley DB и возможно Apache httpd. Если вы хотите выполнить полную сборку, убедитесь, что у вас есть все пакеты, указанные в файле INSTALL. Если вы хотите самостоятельно поработать над Subversion вы можете при помощи вашей клиентской программы вытащить самую последнюю версию исходного кода. Как это сделать описано в «Get the Source Code».
Пред. | Уровень выше | След. |
Архитектура Subversion | Содержание | Компоненты Subversion |
Vendor branches
As is especially the case when developing software, the data that you maintain under version control is often closely related to, or perhaps dependent upon, someone else's data. Generally, the needs of your project will dictate that you stay as up-to-date as possible with the data provided by that external entity without sacrificing the stability of your own project. This scenario plays itself out all the time—anywhere that the information generated by one group of people has a direct effect on that which is generated by another group.
For example, software developers might be working on an application which makes use of a third-party library. Subversion has just such a relationship with the Apache Portable Runtime library (see «The Apache Portable Runtime Library»). The Subversion source code depends on the APR library for all its portability needs. In earlier stages of Subversion's development, the project closely tracked APR's changing API, always sticking to the «bleeding edge» of the library's code churn. Now that both APR and Subversion have matured, Subversion attempts to synchronize with APR's library API only at well-tested, stable release points.
Now, if your project depends on someone else's information, there are several ways that you could attempt to synchronize that information with your own. Most painfully, you could issue oral or written instructions to all the contributors of your project, telling them to make sure that they have the specific versions of that third-party information that your project needs. If the third-party information is maintained in a Subversion repository, you could also use Subversion's externals definitions to effectively «pin down» specific versions of that information to some location in your own working copy directory (see «Externals Definitions»).
But sometimes you want to maintain custom modifications to third-party data in your own version control system. Returning to the software development example, programmers might need to make modifications to that third-party library for their own purposes. These modifications might include new functionality or bug fixes, maintained internally only until they become part of an official release of the third-party library. Or the changes might never be relayed back to the library maintainers, existing solely as custom tweaks to make the library further suit the needs of the software developers.
Now you face an interesting situation. Your project could house its custom modifications to the third-party data in some disjointed fashion, such as using patch files or full-fledged alternate versions of files and directories. But these quickly become maintenance headaches, requiring some mechanism by which to apply your custom changes to the third-party data, and necessitating regeneration of those changes with each successive version of the third-party data that you track.
The solution to this problem is to use vendor branches. A vendor branch is a directory tree in your own version control system that contains information provided by a third-party entity, or vendor. Each version of the vendor's data that you decide to absorb into your project is called a vendor drop.
Vendor branches provide two key benefits. First, by storing the currently supported vendor drop in your own version control system, the members of your project never need to question whether they have the right version of the vendor's data. They simply receive that correct version as part of their regular working copy updates. Secondly, because the data lives in your own Subversion repository, you can store your custom changes to it in-place—you have no more need of an automated (or worse, manual) method for swapping in your customizations.
Versioned Modules
Unlike CVS, a Subversion working copy is aware that it has checked out a module. That means that if somebody changes the definition of a module (e.g. adds or removes components), then a call to svn update will update the working copy appropriately, adding and removing components.
Subversion defines modules as a list of directories within a directory property: see «Externals Definitions».
Пред. | Уровень выше | След. |
Binary Files and Translation | Содержание | Authentication |
Ветки релизов
Большинство программного обеспечения имеет типовой жизненный цикл: написание кода, тестирование, выпуск, повторный цикл. При таком подходе возникают две проблемы. Во-первых, разработчикам необходимо продолжать расширять функциональность в то время, как группа проверки качества будет заниматься тестированием предположительно стабильных версий программы. Во время тестирования не должна останавливаться разработка. Во-вторых, как правило, требуется поддерживать старые, уже выпущенные версии программы; если найдена ошибка в последней версии кода, то скорее всего она присутствует и в уже выпущенных версиях, поэтому пользователи захотят, чтобы эта ошибка была исправлена не дожидаясь выхода новой версии программы.
Здесь-то и может помочь контроль версий. Типичная процедура выглядит примерно так:
Разработчики фиксируют все новое в главную линию разработки. Каждодневные изменения фиксируются в /trunk: новая функциональность, исправление ошибок и тому подобное.
Главная линия разработки копируется в ветку «релиза». Когда команда разработчиков решает, что программа готова к выпуску (скажем, к релизу 1.0), тогда /trunk копируется, например, в /branches/1.0.
Группы продолжают работать параллельно. Одна группа начинает всестороннее тестирование ветки релиза, в то время как вторая группа продолжает работу (скажем, над версией 2.0) в /trunk. Если находятся ошибки в какой-либо из версий, исправления портируются по необходимости в одну или другую сторону. В какой-то момент этот процесс останавливается. Ветка «замораживается» для окончательной проверки перед релизом.
На основе ветки создается метка и выпускается релиз. Когда тестирование завершено, /branches/1.0 копируется в /tags/1.0.0 как справочный снимок. Метка запаковывается и отправляется пользователям.
Ветка продолжает поддерживаться По мере продвижения работы над /trunk для версии 2.0, исправления ошибок продолжают портироваться из /trunk в /branches/1.0. Когда будет накоплено определенной количество исправлений, руководство может решить сделать релиз 1.0.1: /branches/1.0 копируется в /tags/1.0.1, метка пакуется и выпускается.
По мере развития программы эти этапы повторяются: когда работа над 2.0 будет завершена, создается новая ветка релиза 2.0, тестируется, создается метка и в последствии выпускается релиз. После нескольких лет в хранилище будет находиться определенное количество веток релизов, находящихся в режиме «сопровождения» и определенное количество меток, отражающих последние выпущенные ветки.
Since Subversion treats branches and
Since Subversion treats branches and tags as ordinary directories, always remember to check out the trunk (http://svn.example.com/repos/calc/trunk/) of your project, and not the project itself (http://svn.example.com/repos/calc/). If you make the mistake of checking out the project itself, you'll wind up with a working copy that contains a copy of your project for every branch and tag you have.[56]
[56] That is, providing you don't run out of disk space before your checkout finishes.
Пред. | Уровень выше | След. |
Distinction Between Status and Update | Содержание | Metadata Properties |
ЏаҐ¤гЇаҐ¦¤ҐЁҐ, ®в®бп饥бп Є ®Єаг¦ о饬г ⥪бвг.
ЋЎа вЁвҐ ўЁ¬ ЁҐ, зв® ЇаЁ¬Ґал Ёб室®Ј® Є®¤ пў«повбп ўбҐЈ® «Ёим ЇаЁ¬Ґа ¬Ё. •®вп ®Ё Ё ¬®Јгв Ўлвм б®Ўа л б Ї®¬®ймо ®ЇаҐ¤Ґ«сле § Є«Ё Ё© ¤«п Є®¬ЇЁ«пв®а , ў ⥪б⥠ЄЁЈЁ ®Ё ЇаЁў®¤пвбп ¤«п Ё««обва жЁЁ ᮮ⢥вбвўго饩 Їа®Ў«Ґ¬л Ё Ґ ®Ўп§ вҐ«м® б«г¦ в ЇаЁ¬Ґа®¬ е®а®иҐЈ® бвЁ«п Їа®Ја ¬¬Ёа®ў Ёп.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
Љ Є зЁв вм нвг ЄЁЈг?я | ‘®¤Ґа¦ ЁҐ | я‘вагЄвга ЄЁЈЁ |
You can just remove the conflict files and commit, but svn resolved fixes up some bookkeeping data in the working copy administrative area in addition to removing the conflict files, so we recommend that you use this command.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn propsetя | ‘®¤Ґа¦ ЁҐ | яsvn revert |
Be careful when using the --relocate option. If you mistype the argument, you might end up creating nonsensical URLs within your working copy that render the whole workspace unusable and tricky to fix. It's also important to understand exactly when one should or shouldn't use --relocate. Here's the rule of thumb:
If the working copy needs to reflect a new directory within the repository, then use just svn switch.
If the working copy still reflects the same repository directory, but the location of the repository itself has changed, then use svn switch --relocate.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn statusя | ‘®¤Ґа¦ ЁҐ | яsvn unlock |
Revision properties are not under version control, so this command will permanently overwrite the previous log message.
Восстановление удаленных элементов
Отличным свойством системы контроля версия является то, что информация никогда не теряется. При удалении файла или директории, элемент исчезает из правки HEAD но продолжает существовать в более ранних правках. Одним из наиболее частых вопросов, задаваемых новыми пользователями, является такой: «Как мне вернуть назад свой файл или директорию?»
Первым шагом является определение того, какой именно элемент вы пытаетесь восстановить. Неплохой метафорой является представление каждого объекта в хранилище существующим в двухмерной системе координат. Первой координатой является отдельное дерево правок, второй координатой является путь в этом дереве. Таким образом каждая версия файла или директории может быть представлена конкретной парой координат.
Subversion, в отличие от CVS, не имеет директории Attic[16] поэтому для определения необходимой при восстановлении пары координат нужно воспользоваться командой svn log. Лучше всего запустить svn log --verbose в директории, которая содержала удаленный элемент. Параметр --verbose покажет для каждой правки список измененных элементов; все, что вам остается сделать, это найти правку, в которой файл или директория были удалены. Сделать это можно визуально или воспользоваться для обработки вывода каким-то инструментом (grep или может быть последовательным поиском в редакторе).
$ cd parent-dir $ svn log --verbose … ------------------------------------------------------------------------ r808 | joe | 2003-12-26 14:29:40 -0600 (Fri, 26 Dec 2003) | 3 lines Changed paths: D /calc/trunk/real.c M /calc/trunk/integer.c Added fast fourier transform functions to integer.c. Removed real.c because code now in double.c. …В примере предполагается, что вы ищите удаленный файл real.c. Просмотрев логи родительской директории вы определите, что этот файл был удален в правке 808. Следовательно, последняя существовавшая версия файла была в правке, предшествующей этой. Вывод: необходимо из правки 807 восстановить путь /calc/trunk/real.c.
Поиск был сложной задачей. Теперь, когда известно, что нужно восстановить, есть две возможности.
Одним из вариантов является использование svn merge для применения правки 808 «в обратном направлении». (Как отменять изменения мы уже рассматривали, см. «Отмена изменений».) Это приведет к эффекту повторного добавления фала real.c в виде локальных изменений. Файл будет запланирован для добавления и после фиксации будет опять присутствовать в HEAD.
Однако в этом, отдельно взятом примере, это не самое лучшее решение. Повторное применение правки 808 не только добавит файл real.c; лог сообщение показывает, что будут отменены некоторые изменения в integer.c, чего вы не хотите. Конечно, можно выполнить обратное объединение с правкой 808, а затем отменить (svn revert) локальные изменения integer.c, однако такой подход плохо масштабируется. Что если в правке 808 было изменено 90 файлов?
При втором, более целевом методе, svn merge вообще не используется, а вместо этого применяется команда svn copy. Просто скопируете определенные «парой координат» правку и путь из хранилища в рабочую копию:
$ svn copy --revision 807 \ http://svn.example.com/repos/calc/trunk/real.c ./real.c $ svn status A + real.c $ svn commit -m "Resurrected real.c from revision 807, /calc/trunk/real.c." Adding real.c Transmitting file data . Committed revision 1390.Знак плюс в статусе показывает, что элемент не просто запланирован для добавления, а запланирован для добавления «с историей». Subversion запоминает откуда он был скопирован. В будущем, запуск svn log для этого файла будет пересекать восстановление файла и всю историю, предшествующую правке 807. Другими словами, новый файл real.c на самом деле не является новым; он является прямым наследником оригинального, удаленного файла.
Хотя наш пример показывает как восстанавливать файл, обратите внимание, на то что этот подход работает также и для восстановления удаленных директорий.
Возможности Subversion
Обсуждать возможности Subversion удобнее всего в разрезе её улучшений по сравнению с CVS. Суть некоторых рассматриваемых здесь возможностей может быть не совсем понятна читателям, которые плохо знакомы с CVS. Если же вы совсем не имеете представления об управлении версиями, то вам лучше сначала прочитать главу 2, «Основные понятия», где даётся доступное введение в управление версиями.
Subversion предоставляет следующие возможности:
Управление версиями каталоговCVS следит только за историей отдельных файлов, тогда как Subversion использует «виртуальную» файловую систему с возможностями управления версиями, которая способна отслеживать изменения во времени целых деревьев каталогов. Под управление версиями попадают файлы и каталоги.
Настоящая история версийCVS ограничивается управлением версиями файлов, поэтому такие операции, как копирование и переименование, хотя и относящиеся к файлам, но по существу являющиеся изменениями каталогов, содержащих эти файлы, в CVS не поддерживаются. Кроме того, в CVS вы не можете заменить файл, помещённый под управление версиями, другим файлом с тем же именем, но совершенно иным содержанием, возможно никак не связанным со старым объектом, без наследования таким элементом всей истории изменений. Subversion делает возможным добавление, удаление, копирование и переименование как файлов, так и каталогов. При этом каждый вновь добавленный файл начинает жизнь с чистого листа, сохраняя собственную историю изменений.
Атомарные закрепления измененийКаждый набор изменений либо попадает в хранилище целиком, либо не попадает туда вовсе. Это позволяет разработчикам создавать и закреплять изменения логически оправданными кусками, предотвращая тем самым проблемы, которые могут возникать в тех случаях, когда только часть необходимых изменений помещается в хранилище успешно.
Метаданные с версиямиКаждый файл и каталог имеет собственный набор свойств, представленных в виде названия и значения. Вы можете создавать и сохранять любые необходимые пары названий свойств и их значений. Свойства файлов точно так же находятся под управлением версиями, как и их содержимое.
Выбор средств доступа к хранилищу по сетиВ Subversion используется абстракция доступа к хранилищу, что позволяет реализовывать самые разные сетевые механизмы доступа. Subversion может быть подключена к серверу HTTP Apache в виде модуля, что даёт ей огромное преимущество с точки зрения устойчивости работы и способности к взаимодействию, а также предоставляет прямой доступ к существующим возможностям этого сервера, включая установление личности, проверку прав доступа и сжатие информации при передаче. Кроме того, имеется лёгкий самостоятельный сервер Subversion, который использует собственный протокол взаимодействия с клиентами и может легко туннелировать данные через SSH.
Единый способ работы с даннымиSubversion обнаруживает различия между файлами с помощью специального бинарного алгоритма, который одинаково работает как с текстовыми, так и с бинарными файлами. Файлы записываются в хранилище в сжатом виде независимо от их типа, а различия между отдельными версиями могут передаваться по сети в обоих направлениях.
Эффективные ветки и меткиПлата за использование веток и меток не должна быть пропорциональна размеру проекта. Subversion создаёт ветки и метки путём простого копирования проекта, используя механизм, похожий на жёсткие ссылки в файловых системах. Благодаря этому, операции по созданию веток и меток занимают немного времени.
Дружелюбность по отношению к разработчикамSubversion не имеет исторического багажа. Она реализована в виде набора динамических библиотек на языке C, API которых хорошо известен. Это делает Subversion чрезвычайно удобной для сопровождения системой, пригодной для взаимодействия с другими приложениями и языками программирования.
Пред. | Уровень выше | След. |
История Subversion | Содержание | Архитектура Subversion |
WebDAV
WebDAV (shorthand for «Web-based Distributed Authoring and Versioning») is an extension of the standard HTTP protocol designed to make the web into a read/write medium, instead of the basically read-only medium that exists today. The theory is that directories and files can be shared—as both readable and writable objects—over the web. RFCs 2518 and 3253 describe the WebDAV/DeltaV extensions to HTTP, and are available (along with a lot of other useful information) at http://www.webdav.org/.
A number of operating system file browsers are already able to mount networked directories using WebDAV. On Win32, the Windows Explorer can browse what it calls Web Folders (which are just WebDAV-ready network locations) as if they were regular shared folders. Mac OS X also has this capability, as do the Nautilus and Konqueror browsers (under GNOME and KDE, respectively).
How does all of this apply to Subversion? The mod_dav_svn Apache module uses HTTP, extended by WebDAV and DeltaV, as one of its network protocols. Subversion uses mod_dav_svn to map between Subversion's versioning concepts and those of RFCs 2518 and 3253.
For a more thorough discussion of WebDAV, how it works, and how Subversion uses it, see Приложение B, WebDAV и автоматическое управление версиями. Among other things, that appendix discusses the degree to which Subversion adheres to the generic WebDAV specification, and how that affects interoperability with generic WebDAV clients.
Пред. | Уровень выше | След. |
Inside the Working Copy Administration Area | Содержание | Programming with Memory Pools |
Your RA Library Here
For those who wish to access a Subversion repository using still another protocol, that is precisely why the Repository Access Layer is modularized! Developers can simply write a new library that implements the RA interface on one side and communicates with the repository on the other. Your new library can use existing network protocols, or you can invent your own. You could use inter-process communication (IPC) calls, or—let's get crazy, shall we?—you could even implement an email-based protocol. Subversion supplies the APIs; you supply the creativity.
Зачем нужны свойства?
Свойства могут быть очень полезной добавкой к рабочей копии. Фактически, сама Subversion использует свойства для хранения служебной информации и определения того, какие действия необходимо выполнить. Подобным образом и вы можете использовать свойства для своих целей. Конечно, все для чего можно использовать свойства можно делать, используя обычные версионированные файлы, однако обратите внимание на приведенный ниже пример использования Subversion-свойств.
Скажем, вы хотите разработать веб-сайт, содержащий много цифровых фотографий и показывающий их с подписью и датой. Набор этих фотографий постоянно изменяется и вы захотите по возможности максимально автоматизировать этот сайт. Фотографии могут быть большого размера и как обычно делают на таких сайтах, для своих посетителей вам будет необходимо показывать миниатюры изображений. Сделать это вы можете с помощью обычных файлов. То есть рядом, в директории, вы можете иметь файлы image123.jpg и image123-thumbnail.jpg. Подобным образом, отдельно от графического файла, можно хранить и дату. В результате ваше дерево файлов будет захламлено и будет многократно увеличиваться при каждом добавлении на сайт фотографии.
Представим эту же ситуацию при использовании Subversion-свойств файлов. Допустим, имеется файл image123.jpg и у этого файла установлено свойство caption, datestamp и даже thumbnail. В этом случае рабочая копия выглядит гораздо более управляемо — фактически она будет выглядеть так, как-будто она ничего кроме графических файлов не содержит. Однако ваш скрипт автоматизации знает больше. Он знает, что может воспользоваться svn (а еще лучше языковой обвязкой Subversion — см. «Using Languages Other than C and C++») для получения дополнительной, необходимой для показа на сайте информации, не занимаясь чтением индексного файла или играми с путями файлов.
Как (и для чего) использовать Subversion-свойства вы решаете самостоятельно. Как уже говорилось, Subversion имеет свои применения свойств, которые мы рассмотрим в этой главе немного позже. А с начала давйте поговорим как работать со свойствами используя программу svn.
The decision on when to
The decision on when to fire off a contextual diff or merge as part of a larger Subversion operation is made entirely by Subversion, and is affected by, among other things, whether or not the files being operated on are human-readable as determined by their svn:mime-type property. This means, for example, that even if you had the niftiest Microsoft Word-aware differencing or merging tool in the Universe, it would never be invoked by Subversion so long as your versioned Word documents had a configured MIME type that denoted that they were not human-readable (such as application/msword). For more about MIME type settings, see «svn:mime-type»
Џ®б«Ґ¤гойЁ© ЇаЁ¬Ґа ЇаҐ¤Ї®« Ј Ґв «ЁзЁҐ г ў б а Ў®в ойЁе Subversion Є«ЁҐв ¤«п Є®¬ ¤®© бва®ЄЁ svn Ё Ёбва㬥⠤¬ЁЁбваЁа®ў Ёп svnadmin. Ља®¬Ґ нв®Ј® ® а ббзЁв в®, зв® ўл ЁбЇ®«м§гҐвҐ Subversion ўҐабЁЁ 1.2 Ё«Ё Ў®«ҐҐ Ї®§¤Ґ© (¤«п в®Ј®, зв®Ўл нв® Їа®ўҐаЁвм, ўлЇ®«ЁвҐ svn --version).
Subversion еа Ёв ўбо ўҐабЁ®Ёа®ў го Ёд®а¬ жЁо ў жҐва «м®¬ еа Ё«ЁйҐ. „«п з « , ᮧ¤ ¤Ё¬ ®ў®Ґ еа Ё«ЁйҐ:
$ svnadmin create /path/to/repos $ ls /path/to/repos conf/ dav/ db/ format hooks/ locks/ README.txt ќв Є®¬ ¤ ᮧ¤ Ґв ®ўго ¤ЁаҐЄв®аЁо /path/to/repos ᮤҐа¦ йго Subversion еа Ё«ЁйҐ. “ЎҐ¤ЁвҐбм, зв® нв ¤ЁаҐЄв®аЁп 室Ёвбп «®Є «м®¬ ¤ЁбЄҐ, Ґ бҐвҐў®© и аҐ. ЏаҐЁ¬гйҐб⢥® ў нв ®ў п ¤ЁаҐЄв®аЁп (Єа®¬Ґ Їа®зҐЈ®) ᮤҐа¦Ёв Ў®а д ©«®ў Ў §л ¤ ле. ‚л Ґ гўЁ¤ЁвҐ бў®Ёе ўҐабЁ®Ёа®ў ле д ©«®ў Ґб«Ё ўл § Ј«пЁвҐ ўгвам. Ѓ®«миҐ Ёд®а¬ жЁЁ ® ᮧ¤ ЁЁ Ё Ї®¤¤Ґа¦ЄҐ еа Ё«Ёй ЁйЁвҐ ў ѓ« ў я5, Ђ¤¬ЁЁбваЁа®ў ЁҐ еа Ё«Ёй .
“ Subversion Ґв Ї®пвЁп <Їа®ҐЄв>. •а Ё«ЁйҐ пў«пҐвбп Їа®бв® ўЁавг «м®© ўҐабЁ®Ёа®ў ®© д ©«®ў®© бЁб⥬®©, Ў®«м讥 ¤ҐаҐў® д ©«®ў, Є®в®а®Ґ ¬®¦Ґв ᮤҐа¦ вм ўбҐ, зв® гЈ®¤®. Ћ¤Ё ¤¬ЁЁбва в®ал ЇаҐ¤Ї®зЁв ов ¤Ґа¦ вм ў еа Ё«ЁйҐ в®«мЄ® ®¤Ё Їа®ҐЄв, ¤агЈЁҐ ¤Ґа¦ вм ў еа Ё«ЁйҐ ¬®¦Ґбвў® Їа®ҐЄв®ў, а §¬Ґй п Ёе ў ®в¤Ґ«мле ¤ЁаҐЄв®аЁпе. „®бв®Ёбвў Є ¦¤®Ј® Ё§ Ї®¤е®¤®ў а бᬮваҐл ў
‚ н⮬ ЇаЁ¬ҐаҐ ¬л Ї®¤а §г¬Ґў Ґ¬ «ЁзЁҐ г ў б Є Є®Ј® в® Їа®ҐЄв ( Ў®а д ©«®ў Ё«Ё ¤ЁаҐЄв®аЁ©), Є®в®ал© ўл е®вЁвҐ Ё¬Ї®авЁа®ў вм ў в®«мЄ® з⮠ᮧ¤ ®Ґ Subversion еа Ё«ЁйҐ. Ќ зЁвҐ б ®ЎкҐ¤ЁҐЁп Ёе ў ®в¤Ґ«м®© ¤ЁаҐЄв®аЁЁ §ў ®© myproject (Ё«Ё Є Є-в® Ё зҐ). Џ® ЇаЁзЁ ¬, Є®в®алҐ Ўг¤гв пбл Ї®§¦Ґ (б¬. ѓ« ў я4, ‚Ґвў«ҐЁҐ Ё б«ЁпЁҐ), ў иҐ ¤ҐаҐў® Їа®ҐЄв ¤®«¦® ᮤҐа¦ вм ваЁ ¤ЁаҐЄв®аЁЁ ўҐа奣® га®ўп б §ў Ёп¬Ё branches, tags Ё trunk. ‚бп ў и Ёд®а¬ жЁп ¤®«¦ 室Ёвмбп ў ¤ЁаҐЄв®аЁЁ trunk, ¤ЁаҐЄв®аЁЁ branches Ё tags ¤®«¦л Ўлвм Їгбвл¬Ё:
/tmp/myproject/branches/ /tmp/myproject/tags/ /tmp/myproject/trunk/ foo.c bar.c Makefile : €бЇ®«м§®ў вм Ї®¤¤ЁаҐЄв®аЁЁ branches, tags Ё trunk Ґ ®Ўп§ ⥫м®. Џа®бв® в Є®© Ї®¤е®¤ з йҐ ўбҐЈ® ЁбЇ®«м§гҐвбп Ё ўҐа®п⥥ ўбҐЈ® ў ¤ «мҐ©иҐ¬ ўл Ўг¤ҐвҐ ЁбЇ®«м§®ў вм Ё¬Ґ® ҐЈ®.
Љ Є в®«мЄ® ўл Ї®«гзЁвҐ Ј®в®ў®Ґ ¤ҐаҐў® ¤ ле, Ё¬Ї®авЁаг©вҐ ҐЈ® ў еа Ё«ЁйҐ ЇаЁ Ї®¬®йЁ Є®¬ ¤л svn import (б¬.
$ svn import /tmp/myproject file:///path/to/repos/myproject -m "initial import" Adding /tmp/myproject/branches Adding /tmp/myproject/tags Adding /tmp/myproject/trunk Adding /tmp/myproject/trunk/foo.c Adding /tmp/myproject/trunk/bar.c Adding /tmp/myproject/trunk/Makefile : Committed revision 1. $ ’ҐЇҐам ў еа Ё«ЁйҐ 室Ёвбп нв® ¤ҐаҐў® ¤ ле. Љ Є Ўл«® ®в¬ҐзҐ® а ҐҐ, ўл Ґ гўЁ¤ЁвҐ бў®Ёе д ©«®ў Ґб«Ё § Ј«пЁвҐ ў еа Ё«ЁйҐ Їап¬го; ўбҐ еа Ёвбп ў Ў §Ґ ¤ ле. Ћ¤ Є® ᥩз б ў®®Ўа ¦ Ґ¬ п д ©«®ў п бЁб⥬л еа Ё«Ёй Ё¬ҐҐв ¤ЁаҐЄв®аЁо ўҐа奣® га®ўп б §ў ЁҐ¬ myproject Є®в®а п ᮤҐа¦Ёв ў иг Ёд®а¬ жЁо.
ЋЎа вЁвҐ ўЁ¬ ЁҐ в®, зв® ЇҐаў® з «м п ¤ЁаҐЄв®аЁп /tmp/project ®бв Ґвбп ЎҐ§ Ё§¬ҐҐЁ©; Subversion ® Ґ© Ґ § Ґв. (” ЄвЁзҐбЄЁ, ЇаЁ ¦Ґ« ЁЁ, ўл ¬®¦ҐвҐ ¤ ¦Ґ г¤ «Ёвм нв®в Є в «®Ј.) —в®Ўл з вм а Ў®в вм б Ёд®а¬ жЁҐ© еа Ё«Ёй ў ¬ 㦮 ᮧ¤ вм ®ўго <а Ў®зго Є®ЇЁо> Ёд®а¬ жЁЁ, бў®ҐЈ® த з б⮥ а Ў®зҐҐ Їа®бва бвў®. Џ®Їа®бЁвҐ Subversion ᮧ¤ вм а Ў®зго Є®ЇЁо ¤ЁаҐЄв®аЁЁ myproject/trunk еа Ё«Ёй :
$ svn checkout file:///path/to/repos/myproject/trunk myproject A myproject/foo.c A myproject/bar.c A myproject/Makefile : Checked out revision 1. ‘Ґ©з б г ў б ў ®ў®© ¤ЁаҐЄв®аЁЁ myproject Ґбвм «Ёз п Є®ЇЁп з бвЁ еа Ё«Ёй . ‚ а Ў®зҐ© Є®ЇЁЁ ўл ¬®¦ҐвҐ । ЄвЁа®ў вм д ©«л, § ⥬ § дЁЄбЁа®ў вм ўҐбҐлҐ Ё§¬ҐҐЁп ў еа Ё«ЁйҐ.
ЋвЄа®©вҐ бў®о а Ў®зго Є®ЇЁо Ё ®в। ЄвЁаг©вҐ ᮤҐа¦Ё¬®Ґ д ©«®ў.
‚лЇ®«ЁвҐ svn diff зв®Ўл гўЁ¤Ґвм ®ЎкҐ¤ЁҐл© diff ўҐбҐле Ё§¬ҐҐЁ©.
‚лЇ®«ЁвҐ svn commit ¤«п дЁЄб жЁЁ ®ў®© ўҐабЁЁ ў иЁе д ©«®ў ў еа Ё«ЁйҐ.
‚лЇ®«ЁвҐ svn update ¤«п ЇаЁўҐ¤ҐЁп а Ў®зҐ© Є®ЇЁЁ ў < Єв㠫쮥> б®бв®пЁҐ Ї® ®в®иҐЁо Є еа Ё«Ёйг.
„«п Ї®«гзҐЁп Ї®«®Ј® бЇЁбЄ ў®§¬®¦ле ¤Ґ©бвўЁ© б а Ў®зҐ© Є®ЇЁҐ© Їа®звЁвҐ ѓ« ў я3, ќЄбЄгабЁп Ї® Subversion.
Џ®б«Ґ нв®Ј® ўл ¬®¦ҐвҐ ᤥ« вм ў иҐ еа Ё«ЁйҐ ¤®бвгЇл¬ ¤«п ¤агЈЁе зҐаҐ§ бҐвм. ‘¬. ѓ« ў я6, Ќ бва®©Є бҐаўҐа ¤«п § Є®¬бвў б а §«Ёзл¬Ё вЁЇ ¬Ё ¤®бвгЇле бҐаўҐале Їа®жҐбб®ў Ё ¬Ґв®¤ ¬Ё Ёе бва®©ЄЁ.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
Љ®¬Ї®Ґвл Subversionя | ‘®¤Ґа¦ ЁҐ | яѓ« ў 2. Ћб®ўлҐ Ї®пвЁп |
‡ ¬Ґз ЁҐ, ®в®бп饥бп Є ®Єаг¦ о饬г ⥪бвг.
‚л ¬®¦ҐвҐ Є®ЇЁа®ў вм д ©«л в®«мЄ® ўгваЁ ®¤®Ј® еа Ё«Ёй . Subversion Ґ Ї®¤¤Ґа¦Ёў Ґв ¬Ґ¦еа Ё«Ёй®Ј® Є®ЇЁа®ў Ёп.
Subversion does not support moving between working copies and URLs. In addition, you can only move files within a single repository-Subversion does not support cross-repository moving.
WC -> WCMove and schedule a file or directory for addition (with history).
URL -> URLComplete server-side rename.
By default, you cannot modify revision properties in a Subversion repository. Your repository administrator must explicitly enable revision property modifications by creating a hook named pre-revprop-change. See
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn proplistя | ‘®¤Ґа¦ ЁҐ | яsvn resolved |
If you provide no targets to svn revert, it will do nothing-to protect you from accidentally losing changes in your working copy, svn revert requires you to provide at least one target.
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn resolvedя | ‘®¤Ґа¦ ЁҐ | яsvn status |
--show-updates only places an asterisk next to items that are out of date (that is, items that will be updated from the repository if you run svn update). --show-updates does not cause the status listing to reflect the repository's version of the item.
And finally, the most information you can get out of the status subcommand:
$ svn status --show-updates --verbose wc M 965 938 sally wc/bar.c * 965 922 harry wc/foo.c A + 965 687 harry wc/qax.c 965 687 harry wc/zig.c Head revision: 981 For many more examples of svn status, see
ЏаҐ¤.я | “а®ўҐм ўлиҐ | я‘«Ґ¤. |
svn revertя | ‘®¤Ґа¦ ЁҐ | яsvn switch |