Ключевые идеи, стоящие за ветками


Два важных понятия, которые вы должны запомнить из этого раздела.

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

Subversion не имеет такого понятия как ветка — есть только копии. При копировании директории результирующая директория становиться «веткой» только потому что вы рассматриваете ее таким образом. Вы можете по-разному думать о директории, по разному ее трактовать, но для Subversion это просто обычная директория которая была создана копированием.


[13] Subversion не поддерживает возможность копирования между хранилищами. При использовании в командах svn copy или svn move URL, можно копировать только элементы из одного и того же хранилища.

Пред. Уровень выше След.
Глава 4. Ветвление и слияние Содержание Копирование изменений между ветками


Ключевые понятия, стоящие за слиянием


Вы увидели примеры использования svn merge, продолжим рассмотрение. Если вы чувствуете не уверенность в том как собственно работает слияние, то в этом вы не одиноки. Многие пользователи (особенно те, для которых управление версиями в новинку) поначалу путаются в правильности записи этой команды и в том, как и когда эту функцию следует использовать. Отбросьте страх, на самом деле эта команда намного проще чем вы думаете! Очень просто понять механизм того, как именно ведет себя svn merge.

В замешательство приводит, главным образом название команды. Термин «слияние» как бы указывает на то, что ветки соединяются вместе, или происходит какое-то волшебное смешивание данных. На самом деле это не так. Лучшим названием для этой команды могло быть svn diff-and-apply потому что это все, что происходит: сравниваются два файловых дерева хранилища, а различия переносятся в рабочую копию.

Команда принимает три аргумента:

Начальное дерево хранилища (как правило, называемое левой частью при сравнении),

Конечное дерево хранилища (как правило называемое правой частью при сравнении),

Рабочую копию для применения отличий, в виде локальных изменений (как правило, называемую целью слияния).

Когда эти три аргумента указаны, сравниваются два дерева и результирующие различия применяются к целевой рабочей копии в виде локальных изменений. После того, как команда выполнена, результат не будет отличаться он того как если бы вы вручную редактировали файлы или многократно выполняли команды svn add или svn delete самостоятельно. Если результат вас устраивает, его можно зафиксировать. Если результат вас не устраивает, просто отмените (svn revert) все сделанные изменения.

Правила записи svn merge позволяют указывать три необходимых аргумента довольно гибко. Вот несколько примеров:

$ svn merge http://svn.example.com/repos/branch1@150 \ http://svn.example.com/repos/branch2@212 \ my-working-copy $ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy $ svn merge -r 100:200 http://svn.example.com/repos/trunk

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



Компоненты Subversion


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

svn

CLI-клиент.

svnversion

Программа показывающая состояние (в пределах ревизий существующих элементов) рабочей копии.

svnlook

Инструмент для контроля Subversion хранилища.

svnadmin

Инструмент для создания, настройки или восстановления Subversion хранилища.

svndumpfilter

Программа для фильтрации дамповых потоков Subversion хранилища.

mod_dav_svn

Подключаемый модуль для HTTP сервера Apache, использующийся для предоставления сетевого доступа к вашему хранилищу.

svnserve

Собственный отдельный сервер, запускается как процесс-демон и доступен посредством SSH; еще один способ для предоставления сетевого доступа к хранилищу.

При условии корректно установленной Subversion вы готовы к старту. Следующие две главы описывают использование svn, CLI-клиента Subversion.

Пред. Уровень выше След.
Установка Subversion Содержание Быстрый старт


Конфигурация и реестр Windows


В дополнение к обычным INI-настройкам, Subversion-клиент, работающий на платформе Windows, может использовать для хранения настроек Windows-реестр. Имена параметров и их значения точно такие же, как и в INI-файлах. Иерархия «файлов» сохраняется, только немного меняется способ адресации — файлы и разделы просто заменяются уровнями в дереве ключей реестра.

За общесистемными настройками Subversion обращается к ключу HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion Например, параметр global-ignores, находящийся в разделе miscellany файла config будет находиться в HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Config\Miscellany\global-ignores. Пользовательские настройки хранятся в ключе HKEY_CURRENT_USER\Software\Tigris.org\Subversion.

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

Параметры командной строки

Пользовательские INI-файлы

Параметры в реестре

Системные INI-файлы

Общесистемные параметры в реестре

Кроме того, реестр Windows не поддерживает механизма «комментирования». Тем не менее, Subversion игнорирует параметры, у которых имена начинаются с символа «решетка» (#). Это позволяет закомментировать параметр, не удаляя ключ из реестра, что значительно упрощает процесс восстановления этого параметра.

Клиент для командной строки svn никогда ничего не записывает и не создает первоначальные «умолчательные» параметры в реестре Windows. Нужные вам ключи вы можете создать используя программу REGEDIT. Либо, можно создать .reg-файл и двойным щелчком на этом файле в Explorer добавить информацию в реестр.

Пример 7.1. Пример указания параметров в (.reg) файле реестра.

REGEDIT4 [HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\groups]

[HKEY_LOCAL_MACHINE\Software\Tigris.org\Subversion\Servers\global] "#http-proxy-host"="" "#http-proxy-port"="" "#http-proxy-username"="" "#http-proxy-password"="" "#http-proxy-exceptions"="" "#http-timeout"="0" "#http-compression"="yes" "#neon-debug-mask"="" "#ssl-authority-files"="" "#ssl-trust-default-ca"="" "#ssl-client-cert-file"="" "#ssl-client-cert-password"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auth] "#store-auth-creds"="no" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\helpers] "#editor-cmd"="notepad" "#diff-cmd"="" "#diff3-cmd"="" "#diff3-has-program-arg"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\miscellany] "#global-ignores"="*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store" "#log-encoding"="" "#use-commit-times"="" "#template-root"="" "#enable-auto-props"="" [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\tunnels] [HKEY_CURRENT_USER\Software\Tigris.org\Subversion\Config\auto-props]

В предыдущем примере показано содержимое .reg-файла, содержащего часто используемые параметры и их значения по умолчанию. Обратите внимание, что приведены как общесистемные (сетевые настройки, относящиеся к прокси-серверу) и пользовательские параметры (программы-редакторы и сохранение паролей, среди прочего). Так же обратите внимание, что все параметры закомментированы. Необходимо будет просто удалить символ «решетка» (#) и установить нужное значение.



Конфликты при объединении


Так же как и команда svn update, svn merge внедряет изменения в рабочую копию. А следовательно тоже может создавать конфликты. Однако конфликты, создаваемые svn merge иногда отличаются и эти отличия рассмотрены в этом разделе.

В начале будем считать, что рабочая копия не имеет локальных изменений. При обновлении (svn update) до конкретной правки, изменения, отправляемые сервером, будут всегда «без проблем» внедрятся в рабочую копию. Сервер создает дельту сравнивая два дерева: виртуальный снимок рабочей копии и дерево файлов, которое вас интересует. Учитывая то, что левая часть сравнения полностью эквивалентна тому, что вы уже имеете, дельта гарантированно правильно конвертирует рабочую копию в правую часть сравнения.

Однако svn merge не может этого гарантировать и может вести себя более хаотично: пользователь может запросить сервер сравнить любые два дерева файлов, даже такие, которые не имеют отношения к рабочей копии! Из этого следует большое количество потенциальных человеческих ошибок. Пользователи иногда будут сравнивать два ошибочных дерева создавая дельту которая не сможет правильно внедриться. svn merge будет пытаться внедрить по возможности больше различий, но иногда это будет не возможно. Так же как команда patch в Unix иногда жалуется на «неудачные попытки» объединения, svn merge будет жаловаться на «пропущенные цели»:

$ svn merge -r 1288:1351 http://svn.example.com/repos/branch U foo.c U bar.c Skipped missing target: 'baz.c' U glub.c C glorb.h $

Возможно, что в предыдущем примере файл baz.c существует в обоих сравниваемых снимках ветки и Subversion пытается применить результирующую дельту для того, чтобы изменить содержимое файла, однако в рабочей копии файл отсутствует. В любом случае сообщение «skipped» означает, что скорее всего пользователь ошибся при указании деревьев для сравнения; классическая ошибка оператора. Если это произошло, то проще всего рекурсивно отменить все изменения, сделанные при слиянии (svn revert --recursive), сразу же после этого удалить все не версионированные файлы и директории и повторно запустить svn merge с другими параметрами.

Обратите внимание на то, что в предыдущем примере в файле glorb.h возник конфликт. Ранее мы договорились, что рабочая копия не имеет локальных изменений: откуда же взялся конфликт? Опять же, так как пользователь мог запустить svn merge для выделения и применения к рабочей копии какой то старой дельты, в результате, такая дельта может содержать изменения, которые не смогут внедриться в рабочий файл без появления проблем, даже если он не имеет локальных изменений.

Еще одно небольшое отличием между svn update и svn merge заключается в названиях файлов, создаваемых при возникновении конфликта. В разделе «Решение конфликтов (при объединении с чужими изменениями)» мы говорили о том, что при обновлении создаются файлы с названиями filename.mine, filename.rOLDREV, и filename.rNEWREV. А svn merge в конфликтной ситуации создает три файла с названиями filename.working, filename.left и filename.right. Здесь, термины «left» и «right» указывают на две стороны сравнения, то есть на используемые при сравнении деревья. Это разделение используемых названий поможет вам отличать конфликты возникшие в результате обновления от конфликтов, возникших в результате объединения.



Копирование изменений между ветками


Сейчас вы и Салли работаете над параллельными ветками проекта: вы работаете над своей собственной веткой, а Салли работает над главной линией разработки (trunk).

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

Положительным моментом является то, что вы и Салли не пересекаетесь друг с другом. Отрицательный момент в том, что вы можете разойтись слишком далеко друг относительно друга. Помните, что одной из проблем такой «сходящейся к тупику» стратегии является то, что к моменту, когда вы закончите работу со своей веткой может быть практически невозможно снова объединить ваши изменения с главной линией без огромного количества конфликтов.

Вместо этого вы и Салли можете продолжать делиться изменениями по ходу работы. Вы можете решать вплоть до отдельного изменения, стоит ли им делиться; Subversion предоставляет возможность выборочного «копирования» изменений между ветками. А тогда, когда ваша ветка будет полностью закончена, полный набор изменений ветки может быть скопирован обратно в основную ветку.



Копирование отдельных изменений


В предыдущем пункте мы указали, что и вы и Салли, в месте, в разных ветках вносите изменения в integer.c. Если посмотреть на лог сообщение Салли для правки 344, вы увидите, что она исправила несколько орфографических ошибок. Конечно же, в вашей копии этого файла эти ошибки остались. Возможно, что ваши будущие изменения для этого файла коснутся областей которые содержат орфографические ошибки и таким образом вы получите несколько потенциальных конфликтов при последующем объединении вашей ветки. Поэтому, лучше получить изменения Салли сейчас, до того, как вы начнете вплотную работать в этих областях файла.

Настал момент воспользоваться командой svn merge. Эта команда, оказывается, является очень близким родственником команды svn diff (о которой вы читали Главе 3). Обе эти команды способны сравнивать любые два объекта в хранилище и показывать изменения. Например, вы можете попросить svn diff показать все изменения сделанные Салли в правке 344:

$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk Index: integer.c =================================================================== --- integer.c (revision 343) +++ integer.c (revision 344) @@ -147,7 +147,7 @@ case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break; case 7: sprintf(info->operating_system, "Macintosh"); break; case 8: sprintf(info->operating_system, "Z-System"); break; - case 9: sprintf(info->operating_system, "CPM"); break; + case 9: sprintf(info->operating_system, "CP/M"); break; case 10: sprintf(info->operating_system, "TOPS-20"); break; case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break; case 12: sprintf(info->operating_system, "QDOS"); break; @@ -164,7 +164,7 @@ low = (unsigned short) read_byte(gzfile); /* read LSB */ high = (unsigned short) read_byte(gzfile); /* read MSB */ high = high << 8; /* interpret MSB correctly */ - total = low + high; /* add them togethe for correct total */ + total = low + high; /* add them together for correct total */ info->extra_header = (unsigned char *) my_malloc(total); fread(info->extra_header, total, 1, gzfile); @@ -241,7 +241,7 @@ Store the offset with ftell() ! */ if ((info->data_offset = ftell(gzfile))== -1) { - printf("error: ftell() retturned -1.\n"); + printf("error: ftell() returned -1.\n"); exit(1); } @@ -249,7 +249,7 @@ printf("I believe start of compressed data is %u\n", info->data_offset); #endif - /* Set postion eight bytes from the end of the file. */ + /* Set position eight bytes from the end of the file. */ if (fseek(gzfile, -8, SEEK_END)) { printf("error: fseek() returned non-zero\n");

Команда svn merge ведет себя практически полностью идентично. Но вместо вывода различий на терминал, применяет их к рабочей копии в виде локальных изменений:

$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status M integer.c

Вывод команды svn merge показывает, что к вашей копии integer.c был применен патч. Теперь она содержит изменения Салли — изменения Салли были «скопированы» из главной линии разработки в вашу рабочую копию, вашей личной ветки и теперь существуют в виде локальных изменений. С этого момента вы можете просмотреть локальные изменения и убедиться в том, что они корректно работают.

По другому сценарию, возможно, что не все будет так хорошо и integer.c может оказаться в состоянии конфликта. Вам необходимо будет при помощи стандартной процедуры (см. Главу 3) решить конфликт, либо если вы прейдете к мнению, что объединение было плохой идеей, просто отказаться от него, отменив локальные изменения командой svn revert.

После просмотра результата объединения изменений, можно их как обычно зафиксировать (svn commit). После этого изменения будут внесены в вашу ветку хранилища. В терминах контроля версий такую процедуру копирования изменений между ветками обычно называют портированием изменений.

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

$ svn commit -m "integer.c: ported r344 (spelling fixes) from trunk." Sending integer.c Transmitting file data . Committed revision 360.

Как вы увидите в последующих разделах, очень важно следовать подобному «хорошему стилю» организации работы.

Почему бы не использовать вместо этого патчи?

Вопрос, который может крутиться у вас в голове, особенно если вы пользователь Unix: зачем вообще связываться с svn merge? Почему просто не использовать команду операционной системы patch для выполнения этой работы? Например:

$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk > patchfile $ patch -p0 < patchfile Patching file integer.c using Plan A... Hunk #1 succeeded at 147. Hunk #2 succeeded at 164. Hunk #3 succeeded at 241. Hunk #4 succeeded at 249. done

Для этого конкретного случая, да, действительно разницы нет. Однако, svn merge имеет специфические функции благодаря которым превосходит программу patch. Формат файлов, используемый программой patch довольно таки ограниченный; он способен передавать только изменения содержимого файлов. Он не имеет способа для представления изменений дерева файлов, таких, как добавление, удаление или переименование файлов и директорий. Если скажем, в результате изменений Салли, добавилась новая директория то в выводе svn diff упоминания об этом не будет. Вывод svn diff представляет собой только ограниченный патч-формат, по этому некоторые понятия он просто не может передать. [14] Команда svn merge, напротив, может передавать изменения в структуре файлов и свойств, непосредственно применяя их к рабочей копии.

Небольшое предупреждение: несмотря на то, что svn diff и svn merge очень похожи в основе, в большинстве случаев они имеют разные правила записи. Обязательно прочтите об этом в Главе 9, или спросите у svn help. Например, svn merge требует в качестве целевого объекта путь в рабочей копии, т. е. место, где ей нужно применить изменения структуры файлов. Если целевой объект не указан, предполагается, что делается попытка выполнить одну из следующих операций:

Вы хотите объединить изменения директории с вашей текущей рабочей директорией.

Вы хотите объединить изменения в конкретном файле с файлом имеющим тоже имя в текущей рабочей директории.

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

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

$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk my-calc-branch U my-calc-branch/integer.c

Layered Library Design


Subversion has a modular design, implemented as a collection of C libraries. Each library has a well-defined purpose and interface, and most modules are said to exist in one of three main layers—the Repository Layer, the Repository Access (RA) Layer, or the Client Layer. We will examine these layers shortly, but first, see our brief inventory of Subversion's libraries in Таблица 8.1, «A Brief Inventory of the Subversion Libraries». For the sake of consistency, we will refer to the libraries by their extensionless Unix library names (e.g.: libsvn_fs, libsvn_wc, mod_dav_svn).

Таблица 8.1. A Brief Inventory of the Subversion Libraries

LibraryDescription
libsvn_clientPrimary interface for client programs
libsvn_deltaTree and byte-stream differencing routines
libsvn_diffContextual differencing and merging routines
libsvn_fsFilesystem commons and module loader
libsvn_fs_baseThe Berkeley DB filesystem back-end
libsvn_fs_fsThe native filesystem (FSFS) back-end
libsvn_raRepository Access commons and module loader
libsvn_ra_davThe WebDAV Repository Access module
libsvn_ra_localThe local Repository Access module
libsvn_ra_svnThe custom protocol Repository Access module
libsvn_reposRepository interface
libsvn_subrMiscellaneous helpful subroutines
libsvn_wcThe working copy management library
mod_authz_svnApache authorization module for Subversion repositories access via WebDAV
mod_dav_svnApache module for mapping WebDAV operations to Subversion ones

The fact that the word «miscellaneous» only appears once in Таблица 8.1, «A Brief Inventory of the Subversion Libraries» is a good sign. The Subversion development team is serious about making sure that functionality lives in the right layer and libraries. Perhaps the greatest advantage of the modular design is its lack of complexity from a developer's point of view. As a developer, you can quickly formulate that kind of «big picture» that allows you to pinpoint the location of certain pieces of functionality with relative ease.

Another benefit of modularity is the ability to replace a given module with a whole new library that implements the same API without affecting the rest of the code base. In some sense, this happens within Subversion already. The libsvn_ra_dav, libsvn_ra_local, and libsvn_ra_svn all implement the same interface. And all three communicate with the Repository Layer—libsvn_ra_dav and libsvn_ra_svn do so across a network, and libsvn_ra_local connects to it directly. The libsvn_fs_base and libsvn_fs_fs libraries are another example of this.

The client itself also highlights modularity in the Subversion design. While Subversion itself comes with only a command-line client program, there are several third party programs which provide various forms of client GUI. These GUIs use the same APIs that the stock command-line client does. Subversion's libsvn_client library is the one-stop shop for most of the functionality necessary for designing a working Subversion client (see «Client Layer»).



Localization


Localization is the act of making programs behave in a region-specific way. When a program formats numbers or dates in a way specific to your part of the world, or prints messages (or accepts input) in your native language, the program is said to be localized. This section describes steps Subversion has made towards localization.



Lock Communication


We've seen how svn lock and svn unlock can be used to create, release, break, and steal locks. This satisfies the goal of serializing commit access to a file. But what about the larger problem of preventing wasted time?

For example, suppose Harry locks an image file and then begins editing it. Meanwhile, miles away, Sally wants to do the same thing. She doesn't think to run svn status --show-updates, so she has no idea that Harry has already locked the file. She spends hours editing the file, and when she tries to commit her change, she discovers that either the file is locked or that she's out-of-date. Regardless, her changes aren't mergeable with Harry's. One of these two people has to throw away their work, and a lot of time has been wasted.

Subversion's solution to this problem is provide a mechanism to remind users that a file ought to be locked before the editing begins.

The mechanism is a special property, svn:needs-lock. If the property is attached to a file (the value is irrelevant), then the file will have read-only permissions. When the user locks the file and receives a lock token, the file becomes read-write. When the lock is released—either explicitly unlocked, or released via commit—the file returns to read-only again.

The theory, then, is that if the image file has this property attached, then Sally would immediately notice something is strange when she opens the file for editing. Her application would be unable to save changes, or (better yet) tell her that the file is read-only. This reminds her to lock the file before editing, whereby she discovers the pre-existing lock:

$ /usr/local/bin/gimp raisin.jpg gimp: error: file is read-only! $ ls -l raisin.jpg -r--r--r-- 1 sally sally 215589 Jun 8 19:23 raisin.jpg $ svn lock raisin.jpg svn: Lock request failed: 423 Locked (http://svn.example.com) $ svn info http://svn.example.com/repos/project/raisin.jpg | grep Lock Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Lock Owner: harry Lock Created: 2005-06-08 07:29:18 -0500 (Thu, 08 June 2005) Lock Comment (1 line): Making some tweaks. Locking for the next two hours.

As a matter of «best practice», both users and administrators are encouraged to attach the svn:needs-lock property to any file which cannot be contextually merged. It's the main technique for encouraging good locking habits and preventing wasted effort.

Note that this property is a communication tool which works independently from the locking system. In other words, any file can be locked, whether or not this property is present. And conversely, the presence of this property doesn't make the repository require a lock when committing.

The system isn't flawless, either. It's possible that even when a file has the property, the read-only reminder won't always work. Sometimes applications misbehave and «hijack» the read-only file, silently allowing users to edit and save the file anyway. Unfortunately, there's not much Subversion can do about this.

Пред. Уровень выше След.
Свойства Содержание Peg and Operative Revisions


Locking


Subversion's «copy-modify-merge» model is optimal when users are collaborating on projects that consist of line-based text files, such as program source code. However, as discussed in Когда блокирование необходимо, sometimes one has to use the «lock-modify-unlock» model instead of Subversion's standard concurrent model. When a file consists of binary data, it's often difficult or impossible to merge two sets of changes made in parallel by different users. For this reason, Subversion 1.2 and later offers a feature known as locking, often known as «reserved checkouts» in other version control systems.

Subversion's locking feature has two main goals:

Serializing access to a resource. Allow a user to grab an exclusive right to change to a file in the repository. If Harry reserves the right to change foo.jpg, then Sally should not be able to commit a change to it.

Aiding communication. Prevent users from wasting time on unmergeable changes. If Harry has reserved the right to change foo.jpg, then it should be easy for Sally to notice this fact and avoid working on the file.

Subversion's locking feature is currently limited to files only—it's not yet possible to reserve access to a whole directory tree.

Three meanings of «lock»

In this section, and almost everywhere in this book, the words «lock» and «locking» describe a mechanism for mutual exclusion between users to avoid clashing commits. Unfortunately, there are two other sorts of «lock» with which Subversion, and therefore this book, sometimes needs to be concerned.

Working copy locks, used internally by Subversion to prevent clashes between multiple Subversion clients operating on the same working copy. This is the sort of lock indicated by an L in the third column of svn status output, and removed by the svn cleanup command, as described in «svn cleanup».

Database locks, used internally by the Berkeley DB backend to prevent clashes between multiple programs trying to access the database. This is the sort of lock whose unwanted persistence after an error can cause a repository to be «wedged», as described in «Repository Recovery».

You can generally forget about these other sorts of lock, until something goes wrong that requires you to care about them. In this book, «lock» means the first sort unless the contrary is either clear from context or explicitly stated.



Make and Test Your Changes


With the code and community policy understanding in hand, you are ready to make your changes. It is best to try to make smaller but related sets of changes, even tackling larger tasks in stages, instead of making huge, sweeping modifications. Your proposed changes will be easier to understand (and therefore easier to review) if you disturb the fewest lines of code possible to accomplish your task properly. After making each set of proposed changes, your Subversion tree should be in a state in which the software compiles with no warnings.

Subversion has a fairly thorough [53] regression test suite, and your proposed changes are expected to not cause any of those tests to fail. By running make check (in Unix) from the top of the source tree, you can sanity-check your changes. The fastest way to get your code contributions rejected (other than failing to supply a good log message) is to submit changes that cause failure in the test suite.

In the best-case scenario, you will have actually added appropriate tests to that test suite which verify that your proposed changes work as expected. In fact, sometimes the best contribution a person can make is solely the addition of new tests. You can write regression tests for functionality that currently works in Subversion as a way to protect against future changes that might trigger failure in those areas. Also, you can write new tests that demonstrate known failures. For this purpose, the Subversion test suite allows you to specify that a given test is expected to fail (called an XFAIL), and so long as Subversion fails in the way that was expected, a test result of XFAIL itself is considered a success. Ultimately, the better the test suite, the less time wasted on diagnosing potentially obscure regression bugs.



Metadata Properties


A new feature of Subversion is that you can attach arbitrary metadata (or «properties») to files and directories. Properties are arbitrary name/value pairs associated with files and directories in your working copy.

To set or get a property name, use the svn propset and svn propget subcommands. To list all properties on an object, use svn proplist.

For more information, see «Свойства».

Пред. Уровень выше След.
Branches and Tags Содержание Conflict Resolution


Метки


Еще одним понятием, свойственным управлению версиями является метка. Метка является просто «снимком» проекта в определенный момент времени. В Subversion эта идея уже, кажется, повсюду. Каждая правка хранилища является именно этим — снимком файловой системы после каждой фиксации.

Как правило, люди предпочитают давать меткам удобочитаемые имена, наподобие release-1.0. И делать снимки небольших поддиректорий файловой системы. Проще говоря, не просто запомнить, что версия 1.0 программы соответствует поддиректории в правке 4822.



Mod_dav_svn


Пред. Уровень выше След.
svnversion Содержание mod_dav_svn Configuration Directives


Модель Блокирование-Изменение-Разблокирование


Для того, что бы несколько авторов не мешало друг другу многие системы управления версиями применяют модель блокирование-изменение-разблокирование. Эта модель запрещает одновременное редактирование файла несколькими пользователями. Эксклюзивность доступа гарантируется блокировками. Перед началом редактирования Гарри должен «заблокировать» файл. Если файл заблокировал Гарри, Салли уже не сможет его заблокировать и не сможет внести в него изменения. Ей остается только читать файл и ждать пока Гарри закончит свои изменения и снимет свою блокировку. После того как Гарри разблокирует файл, файл сможет получить Салли, заблокировать его и начать редактирование. Рисунок 2.3, «Модель блокирование-изменение-разблокирование» демонстрирует это простое решение.

Рисунок 2.3. Модель блокирование-изменение-разблокирование

Проблемой модели блокирование-изменение-разблокирование является то, что она немного ограниченная и часто доставляет неудобства пользователям:

Блокирование может вызвать проблемы администрирования. Иногда Гарри заблокирует файл, а затем забудет об этом. Между тем, ожидая редактирования файла, у Салли будут связаны руки. А Гарри уехал в отпуск. Теперь Салли, для снятия блокировки Гарри, нужно обращаться к администратору. Ситуация заканчивается не нужной задержкой и потерянным временем.

Блокирование может вызвать излишнюю пошаговость. Что если Гарри редактирует начало текстового файла, а Салли нужно отредактировать концовку этого же файла? Эти изменения совсем не перекрываются. Они могли бы легко редактировать файл одновременно и никаких особенных проблем это не вызвало бы, предполагая корректное слияние изменений. Блокирование файла в такой ситуации не требуется.

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



Модель Копирование-Изменение-Слияние


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

Вот пример. Скажем и Гарри и Салли создали копированием из хранилища рабочие копии одного и того же проекта. Они работают одновременно и в своих рабочих копиях вносят изменения в один и тот же файл А. Первой свои изменения в хранилище сохраняет Салли. Когда позже Гарри попытается сохранить свои изменения, хранилище проинформирует его о том, что его файл А устарел. Другими словами, файл А каким то образом изменился со времени, когда он его последний раз копировал. Поэтому Гарри просит свой клиент слить любые изменения из хранилища в его рабочую копию файла А. По счастливому совпадению, изменения Салли не перекрываются с его собственными; после объединения обоих наборов изменений он сохраняет свою рабочую копию обратно в хранилище. Рисунок 2.4, «Модель копирование-изменение-слияние» и Рисунок 2.5, «Модель копирование-изменение-слияние (продолжение)» показывают этот процесс.

Рисунок 2.4. Модель копирование-изменение-слияние


Рисунок 2.5. Модель копирование-изменение-слияние (продолжение)

А что если изменения Салли перекрываются с изменениями Гарри? Что тогда? Эта ситуация называется конфликтом и, как правило, это не является большой проблемой. Когда Гарри просит свой клиент слить последние изменения хранилища в рабочую копию, его копия файла А как-то помечается как находящаяся в состоянии конфликта: у него будет возможность видеть оба набора конфликтующих изменений и вручную сделать между ними выбор. Помните, что ПО не может автоматически разрешать конфликты; только человек способен к пониманию и выполнению осмысленного выбора. Разрешив вручную перекрывающиеся изменения - возможно, после обсуждения с Салли — он может безопасно сохранить объединенный файл обратно в хранилище.

Модель копирование-изменение-слияние может выглядеть немного хаотично, однако, на практике она отлично работает. Пользователи могут работать параллельно, не тратя время на ожидание друг друга. При работе над одними и теми же файлами оказывается, что большинство параллельно вносимых изменений совсем не перекрываются; конфликты бывают редко. И время, которое было потрачено на разрешение конфликтов значительно меньше времени отнимаемого блокирующей системой.

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

Когда блокирование необходимо

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

Модель копирование-изменение-слияние основывается на предположении о том, что файлы контекстно-объединяемы: это так если большинство файлов в хранилище — текстовые файлы (например исходный код программы). Но для файлов бинарных форматов, таких как графические или звуковые, как правило не возможно объединить конфликтующие изменения. В таких ситуациях пользователям действительно необходимо быть внимательными при изменении файла. Без раздельного доступа кто-то может впустую потратить время на изменения, которые в конце концов будут потеряны.

Так как и CVS, и Subversion, — в первую очередь системы типа копирование-изменение-слияние, то в них обоих признается необходимость блокирования определенных файлов и предлагаются механизмы для этого. См. «Locking».

Пред. Уровень выше След.
Глава 2. Основные понятия Содержание Subversion в действии


Модели версионирования


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



More Disconnected Operations


In recent years, disk space has become outrageously cheap and abundant, but network bandwidth has not. Therefore, the Subversion working copy has been optimized around the scarcer resource.

The .svn administrative directory serves the same purpose as the CVS directory, except that it also stores read-only, «pristine» copies of your files. This allows you to do many things off-line:

svn status

Shows you any local changes you've made (see «svn status»)

svn diff

Shows you the details of your changes (see «svn diff»)

svn revert

Removes your local changes (see «svn revert»)

Also, the cached pristine files allow the Subversion client to send differences when committing, which CVS cannot do.

The last subcommand in the list is new; it will not only remove local changes, but it will un-schedule operations such as adds and deletes. It's the preferred way to revert a file; running rm file; svn update will still work, but it blurs the purpose of updating. And, while we're on this subject…

Пред. Уровень выше След.
Directory Versions Содержание Distinction Between Status and Update


Название


mod_dav_svn Configuration Directives — Apache configuration directives for serving Subversion repositories through Apache HTTP Server.



svn add — Добавляет файлы, директории и символические связи.




svn blame — Построчно показывает автора и редакцию для указанных файлов или URL-ов.




svn cat — Выводит содержимое указанного файлов или URL-ов.




svn checkout — Создает рабочую копию на основе данных в хранилище.




svn cleanup — Рекурсивно чистит рабочую копию.




svn commit — Высылает сделанные вами изменения рабочей копии в хранилище для их закрепления в нем.




svn copy — Копирует файл или каталог в рабочей копии или хранилище.




svn delete — Delete an item from a working copy or the repository.




svn diff — Display the differences between two paths.




svn export — Export a clean directory tree.




svn help — Help!




svn import — Commit an unversioned file or tree into the repository.




svn info — Display information about a local or remote item.




svn list — List directory entries in the repository.




svn lock — Lock working copy paths or URLs in the repository, so that no other user can commit changes to them.




svn log — Display commit log messages.




svn merge — Apply the differences between two sources to a working copy path.




svn mkdir — Create a new directory under version control.




svn move — Move a file or directory.




svn propdel — Remove a property from an item.




svn propedit — Edit the property of one or more items under version control.




svn propget — Print the value of a property.




svn proplist — List all properties.




svn propset — Set PROPNAME to PROPVAL on files, directories, or revisions.




svn resolved — Remove «conflicted» state on working copy files or directories.




svn revert — Undo all local edits.




svn status — Print the status of working copy files and directories.




svn switch — Update working copy to a different URL.




svn unlock — Unlock working copy paths or URLs.




svn update — Update your working copy.




svnadmin create — Create a new, empty repository.




svnadmin deltify — Deltify changed paths in a revision range.




svnadmin dump — Dump the contents of filesystem to stdout.




svnadmin help




svnadmin hotcopy — Make a hot copy of a repository.




svnadmin list-dblogs — Ask Berkeley DB which log files exist for a given Subversion repository (applies only to repositories using the bdb backend).




svnadmin list-unused-dblogs — Ask Berkeley DB which log files can be safely deleted (applies only to repositories using the bdb backend).




svnadmin load — Read a «dumpfile»-formatted stream from stdin.




svnadmin lslocks — Print descriptions of all locks.




svnadmin lstxns — Print the names of all uncommitted transactions.




svnadmin recover — Bring a repository database back into a consistent state (applies only to repositories using the bdb backend). In addition, if repos/conf/passwd does not exist, it will create a default password file .




svnadmin rmlocks — Unconditionally remove one or more locks from a repository.




svnadmin rmtxns — Delete transactions from a repository.




svnadmin setlog — Set the log-message on a revision.




svnadmin verify — Verify the data stored in the repository.



Об этой книге


Содержание

Для кого написана эта книга?Как читать эту книгу?Соглашения, принятые в книгеТипографские соглашенияПиктограммыСтруктура книгиЭта книга распространяется свободноБлагодарностиFrom Ben Collins-SussmanFrom Brian W. FitzpatrickFrom C. Michael Pilato

«Если язык C — это клубок верёвок, в которых можно легко запутаться, то Subversion — это что-то вроде склада для верёвок». — Брайан У. Фитцпатрик

В мире программного обеспечения с открытым исходным кодом в качестве инструмента управления версиями долгое время использовалась Concurrent Versions System[1] (CVS). На это были свои причины. CVS сама по себе является свободным программным обеспечением, на работу с ней не накладывается ограничений, а поддержка сетевых возможностей позволяет десяткам географически разделённых программистов работать совместно — всё это отлично подходит для мира свободного программного обеспечения, отличающегося духом сотрудничества. CVS и её полубеспорядочная модель разработки стали краеугольными камнями культуры свободного программного обеспечения.

Однако, несмотря на все достоинства CVS, её возраст даёт о себе знать. Subversion представляет собой относительно молодую систему управления версиями, призванную прийти на смену CVS. Её разработчики стремятся завоевать сердца пользователей CVS сразу с двух сторон: во-первых, Subversion создаётся как система с открытым исходным кодом, которая по своему устройству и ощущениям от работы напоминает CVS, а во-вторых, она пытается исправить наиболее очевидные недостатки CVS. И хотя то, что получается в результате, не обязательно является новым витком в развитии технологий управления версиями, Subversion на самом деле очень мощное, удобное и гибкое средство.

Эта книга описывает систему управления версиями Subversion поколения 1.3. Мы стремились охватить материал как можно шире. В то же время следует иметь в виду, что разработкой Subversion занимается активное энергичное сообщество, так что уже сейчас идёт работа над рядом особенностей и улучшений, которые будут внесены в последующие версии Subversion. Эти нововведения могут привести к некоторым расхождениям между командами и соответствующими пояснениями в тексте книги.



Обновления и фиксации отделены друг от друга


Одно из фундаментальных правил Subversion заключается в том, что «передающее» действие не приводит к «принимаемому», и наоборот. То, что вы готовы внести изменения в хранилище, не означает то, что вы готовы принять изменения от других. А если вы все еще работаете над новыми изменениями, то svn update изящно объединит изменения из хранилища с вашими собственными, вместо того, что бы заставлять вас опубликовать их.

Главным побочным эффектом этого правила является то, что рабочая копия должна вести дополнительный учет при смешивании правок и быть аккуратной при любом смешивании. И то, что каталоги попадают под контроль версий, делает это еще более сложным для понимания.

Допустим, у вас есть рабочая копия, полностью соответствующая правке 10. После изменения файла foo.html, вы выполняете команду svn commit, которая создает в хранилище правку 15. После выполнения фиксации большая часть новичков ожидают, что вся рабочая копия будет иметь правку 15, однако это не так. Между правками 10 и 15 в хранилище могло быть внесено любое количество изменений. Так как команда svn update не выполнялась, а svn commit не загружает изменений, клиент ничего не знает о находящихся в хранилище изменениях. С другой стороны, если команда svn commit будет автоматически загружать последние изменения, то всей рабочей копии можно будет назначить соответствующий номер правки - 15. Однако нарушится фундаментальное правило, согласно которому «передача» и «получение» являются независимыми операциями. Следовательно, все, что может сделать клиент Subversion, это пометить один файл — foo.html — как соответствующий правке 15. Остальная рабочая копия продолжает соответствовать правке 10. Только при выполнении svn update будут загружены последние изменения и вся рабочая копия будет помечена как соответствующая правке 15.



и символические связи, помечая их


Добавляет файлы, директории и символические связи, помечая их для последующего внесения в хранилище. Будучи помеченными, они закачиваются и добавляются в хранилище при первом же закреплении изменений. Если вы что-то добавили, но потом передумали до закрепления, то снять метку добавления можно подкомандой svn revert.


Построчно показывает автора и редакцию для указанных файлов или URL-ов. Каждая строка текста начинается с имени автора (имени пользователя) и номера редакции. Таким образом указывается кто и когда изменял эту строку последний раз.



Выводит содержимое указанного файлов или URL-ов. Для перечисления содержимого каталогов используйте svn list.



Создает рабочую копию на основе данных в хранилище. Если PATH пропущен, базовое имя URL будет использоваться в качестве имени для каталога рабочей копии. Если задано несколько URL, соответствующие копии будут создаваться в подкаталоге PATH, каждая в своем каталоге образованом из базового имени URL.



Рекурсивно чистит рабочую копию, удаляя блокировки оставшиеся от незавершенных операций. Как только столкнетесь с ошибкой «рабочая копия заблокирована», запустите эту подкоманду для удаления старых блокировок и приведения рабочей копии в работоспособное состояние.
Если по некоторым причинам операция по команде svn update провалилась из-за проблем с запущенным внешней программой различий (например, что-то не то в ней нажал или произошел сбой сети), нужно задать параметр --diff3-cmd чтобы дать возможность при чистке копии завершить все объединяния используя внешнюю программу различий. Вы также можете указать конфигурационный каталог посредством параметра --config-dir, но постарайтесь не злоупотреблять этими параметрами.



Высылает сделанные вами изменения рабочей копии в хранилище для их закрепления в нем. Если вы не воспользовались ни --file, ни --message параметром, svn запустит внешний редактор для составления комментария. Прочтите описание параметра editor-cmd в «Config».
svn commit вышлет храшилищу все рекурсивно найденные метки блокировок и разблокирует соответсвующие этим меткам ресурсы, если не был указан параметр --no-unlock. "Район поиска" задается указанием PATH.


Копирует файл в рабочей копии или в хранилище. SRC и DST могут быть путями как внутри рабочей копии, так и URL внутри хранилища:
WC -> WCПланирует копирование объекта (вместе с историей).
WC -> URLСоздает копию объекта из рабочей копии непосредственно в хранилище.
URL -> WCВыгружает копию объекта из хранилища в рабочую копию и планирует ее добавление.
URL -> URLВыполняет копирование объектов непосредственно в хранилище. Обычно используется для ветвления.

Отмена изменений


Еще одним типичным применением для svn merge является откат изменений, которые уже были зафиксированы. Предположим вы спокойно работаете в рабочей копии /calc/trunk и выясняете, что изменения сделанные в правке 303, которые изменили integer.c, полностью ошибочны. Вы можете воспользоваться командой svn merge для «отмены» изменений в своей рабочей копии, после чего зафиксировать локальные изменения в хранилище. Все, что нужно сделать, это указать обратные отличия:

$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk U integer.c $ svn status M integer.c $ svn diff … # verify that the change is removed … $ svn commit -m "Undoing change committed in r303." Sending integer.c Transmitting file data . Committed revision 350.

Одним из взглядов на правку хранилища является представление ее в виде сгруппированных изменений (некоторые системы управления версиями называют это набором изменений). Используя параметр -r можно попросить svn merge применить к рабочей копии набор изменений или целый диапазон наборов изменений. В нашем случае с отменой изменений, мы просим svn merge применить к рабочей копии набор изменений #303 в обратном направлении.

Обратите внимание, что откат изменений подобным образом ничем не отличается от любых других операций, выполненных с помощью svn merge, поэтому необходимо использовать svn status и svn diff для того, что бы убедится, что ваша работа находится в том состоянии в котором вам нужно, а затем используя svn commit отправить финальную версию в хранилище. После фиксации, этот конкретный набор изменений больше не будет отражен в правке HEAD.

Но наряду с этим, вы можете подумать: однако же на самом деле фиксация не отменяется, не так ли? Изменения продолжают существовать в правке 303. И если кто-то создаст рабочую копию версии проекта calc между правками 303 и 349, он все равно получит ошибочные изменения, верно?

Да, это так. Когда мы говорим об «удалении» изменений, имеется в виду их удаление из HEAD. Первоначальные изменения продолжают существовать в истории хранилища. Для большинства ситуаций это является положительным моментом. В любом случае, большинство пользователей интересует только HEAD проекта. Однако, возможны ситуации, когда действительно необходимо удалить последствия фиксации. (Возможно, кто-то случайно зафиксировал конфиденциальный документ.) Сделать это будет не так просто, так как Subversion спроектирована специально таким образом, что бы исключить возможность потери информации. Правки представляют собой не меняющиеся деревья файлов, основывающиеся одно на другом. Удаление правки из хранилища может вызвать эффект домино, создавая беспорядок во всех последующих правках и возможно разрушая все рабочие копии. [15]



targets FILENAME


-- targets FILENAME --non-recursive (-N) --quiet (-q) --config-dir DIR --auto-props --no-auto-props --force

Параметры конфигурации


В этом разделе рассматриваются поддерживаемые Subversion параметры времени выполнения.



Параметры svn


Хотя Subversion имеет различные параметры для своих подкоманд, все параметры глобальны. То есть, каждый параметр гарантированно означает одно и тоже, в независимости от подкоманды с которой он используется. Например, --verbose (-v) всегда означает («многословный вывод»), в независимости от того, с какой подкомандой вы его используете.

--auto-props

Включает auto-props, переопределяя значение директивы enable-auto-props в файле config.

--config-dir DIR

Заставляет Subversion считать настройки с указанного каталога вместо используемого по умолчанию (.subversion в домашнем каталоге пользователя).

--diff-cmd CMD

Позволяет указать внешнюю программу просмотра различий между файлами. По умолчанию, подкоманда svn diff использует внутренний механизм сравнения Subversion, выдающий результат в едином формате записи различий (unified diffs). Воспользоваться внешней программой просмотра различий можно указав ее имя в качестве аргумента --diff-cmd. Необходимые аргументы могут быть переданы программе просмотра различий через параметр --extensions (будет описан ниже в этой главе).

--diff3-cmd CMD

Позволяет указать внешнюю программу для слияния файлов.

--dry-run

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

--editor-cmd CMD

Определяет внешнюю программу для редактирования комментария или свойства.

--encoding ENC

Говорит Subversion в какой кодировке вы пишете комментарий. По умолчанию используется кодировка локали вашей операционной системы. Нужно указать ее явно, если вы желаете написать комментарий в другой кодировке.

--extensions (-x) ARGS

Определяет параметр который Subversion должна передать внешней программе сравнения, когда выясняется различие между файлами. Для передачи нескольких параметров, их нужно заключить их в кавычки (например, svn diff --diff-cmd /usr/bin/diff -x "-b -E"). Этот параметр командной строки может использоваться только совместно с параметром --diff-cmd.

--file (-F) FILENAME

Использует содержимое указанного файла в качестве входных данных запрашиваемых вызываемой подкомандой.

--force

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

--force-log

Принуждает параметры --message (-m) или --file (-F) принять в качестве значения сомнительный параметр. По умолчанию, Subversion будет выдавать ошибку, если значения этих параметров выглядят так, как если бы они были объектами обрабатываемыми подкомандой. Например, когда в качестве значения параметра --file (-F) используется имя файла находящегося под версионным контролем, Subversion предполагает была допущена ошибка. Ей кажется, что вместо положенного в таком случае обычного—неверсионированного—файла, по ошибке был указан целевой файл вызываемой операции. Чтобы подтвердить своих намерения и обойти ошибки такого рода, нужно явно задать параметр --force-log для подкоманд предполагающих ввод комментариев.

--help (-h or -?)

Если используется с одной или более подкоманд—выводит внутренний подсказку каждой подкоманды. Если без подкоманд, то отображает общую подсказку.

--ignore-ancestry

Сообщает Subversion о необходимости игнорировать происхождение при вычислении различий. То есть, полагаться только на содержимое.

--ignore-externals

Сообщает Subversion о необходимости игнорировать внешние определения и соответствующие рабочие копии.

--incremental

Выводит результаты в удобном для склейки виде.

--limit NUM

Выводит только первые NUM сообщений из истории.

--message (-m) MESSAGE

Указывает на то, что вы комментируюте операцию закрепления изменений сообщением следующим за параметром. Например:

$ svn commit -m "They don't make Sunday." --new ARG

Определяет ARG как более новый целевой объект.

--no-auth-cache

Препятствует кешированию идентификационной информации (например имя и пароль) в административноv каталоге Subversion.

--no-auto-props

Отключает auto-props, переопределяя указание enable-auto-props в файле config.

--no-diff-added

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

--no-diff-deleted

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

--no-ignore

Показывает файлы в статусном списке, которых были бы пропущены как подподающие под шаблон конфигурационного свойства global-ignores или свойства svn:ignore. Смотри «Config» и «svn:ignore» для дополнительной информации.

--no-unlock

Не снимает блокировку с файлов автоматически. По умолчанию блокировка снимается для всех фалов учавствющих в закреплении изменений. Смотри «Locking» для для дополнительной информации.

--non-interactive

В случае ошибки идентификации или неполноты параметров идентификации, препятсвует их запрашиванию (например, запросу имени или пароля). Это полезно при вызове Subversion в скрипте, что бы в случаее ошибки Subversion запрос дополнительной информации не привел к остановке выполнения скрипта.

--non-recursive (-N)

Недопускает рекурсивного выполнения подкоманды для подкаталогов. Большинство подкоманд рекурсивно по умолчанию, но некоторые—обычно те, что могут удалять или отменять ваши локальные изменения—таковыми не являются.

--notice-ancestry

Обращает внимение на происхождение при вычислении различий.

--old ARG

Определяет ARG как более поздний целевой объект.

--password PASS

Указывает на ваше желание явно задать пароль для аутентификации—как бы то нибыло, если пароль потребуется, Subversion его у вас спросит.

--quiet (-q)

Выражает просьбу сопровождать выполнение операции только существенной информацией.

--recursive (-R)

Выполнять подкоманды рекурсивно для всех подкаталогов. Большинство подкоманд рекурсивно по умолчанию.

--relocate FROM TO [PATH...]

Используется совместно с подкомандой svn switch, предписывая вашей рабочей копии ссылаться на другое хранилище. Это полезно при изменении адрес размещения вашего хранилица изменился, а вы имеете уже существующую рабочую копию, которую бы желали продолжать использовать. Используйте svn switch в качестве примера.

--revision (-r) REV

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

$ svn log -r 1729 $ svn log -r 1729:HEAD $ svn log -r 1729:1744 $ svn log -r {2001-12-04}:{2002-02-17} $ svn log -r 1729:{2002-02-17}

Используйте «Ключевые слова правок» для дополнительной информации.

--revprop

Оперирует со свойствами редакции, a не свойствами файла или каталога. Этот параметр требует указания редакции по средством --revision (-r). Ознакомтесь с «Unversioned Properties» для внесения ясности по неверсионируемым свойствам.

--show-updates (-u)

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

--stop-on-copy

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

--strict

Требует от Subversion использовать строгую семантику. Описать изменение поведения подкоманды довольно трудно без учета специфики самой подкоманды.

--targets FILENAME

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

--username NAME

Указывает на ваше желание явно задать имя пользователя для аутентификации—как бы то нибыло, если имя пользователя потребуется, Subversion его у вас спросит.

--verbose (-v)

Выражает просьбу комментировать процесс выполнения операции как можно более детально. Это может привести к выводу дополнительных полей, подробной информации по каждому файлу или более полной информации о выполняемой операции.

--version

Выводит информацию о версии программы клиента. В дополнение к номеру версии выводится и список всех модулей доступа к хранилищу, которыми может воспользоваться этот клиент.

--xml

Осуществлять вывод в XML-формате.



Параметры времени выполнения


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

Область конфигурации Subversion имеет двух уровневую иерархию имен параметров и их значений. Как правило, она сводиться к отдельной директории, содержащей конфигурационные файлы (первый уровень) являющиеся простыми текстовыми файлами в стандартном INI формате (с «разделами», обеспечивающими второй уровень). Эти файлы содержат директивы используемые клиентом для определения поведения клиента предпочитаемого пользователем, и могут быть легко отредактированы используя ваш любимый редактор (например, Emacs или vi).



Peg and Operative Revisions


The ability to copy, move, and rename files and directories; to be able to create an object, then delete it and then add a new one at the same path—those are operations which we perform on files and directories on our computers all the time, and operations we tend to take for granted. And Subversion would like you to think they are granted. Subversion's file management support is quite liberating, affording almost as much flexibility for versioned files that you'd expect when manipulating your unversioned ones. But that flexibility means that across the lifetime of your repository, a given versioned resource might have many paths, and a given path might represent several entirely different versioned resources.

Subversion is pretty smart about noticing when an object's version history includes such «changes of address». For example, if you ask for all the logs of a particular file that was renamed last week, Subversion happily provides all those logs—the revision in which the rename itself happened, plus the logs of relevant revisions both before and after that rename. So, most of the time, you don't even have to think about such things. But occasionally, Subversion needs your help to clear up ambiguities.

The simplest example of this occurs when a directory or file is deleted from version control, and then a new directory or file is created with the same name and added to version control. Clearly the thing you deleted and the thing you later added aren't the same thing, they merely happen to have had the same path, which we'll call /trunk/object. What, then, does it mean to ask Subversion about the history of /trunk/object? Are you asking about the thing currently at that location, or the old thing you deleted from that location? Are you asking about the operations that have happened to all the objects that have lived at that path? Clearly, Subversion needs a hint about what you are really asking.

And thanks to moves, versioned resource history can get far more twisted than that, even. For example, you might have a directory named concept, containing some nascent software project you've been toying with. Eventually, though, that project matures to the point that the idea seems to actually have some wings, so you do the unthinkable and decide to give the project a name. [42] Let's say you called your software Frabnaggilywort. At this point, it makes sense to rename the directory to reflect the project's new name, so concept is renamed to frabnaggilywort. Life goes on, Frabnaggilywort releases a 1.0 version, and is downloaded and used daily by hordes of people aiming to improve their lives.

It's a nice story, really, but it doesn't end there. Entrepreneur that you are, you've already got another think in the tank. So you make a new directory, concept, and the cycle begins again. In fact, the cycle begins again many times over the years, each time starting with that old concept directory, then sometimes seeing that directory renamed as the idea cures, sometimes seeing it deleted when you scrap the idea. Or, to get really sick, maybe you rename concept to something else for a while, but later rename the thing back to concept for some reason.

When scenarios like these occur, attempting to instruct Subversion to work with these re-used paths can be a little like instructing a motorist in Chicago's West Suburbs to drive east down Roosevelt Road and turn left onto Main Street. In a mere twenty minutes, you can cross «Main Street» in Wheaton, Glen Ellyn, and Lombard. And no, they aren't the same street. Our motorist—and our Subversion—need a little more detail in order to do the right thing.

In version 1.1, Subversion introduced a way for you to tell it exactly which Main Street you meant. It's called the peg revision, and it is a revision provided to Subversion for the sole purpose of identifying a unique line of history. Because at most one versioned resource may occupy a path at any given time—or, more precisely, in any one revision—the combination of a path and a peg revision is all that is needed to refer to a specific line of history. Peg revisions are specified to the Subversion command-line client using at syntax, so called because the syntax involves appending an «at sign» (@) and the peg revision to the end of the path with which the revision is associated.

But what of the --revision (-r) of which we've spoken so much in this book? That revision (or set of revisions) is called the operative revision (or operative revision range). Once a particular line of history has been identified using a path and peg revision, Subversion performs the requested operation using the operative revision(s). To map this to our Chicagoland streets analogy, if we are told to go to 606 N. Main Street in Wheaton, [43] we can think of «Main Street» as our path and «Wheaton» as our peg revision. These two pieces of information identify a unique path which can travelled (north or south on Main Street), and will keep us from travelling up and down the wrong Main Street in search of our destination. Now we throw in «606 N.» as our operative revision, of sorts, and we know exactly where to go.

The "peg-revision" algorithm

When the commandline client sees a command of the form:

$ svn command -r OPERATIVE-REV item@PEG-REV

...it performs the following algorithm:

Go to revision PEG-REV, and find item. This locates a unique object in the repository.

Trace the object's history backwards (through any possible renames) to its ancestor in revision OPERATIVE-REV.

Perform the requested action on that ancestor, wherever it is located, or whatever its name might be.

Remember that even when you don't explicitly supply a peg-revision, it's still present. It defaults to BASE for working copy items, and to HEAD for URLs.

Say that long ago we created our repository, and in revision 1 added our first concept directory, plus an IDEA file in that directory talking about the concept. After several revisions in which real code was added and tweaked, we, in revision 20, renamed this directory to frabnaggilywort. By revision 27, we had a new concept, a new concept directory to hold it, and a new IDEA file to describe it. And then five years and twenty thousand revisions flew by, just like they would in any good romance story.

Now, years later, we wonder what the IDEA file looked like back in revision 1. But Subversion needs to know if we are asking about how the current file looked back in revision 1, or are we asking for the contents of whatever file lived at concepts/IDEA in revision 1? Certainly those questions have different answers, and because of peg revisions, you can ask either of them. To find out how the current IDEA file looked in that old revision, you run:

$ svn cat -r 1 concept/IDEA subversion/libsvn_client/ra.c:775: (apr_err=20014) svn: Unable to find repository location for 'concept/IDEA' in revision 1

Of course, in this example, the current IDEA file didn't exist yet in revision 1, so Subversion gives an error. The command above is shorthand for a longer notation which explicitly lists a peg revision. The expanded notation is:

$ svn cat -r 1 concept/IDEA@BASE subversion/libsvn_client/ra.c:775: (apr_err=20014) svn: Unable to find repository location for 'concept/IDEA' in revision 1

And when executed, has the expected results. Peg revisions generally default to a value of BASE (the revision currently present in the working copy) when applied to working copy paths, and of HEAD when applied to URLs.

Let's ask the other question, then—in revision 1, what were the contents of whatever file occupied the address concepts/IDEA at the time? We'll use an explicit peg revision to help us out.

$ svn cat concept/IDEA@1 The idea behind this project is to come up with a piece of software that can frab a naggily wort. Frabbing naggily worts is tricky business, and doing it incorrectly can have serious ramifications, so we need to employ over-the-top input validation and data verification mechanisms.

This appears to be the right output. The text even mentions frabbing naggily worts, so this is almost certainly the file which describes the software now called Frabnaggilywort. In fact, we can verify this using the combination of an explicit peg revision and explicit operative revision. We know that in HEAD, the Frabnaggilywort project is located in the frabnaggilywort directory. So we specify that we want to see how the line of history identified in HEAD as the path frabnaggilywort/IDEA looked in revision 1.

$ svn cat -r 1 frabnaggilywort/IDEA@HEAD The idea behind this project is to come up with a piece of software that can frab a naggily wort. Frabbing naggily worts is tricky business, and doing it incorrectly can have serious ramifications, so we need to employ over-the-top input validation and data verification mechanisms.

And the peg and operative revisions need not be so trivial, either. For example, say frabnaggilywort had been deleted from HEAD, but we know it existed in revision 20, and we want to see the diffs for its IDEA file between revisions 4 and 10. We can use the peg revision 20 in conjunction with the URL that would have held Frabnaggilywort's IDEA file in revision 20, and then use 4 and 10 as our operative revision range.

$ svn diff -r 4:10 http://svn.red-bean.com/projects/frabnaggilywort/IDEA@20 Index: frabnaggilywort/IDEA =================================================================== --- frabnaggilywort/IDEA (revision 4) +++ frabnaggilywort/IDEA (revision 10) @@ -1,5 +1,5 @@ -The idea behind this project is to come up with a piece of software -that can frab a naggily wort. Frabbing naggily worts is tricky -business, and doing it incorrectly can have serious ramifications, so -we need to employ over-the-top input validation and data verification -mechanisms. +The idea behind this project is to come up with a piece of +client-server software that can remotely frab a naggily wort. +Frabbing naggily worts is tricky business, and doing it incorrectly +can have serious ramifications, so we need to employ over-the-top +input validation and data verification mechanisms.

Fortunately, most folks aren't faced with such complex situations. But when you are, remember that peg revisions are that extra hint Subversion needs to clear up ambiguity.


[42] «You're not supposed to name it. Once you name it, you start getting attached to it.» — Mike Wazowski

[43] 606 N. Main Street, Wheaton, Illinois, is the home of the Wheaton History Center. Get it—«History Center»? It seemed appropriate….

Пред. Уровень выше След.
Locking Содержание Externals Definitions


Переключение рабочей копии


Команда svn switch трансформирует существующую рабочую копию в другую ветку. Несмотря на то, что при работе с ветками эта команда не является крайне необходимой, она значительно облегчает жизнь пользователям. В ранее приведенном примере, после создания личной ветки вы создавали новую рабочую копию созданной директории хранилища. Вместо этого, можно попросить Subversion изменить рабочую копию /calc/trunk так, что бы она отражала созданную ветку:

$ cd calc $ svn info | grep URL URL: http://svn.example.com/repos/calc/trunk $ svn switch http://svn.example.com/repos/calc/branches/my-calc-branch U integer.c U button.c U Makefile Updated to revision 341. $ svn info | grep URL URL: http://svn.example.com/repos/calc/branches/my-calc-branch

После «переключения» на ветку, рабочая копия не будет отличаться от той которая получилась бы при создании новой рабочей копии директории хранилища. Как правило, более эффективно использовать эту команду, так как обычно у ветки немного отличий. Сервер отправляет минимально необходимый для того, что бы рабочая копия отражала директорию ветки, набор изменений.

Команда svn switch принимает параметр --revision (-r), по-этому необязательно помещать рабочую копию на самую «верхушку» ветки.

Конечно, большинство проектов, по сравнению с нашим примером calc более сложны, содержат множество поддиректорий. Обычно пользователи Subversion используют специальный алгоритм для работы с ветками:

Скопировать всю директорию «trunk» в директорию новой ветки.

Переключить часть главной линии разработки на ветку.

Другими словами, если пользователь знает, что работа над веткой будет проходить в конкретной директории, он может, с помощью, svn switch переключить на ветку только эту поддиректорию. (А иногда на ветку переключается только один рабочий файл!) В этом случае пользователи могут продолжать обычным образом получать обновления «trunk» для большей части рабочей копии, а переключенные части будут оставаться нетронутыми (до тех пор, пока кто-то не изменить этой ветки). Эта возможность добавляет совершенно новое измерение в понятие «смешанная рабочая копия» — рабочая копия может содержать не только смесь рабочих правок но и смесь местоположений в хранилище.

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

Обратите внимание, на то, что хотя и иметь в рабочей копии смесь местоположений в хранилище является нормальным, все эти местоположения должны быть из одного хранилища. Хранилища Subversion пока не могут сообщаться друг с другом; реализация этой возможности запланирована после Subversion 1.0.[17]

Переключения и обновления

Вы не обратили внимания на то, что вывод svn switch и svn update выглядит одинаково? На самом деле команда switch является расширенным вариантом команды обновления.

При запуске svn update вы просите хранилище сравнить два дерева. Хранилище выполняет это и отправляет описания изменений обратно клиенту. Отличие между svn switch и svn update только в том, что команда update всегда сравнивает два одинаковых пути.

То есть, рабочая копия отражает /calc/trunk, то svn update будет автоматически сравнивать рабочую копию /calc/trunk с правкой HEAD /calc/trunk. Если вы переключаете рабочую копию на ветку, то svn switch будет сравнивать рабочую копию /calc/trunk с какой-то другой директорией в правке HEAD.

Другими словами, обновление переносит рабочую копию сквозь время. А переключение переносит рабочую копию сквозь время и пространство.

Учитывая то, что svn switch в сущности является разновидностью svn update их поведение схоже; при получении новой информации из хранилища, все локальные изменения сохраняются. Это позволяет использовать разнообразные трюки.

Предположим вы внесли некоторые изменения в имеющуюся у вас рабочую копию /calc/trunk. После чего неожиданно обнаружили, что вместо этого вам необходимо внести изменения в ветку Нет проблем! Когда вы переключите (svn switch) рабочую копию на ветку, локальные изменения сохраняться. После чего их можно проверить и зафиксировать в ветке.


[17] Однако, можно воспользоваться svn switch с параметром --relocate если URL сервера изменился и вы не хотите бросать существующую рабочую копию. За более подробной информацией и примерами смотрите раздел, посвященный svn switch в Глава 9, Полное справочное руководство по Subversion

Пред. Уровень выше След.
Типовые примеры использования Содержание Метки


Поддержка веток


Сейчас вы уже понимаете, что Subversion очень гибкая система. Учитывая то, что ветки и метки имеют одну и ту же основу (копии директорий), а также то, что ветки и метки являются обычными элементами файловой системы, Subversion многих пугает. Она слишком гибкая. В этом разделе мы предложим несколько советов по компоновке и поддержке информации с течением времени.



Подкоманды svn



[54] Да, да, вам не нужна подкоманда что бы задействовать параметра командной строки --version, но мы вернемся к этому уже через минуту.

Пред.   След.
Contributing to Subversion Содержание svn add


Подсказка


You should strongly consider using explicit revision numbers in all of your externals definitions. Doing so means that you get to decide when to pull down a different snapshot of external information, and exactly which snapshot to pull. Besides the common sense aspect of not being surprised by changes to third-party repositories that you might not have any control over, using explicit revision numbers also means that as you backdate your working copy to a previous revision, your externals definitions will also revert to the way they looked in that previous revision, which in turn means that the external working copies will be updated to match they way they looked back when your repository was at that previous revision. For software projects, this could be the difference between a successful and a failed build of an older snapshot of your complex codebase.

The support that exists for externals definitions in Subversion today can be a little misleading, though. First, an externals definition can only point to directories, not files. Second, the externals definition cannot point to relative paths (paths like ../../skins/myskin). Third, the working copies created via the externals definition support are still disconnected from the primary working copy (on whose versioned directories the svn:externals property was actually set). And Subversion still only truly operates on non-disjoint working copies. So, for example, if you want to commit changes that you've made in one or more of those external working copies, you must run svn commit explicitly on those working copies—committing on the primary working copy will not recurse into any external ones.

Also, since the definitions themselves use absolute URLs, moving or copying a directory to which they are attached will not affect what gets checked out as an external (though the relative local target subdirectory will, of course, move with renamed directory). This can be confusing—even frustrating—in certain situations. For example, if you use externals definitions on a directory in your /trunk development line which point to other areas of that same line, and then you use svn copy to branch that line to some new location /branches/my-branch, the externals definitions on items in your new branch will still refer to versioned resources in /trunk. Be aware, too, that if you need to re-parent your working copy (using svn switch --relocate), externals definitions will not also be re-parented.

Finally, there might be times when you would prefer that svn subcommands would not recognize or otherwise operate on the external working copies created as the result of externals definition handling. In those instances, you can pass the --ignore-externals option to the subcommand.

Пред. Уровень выше След.
Peg and Operative Revisions Содержание Vendor branches


Удобно для определения правки, в которой ветка была создана («базовой» правки ветки) использовать параметр --stop-on-copy при запуске svn log. При обычном запуске, эта команда показывает все изменения сделанные в ветке, включая те, которые были сделаны до создания ветки. Поэтому, при таком запуске вы увидите и историю главной линии разработки. Параметр --stop-on-copy остановит вывод лог сообщений как только svn log определит, что целевой объект был скопирован или переименован.

$ svn log --verbose --stop-on-copy \ http://svn.example.com/repos/calc/branches/my-calc-branch … ------------------------------------------------------------------------ r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: A /calc/branches/my-calc-branch (from /calc/trunk:340) $

Как и ожидалось, последняя правка выведенная этой командой будет правка, в которой директория my-calc-branch была создана путем копированием.

Вот так выглядит завершение объединения:

$ cd calc/trunk $ svn update At revision 405. $ svn merge -r 341:405 http://svn.example.com/repos/calc/branches/my-calc-branch U integer.c U button.c U Makefile $ svn status M integer.c M button.c M Makefile # ...examine the diffs, compile, test, etc... $ svn commit -m "Merged my-calc-branch changes r341:405 into the trunk." Sending integer.c Sending button.c Sending Makefile Transmitting file data ... Committed revision 406.

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

Например, предположим, что на следующей неделе вы решите продолжить работу над веткой, для завершения расширения функциональности или исправления ошибки. После этого, правка HEAD хранилища будет имеет номер 480 и вы готовы выполнить еще одно объединение своей личной копии с главной линией разработки. Однако, как уже было сказано в разделе «Как правильнее всего использовать слияние», нет необходимости объединять изменения которые уже были объединены раньше; нужно объединить только «новые» изменения, появившиеся с момента последнего объединения. Сложность в том, что бы выделить эти новые изменения.

Первым шагом является запуск svn log для главной линии разработки, для того, что бы увидеть сообщение о времени последнего объединения с веткой:

$ cd calc/trunk $ svn log … ------------------------------------------------------------------------ r406 | user | 2004-02-08 11:17:26 -0600 (Sun, 08 Feb 2004) | 1 line Merged my-calc-branch changes r341:405 into the trunk. ------------------------------------------------------------------------ …

Ага! Так как все изменения в ветке, которые делались между правками 341 и 405 уже были объединены с главной линией разработки в правке 406, то теперь вы знаете, что необходимо брать только те изменения ветки, которые были выполнены после этого — сравнивая правки 406 и HEAD.

$ cd calc/trunk $ svn update At revision 480. # We notice that HEAD is currently 480, so we use it to do the merge: $ svn merge -r 406:480 http://svn.example.com/repos/calc/branches/my-calc-branch U integer.c U button.c U Makefile $ svn commit -m "Merged my-calc-branch changes r406:480 into the trunk." Sending integer.c Sending button.c Sending Makefile Transmitting file data ... Committed revision 481.

Теперь главная линия разработки полностью содержит вторую волну изменений, сделанных в ветке. С этого момента можно либо удалить ветку (об этом мы поговорим позже), либо продолжать работать над веткой, с последующим объединением изменений.




Полезный совет, относящийся к окружающему тексту.




Ваша рабочая копия устарела (или вы что-то в ней локально изменили), но хотите посмотреть HEAD редакцию файла имеющегося в вашей рабочей копии. Подкоманда svn cat автоматически извлечет HEAD редакцию, ей нужено только указать путь к этому файлу:

$ cat foo.c This file is in my local working copy and has changes that I've made. $ svn cat foo.c Latest revision fresh from the repository!
Пред. Уровень выше След.
svn blame Содержание svn checkout



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




Это рекомендованный способ воскрешать случайно удаленные из хранилища файлы!

$ svn copy file:///tmp/repos/test/far-away near-here A near-here

И наконец, копирование внутри хранилища:

$ svn copy file:///tmp/repos/test/far-away file:///tmp/repos/test/over-there -m "remote copy." Committed revision 9.


Это простейший способ «пометить» редакцию в хранилище—просто выполните svn copy желаемой редакции (хотя обычно это HEAD) в желаемый каталог.

$ svn copy file:///tmp/repos/test/trunk file:///tmp/repos/test/tags/0.6.32-prerelease -m "tag tree" Committed revision 12.

Да, и не волнуйтесь, если забыли вовремя пометить редакцию—вы всегда можете сделать это сославшись на старую редакцию:

$ svn copy -r 11 file:///tmp/repos/test/trunk file:///tmp/repos/test/tags/0.6.32-prerelease -m "Forgot to tag at rev 11" Committed revision 13.
Пред. Уровень выше След.
svn commit Содержание svn delete



If you run svn log on a specific path and provide a specific revision and get no output at all

$ svn log -r 20 http://svn.red-bean.com/untouched.txt ------------------------------------------------------------------------

That just means that the path was not modified in that revision. If you log from the top of the repository, or know the file that changed in that revision, you can specify it explicitly:

$ svn log -r 20 touched.txt ------------------------------------------------------------------------ r20 | sally | 2003-01-17 22:56:19 -0600 (Fri, 17 Jan 2003) | 1 line Made a change. ------------------------------------------------------------------------
Пред. Уровень выше След.
svn lock Содержание svn merge



This command is equivalent to an svn copy followed by svn delete.




Subversion has a number of «special» properties that affect its behavior. See «Специальные свойства» for more on these properties.




You can just switch part of your working copy to a branch if you don't want to switch your entire working copy.

Sometimes an administrator might change the «base location» of your repository—in other words, the contents of the repository doesn't change, but the main URL used to reach the root of the repository does. For example, the hostname may change, the URL scheme, or any part of the URL which leads to the repository itself. Rather than checkout a new working copy, you can have the svn switch command «rewrite» the beginnings of all the URLs in your working copy. Use the --relocate option to do the substitution. No file contents are changed, nor is the repository contacted. It's similar to running a Perl script over your working copy .svn/ directories which runs s/OldRoot/NewRoot/.

$ svn checkout file:///tmp/repos test A test/a A test/b … $ mv repos newlocation $ cd test/ $ svn update svn: Unable to open an ra_local session to URL svn: Unable to open repository 'file:///tmp/repos' $ svn switch --relocate file:///tmp/repos file:///tmp/newlocation . $ svn update At revision 3.


If you want to examine an older revision of a single file, you may want to use svn cat.

Пред. Уровень выше След.
svn unlock Содержание svnadmin


Подводя итоги


В этой главе мы рассмотрели ряд фундаментальных вещей о Subversion:

Мы ввели такие понятия, как центральное хранилище, рабочая копия и массив правок хранилища.

Мы рассмотрели на нескольких простых примерах, как при помощи Subversion два партнера могут публиковать и получать изменения, сделанные друг другом, используя модель «копирование-изменение-слияние».

Мы немного поговорили о том, как Subversion отслеживает и управляет информацией в рабочей копии.

На данный момент у вас должно быть хорошее представление о том, как вообще работает Subversion. Теперь, вооруженные этими знаниями, вы готовы перейти к следующей главе, которая представляет собой подробный обзор команд и возможностей Subversion.

Пред. Уровень выше След.
Subversion в действии Содержание Глава 3. Экскурсия по Subversion


В этой главе было рассмотрено очень многое. Мы обсудили концепцию меток и веток, показали как Subversion реализует эти понятия используя команду svn copy. Показали, как svn merge копирует изменения из одной ветки в другую, как с помощью этой команды отменить ошибочные изменения. Мы рассмотрели использование svn switch для создания рабочих копий, собранных из разных директорий хранилища. Обсудили, как управлять организацией и временем жизни веток в хранилище.

Не забывайте о мантре Subversion: ветки и метки легковесны. Поэтому пользуйтесь ими свободно!

Пред. Уровень выше След.
Поддержка веток Содержание Глава 5. Администрирование хранилища


Полное объединение двух веток


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

Как же в этом случае нужно использовать svn merge? Помните о том, что эта команда сравнивает два дерева и применяет различия к рабочей копии. Поэтому, для того, что бы было к чему применять изменения, необходимо иметь рабочую копию главной линии разработки. Будем считать, что-либо у вас под рукой имеется такая (полностью обновленная) копия, либо вы только что создали новую рабочую копию /calc/trunk.

А какие именно два дерева должны сравниваться? На первый взгляд ответ очевиден: сравнивать последнее дерево главной линии разработки с последним деревом вашей ветки. Однако будьте осторожны — такое предположение является ошибочным, многие новые пользователи ошибаются подобным образом! Учитывая то, что svn merge работает так же как svn diff, сравнение последние версии главной линии разработки и вашей ветки покажет изменения сделанные не только в вашей ветке. Такое сравнение покажет слишком много изменений: будут показано не только то, что добавлялось в вашей ветке, но и то, что удалялось в главной линии разработки и не удалялось в вашей ветке.

Для выделения только тех изменений, которые были сделаны в вашей ветке, нужно сравнивать начальное и конечное состояния ветки. Воспользовавшись svn log для ветки, можно узнать, что она была создана в правке 341. А для определения конечного состояния ветки можно просто использовать правку HEAD. Это значит, что вам нужно сравнить правки 341 и HEAD директории с веткой и применить различия к рабочей копии главной линии разработки.



Правки


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

В хранилище каждая фиксация отражается как атомарная операция: либо изменения вносятся полностью, либо не вносятся вообще. Subversion ведёт себя так, принимая в расчет возможные сбои в программах, системные сбои, проблемы с сетью, а также неверные действия пользователя.

Каждый раз, когда происходит фиксация, создаётся новое состояние файловой системы, которое называется правка. Каждая правка получает уникальный номер, на единицу больший номера предыдущей правки. Начальная правка только что созданного хранилища получает номер 0 и не содержит ничего, кроме пустого корневого каталога.

Рисунок 2.7, «Хранилище» отлично иллюстрирует хранилище. Представьте массив номеров правок, начинающийся с 0, с направлением слева направо. Каждый номер правки имеет соответствующее дерево файлов, а каждое дерево представляет собой «снимок» того, как хранилище выглядело после фиксации.

Рисунок 2.7. Хранилище

Глобальные номера правок

В отличие от многих других систем управления версиями, номера правок в Subversion относятся ко всем, а не только к отдельно взятым файлам. Каждый номер правки соответствует целому дереву, отдельному состоянию хранилища после зафиксированного изменения. Иначе говоря — правка N представляет состояние файловой системы хранилища после выполнения N-ой фиксации. Когда пользователи Subversion говорят о «правке 5 foo.c », на самом деле речь идет о « foo.c входящем в правку 5». Заметьте, что обычно правки N и M файла не обязательно будут отличаться. Поскольку в CVS используется пофайловая нумерация правок, пользователи CVS могут обратиться за более подробной информацией к Приложение A, Subversion для пользователей CVS.

Важно помнить то, что рабочие копии не всегда соответствуют какой-то одной правке в хранилище; они могут содержать файлы из разных правок. Например, вы получили рабочую копию из хранилища, у которого самая последняя правка — 4:

calc/Makefile:4 integer.c:4 button.c:4

На данный момент рабочий каталог полностью соответствует правке 4 в хранилище. Допустим, что вы внесли изменения в button.c, и зафиксировали эти изменения. При отсутствии других фиксаций ваша фиксация создаст правку под номером 5, и теперь ваша рабочая копия выглядит следующим образом:

calc/Makefile:4 integer.c:4 button.c:5

Предположим, что после этого Салли фиксирует изменения integer.c, создавая правку 6. Если вы воспользуетесь svn update для приведения своей рабочей копии в актуальное состояние, то она станет выглядеть так:

calc/Makefile:6 integer.c:6 button.c:6

Изменения, внесенные Салли в integer.c будут отражены в вашей рабочей копии, и ваши изменения в button.c также будут присутствовать. В этом примере текст Makefile в правках 4, 5 и 6 идентичен, однако, Subversion проставляет номер правки 6 для вашей рабочей копии Makefile, чтобы показать что файл не устарел. Таким образом, после того как вы выполните полное обновление вашей рабочей копии, она будет полностью соответствовать текущему состоянию хранилища.



Скверный список ответов на часто


Скверный список ответов на часто задаваемые вопросы (ЧаВо) состоит не из тех вопросов, которые были заданы на самом деле, а из тех, на которые автору такого списка хотелось бы дать ответ. Вы наверняка сталкивались с чем-то подобным:
ВОПРОС: Как Glorbosoft XYZ поможет поднять производительность труда наших сотрудников?
ОТВЕТ: Многие наши клиенты хотят знать, как поднять производительность труда при помощи наших патентованных офисных инноваций для коллективной работы. Ответ простой: выберите меню «Файл» и перейдите к пункту «Поднять производительность», затем…
Проблема подобных ЧаВо заключается в том, что они вовсе не являются ответами на часто задаваемые вопросы в буквальном смысле. Какой нормальный человек будет звонить в службу технической поддержки и спрашивать: «как нам поднять производительность труда»? Вопросы, которые обычно звучат в таких случаях, узко специализированы, например: «Как настроить календарь для отправки напоминаний за два дня вместо одного?». Однако, создать список якобы заданных вопросов намного проще, чем подобрать настоящие вопросы из реальной жизни. Такая работа требует упорства и организованности: вопросы, возникающие в процессе жизненного цикла программного продукта, и ответы на них должны бережно сохраняться и систематизироваться, пока на их основе не будет создано логически связанное и удобное для поиска единое целое, наилучшим образом отражающее опыт пользователей. Здесь требуется терпеливость и внимательность, присущие естествоиспытателю, а не великие гипотезы и провидческие заявления. Главное в этой работе — открытые глаза и аккуратное отношение к записям в блокноте.
В этой книге мне больше всего нравится то, что она именно так и была написана, и это заметно на каждой её странице. Она является непосредственным результатом общения авторов с пользователями. Книга началась с того, что Бен Коллинз-Сассман как-то раз заметил в рассылке Subversion, что пользователи всё время задают одни и те же вопросы: какого порядка действий следует придерживаться при работе с Subversion; есть ли отличия от других систем управления версиями при работе с ветками и метками; как узнать, кем было выполнено то или иное изменение?
Устав от ежедневного просмотра одних и тех же вопросов, Бен провёл месяц в напряжённой работе, и летом 2002 года появилось Руководство по Subversion — документ, в котором на 60 страницах описывались все основные приёмы работы с Subversion. Это руководство не претендовало на полноту, но оно было включено в поставку Subversion и помогало преодолеть начинающим пользователям первые трудности, с которыми они сталкивались. После того, как издательство O'Reilly and Associates решило выпустить полноценную книгу о Subversion, путь наименьшего сопротивления был очевиден: нужно было просто расширить Руководство по Subversion.
Таким образом, три соавтора новой книги получили необычную возможность. С одной стороны, перед ними была поставлена задача написать книгу в обычном смысле слова, от автора к читателю, начиная с содержания и первого черновика. Но, с другой стороны, у них также была возможность обращаться у устойчивому потоку — да что там говорить, к неуправляемому фонтану — материалу, поступающему от будущих читателей. Subversion уже был в то время в руках тысяч первых пользователей, которые давали множество отзывов не только о самом Subversion, но и о документации к нему.
Пока шла работа над книгой, Бен, Майк и Брайан постоянно отслеживали рассылки и чаты, скрупулёзно отмечая проблемы, с которыми пользователи сталкивались в реальных жизненных ситуациях. Мониторинг подобных отзывов входит в их служебные обязанности в CollabNet, но в данном случае эта работа оказалась неоценимой при подготовке документации к Subversion. В основу написанной ими книги положен твёрдый фундамент опыта, а не зыбучие пески принятия желаемого за действительное; в этой книге соединяются лучшие качества руководства пользователя и списка ЧаВо. Эта двойственность может быть незаметна при первом прочтении книги. При чтении книги по порядку, от корки до корки, создаётся ощущение, что перед нами прямолинейное описание программного продукта. Нам предлагают общий обзор, непременный в таких случаях вводный курс, главу по администрированию, несколько тем для продвинутых пользователей и, само собой, справочник по командам и способы устранения проблем. Лишь возвращаясь к этой книге снова и снова, вы сможете оценить её самобытность: отличительные подробности, которые могут появиться лишь при встрече с неожиданными ситуациями, примеры, взятые из жизни и, самое главное, внимательность к нуждам пользователей и их точке зрения.
Конечно, никто не может пообещать, что эта книга ответит на все ваши вопросы о Subversion. Иногда точность, с которой книга предвосхищает ваши вопросы, может показаться телепатической, но вполне может случиться и так, что вы столкнётесь с пробелом в коллективном знании сообщества и уйдёте с пустыми руками. Лучшее, что можно сделать в такой ситуации — отправить письмо на адрес <users@subversion.tigris.org> с описанием вашей проблемы. Авторы по-прежнему читают эту рассылку, они внимательно наблюдают за вопросами, и, кроме того, сообщество пользователей не ограничивается тремя людьми, имена которых вынесены на обложку этой книги — многие подписчики рассылки также помогают вносить исправления и предлагают новый материал для книги. С точки зрения сообщества, решение вашей конкретной проблемы — это лишь приятный побочный эффект значительно более обширного проекта, а именно, постепенного исправления данной книги и самого Subversion с тем, чтобы как можно ближе соответствовать практике. Эти люди с удовольствием выслушают вас не только потому, что могут помочь, но и потому, что вы можете помочь им. При работе с Subversion, как и с любым другим бурно развивающимся свободным программным обеспечением, вы не будете чувствовать себя одиноким.
Пусть эта книга будет вашим верным помощником.
— Карл Фогель, Чикаго, 14 марта 2004 г.
Пред.   След.
Управление версиями в Subversion Содержание Об этой книге


Предварительные просмотр при объединении


Учитывая, что результатом слияния являются локальные модификации, такая операция не является опасной. Если в начале, при выполнении объединения вы ошиблись, просто отмените изменения (svn revert) и попробуйте еще раз.

Однако, возможна ситуация, когда рабочая копия уже содержит локальные изменения. Изменения, примененные при слиянии будут смешаны с уже существующими и svn revert запустить будет нельзя. Если нельзя будет разделить два набора изменений.

В такой ситуации лучше будет попробовать спрогнозировать или проверить объединения до того, как они произойдут. Самым простым вариантом является запуск svn diff с теми же аргументами, что и для svn merge, это мы уже показывали в первом примере объединения. Другим вариантом предпросмотра является передача команде объединения опции --dry-run:

$ svn merge --dry-run -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status # nothing printed, working copy is still unchanged.

Опция --dry-run не вносит локальные изменения в рабочую копию. Показываются только коды статуса которые будут выведены при настоящем объединении. Это полезно для получения «обобщенной» информации об объединении для тех случаев, когда запуск svn diff выдает слишком детальную информацию.

Subversion и наборы изменений

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

В Subversion глобальный номер правки N относится к дереву в хранилище: так выглядит хранилище после фиксации N. Кроме того, это имя для неявного набора изменений: если сравнить дерево N с деревом N-1 вы получите полный патч того, что было зафиксировано. В этом смысле, о «правке N» можно думать не как о дереве файлов, а как о наборе изменений. Если вы пользуетесь системой отслеживания релизов для управления ошибками, вы можете использовать номера правок для того, что бы ссылаться на конкретные патчи, которые исправляют ошибку — например, «этот релиз был исправлен правкой 9238.». После этого, для того, что бы прочитать о том наборе изменений, который исправляет ошибку можно выполнить svn log -r9238, а для того, что бы увидеть сам патч, выполнить svn diff -r9237:9238. В Subversion команда merge тоже использует номера правок. Можно объединить набор изменений из одной ветки в другую указав его в качестве аргумента: команда svn merge -r9237:9238 внедрит набор изменений #9238 в вашу рабочую копию.



A. Subversion для пользователей CVS


Содержание

Revision Numbers Are Different NowDirectory VersionsMore Disconnected OperationsDistinction Between Status and UpdateStatusUpdateBranches and TagsMetadata PropertiesConflict ResolutionBinary Files and TranslationVersioned ModulesAuthenticationConverting a Repository from CVS to Subversion

This appendix is a guide for CVS users new to Subversion. It's essentially a list of differences between the two systems as «viewed from 10,000 feet». For each section, we provide backreferences to relevant chapters when possible.

Although the goal of Subversion is to take over the current and future CVS user base, some new features and design changes were required to fix certain «broken» behaviors that CVS had. This means that, as a CVS user, you may need to break habits—ones that you forgot were odd to begin with.



C. Инструменты от сторонних разработчиков


Subversion's modular design (covered in «Layered Library Design») and the availability of language bindings (as described in «Using Languages Other than C and C++») make it a likely candidate for use as an extension or backend to other pieces of software. For a listing of many third-party tools that are using Subversion functionality under-the-hood, check out the Links page on the Subversion website (http://subversion.tigris.org/project_links.html).

Пред.   След.
Client Interoperability Содержание Приложение D. Copyright


D. Copyright


Copyright (c) 2002-2005 Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato.

This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

A summary of the license is given below, followed by the full legal text.

--------------------------------------------------------------------

You are free:

* to copy, distribute, display, and perform the work * to make derivative works * to make commercial use of the work

Under the following conditions:

Attribution. You must give the original author credit.

* For any reuse or distribution, you must make clear to others the license terms of this work.

* Any of these conditions can be waived if you get permission from the author.

Your fair use and other rights are in no way affected by the above.

The above is a summary of the full license below.

====================================================================

Creative Commons Legal Code Attribution 2.0

CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.

License

THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

1. Definitions

a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.

b. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License.

c. "Licensor" means the individual or entity that offers the Work under the terms of this License.

d. "Original Author" means the individual or entity who created the Work.

e. "Work" means the copyrightable work of authorship offered under the terms of this License.

f. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.

2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws.

3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;

b. to create and reproduce Derivative Works;

c. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;

d. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works.

e.

For the avoidance of doubt, where the work is a musical composition:

i. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work.

ii. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights agency or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions).

f. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions).

The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved.

4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

a. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any reference to such Licensor or the Original Author, as requested.

b. If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination

a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.

b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

8. Miscellaneous

a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.

b. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.

c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.

d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.

e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.

Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.

Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time.

Creative Commons may be contacted at http://creativecommons.org/.

====================================================================

Пред.   
Приложение C. Инструменты от сторонних разработчиков Содержание 



c Если добавляется каталог, то


Для добавления файла к вашей рабочей копии:
$ svn add foo.c A foo. c Если добавляется каталог, то по умолчанию svn add действует рекурсивно:
$ svn add testdir A testdir A testdir/a A testdir/b A testdir/c A testdir/d Вы можете добавить каталог без добавления его содержимого:
$ svn add --non-recursive otherdir A otherdir По умолчанию, команда svn add * пропустит любые каталоги уже находящиеся под контролем версий. Но иногда, все же, бывает нужно добавить все неверсионированные объекты в вашей рабочей копии, включая те, что находятся внутри каталогов. Указав параметр --force принудит svn add рекурсивно пройтись и по версионированным каталогам:
$ svn add * --force A foo.c A somedir/bar.c A otherdir/docs/baz.doc …
Пред. Уровень выше След.
Глава 9. Полное справочное руководство по Subversion Содержание svn blame


Если вы хотите просмотреть аннотацию


Если вы хотите просмотреть аннотацию для файла readme.txt в тестовом хранилище:
$ svn blame http://svn.red-bean.com/repos/test/readme.txt 3 sally This is a README file. 5 harry You should read this.
Пред. Уровень выше След.
svn add Содержание svn cat


Если вы хотите просмотреть readme.txt в хранилище не создавая его рабочей копии:
$ svn cat http://svn.red-bean.com/repos/test/readme.txt This is a README file. You should read this.


Создать рабочую копию в директории с именем mine:
$ svn checkout file:///tmp/repos/test mine A mine/a A mine/ b Checked out revision 2. $ ls mine Создать рабочие копии двух разных каталогов:
$ svn checkout file:///tmp/repos/test file:///tmp/repos/quiz A test/a A test/b Checked out revision 2. A quiz/l A quiz/m Checked out revision 2. $ ls quiz test Создать рабочие копии двух разных каталогов в каталоге с именем working-copies:
$ svn checkout file:///tmp/repos/test file:///tmp/repos/quiz working-copies A working-copies/test/a A working-copies/test/b Checked out revision 2. A working-copies/quiz/l A working-copies/quiz/m Checked out revision 2. $ ls working-copies Если вы прервете создание копии (или его прервет что-то другое: например, разрыв связи и т.п.), вы можете продолжить процесс выдав команду повторно или просто запросив обновление рабочей копии:
$ svn checkout file:///tmp/repos/test test A test/a A test/b ^C svn: The operation was interrupted svn: caught SIGINT $ svn checkout file:///tmp/repos/test test A test/c A test/d ^C svn: The operation was interrupted svn: caught SIGINT $ cd test $ svn update A test/e A test/f Updated to revision 3.
Пред. Уровень выше След.
svn cat Содержание svn cleanup



Собственно, тут не так уж и много примеров можно привести, так как svn cleanup не комментирует свою работу. И если вы не указали PATH, то будет использоваться «.» .
$ svn cleanup $ svn cleanup /path/to/working-copy
Пред. Уровень выше След.
svn checkout Содержание svn commit



Закрепить изменения файла в хранилище неявно определенным текущим каталогом («.»). Задать комментарий в командной строке:
$ svn commit -m "added howto section." Sending a Transmitting file data . Committed revision 3. Закрепить изменения файла foo.c (явно заданного в командной строке). Задать комментарий содержимым файла msg:
$ svn commit -F msg foo.c Sending foo.c Transmitting file data . Committed revision 5. Если вы хотите использовать содержимое файла находящегося под контролем версий в качестве комментария (используя параметр --file), вы должны задать параметр --force-log для явного выражения своих намерений:
$ svn commit --file file_under_vc.txt foo.c svn: The log message file is under version control svn: Log message file is a versioned file; use '--force-log' to override $ svn commit --force-log --file file_under_vc.txt foo.c Sending foo.c Transmitting file data . Committed revision 6. Закрепить факт удаления файла:
$ svn commit -m "removed file 'c'." Deleting c Committed revision 7.
Пред. Уровень выше След.
svn cleanup Содержание svn copy



Планирование копирования объекта внутри рабочей копии. Физическое копирование происходит после выполнения команды закрепления изменений:
$ svn copy foo.txt bar.txt A bar.txt $ svn status A + bar.txt Копирование объекта из рабочей копии в хранилище по заданному URL. Изменения в хранилище вносятся незамедлительно (так что требуется прокомментировать свои действия):
$ svn copy near.txt file:///tmp/repos/test/far-away.txt -m "Remote copy." Committed revision 8. Копирование объекта из хранилища в рабочую копию. Полученная копия планируется на добавление и возникнет в хранилище только после команды закрепления изменений:

Pristine Copies and Property Files


As mentioned before, the .svn directory also holds the pristine «text-base» versions of files. Those can be found in .svn/text-base. The benefits of these pristine copies are multiple—network-free checks for local modifications and difference reporting, network-free reversion of modified or missing files, smaller transmission of changes to the server—but comes at the cost of having each versioned file stored at least twice on disk. These days, this seems to be a negligible penalty for most files. However, the situation gets uglier as the size of your versioned files grows. Some attention is being given to making the presence of the «text-base» an option. Ironically though, it is as your versioned files' sizes get larger that the existence of the «text-base» becomes more crucial—who wants to transmit a huge file across a network just because they want to commit a tiny change to it?

Similar in purpose to the «text-base» files are the property files and their pristine «prop-base» copies, located in .svn/props and .svn/prop-base respectively. Since directories can have properties, too, there are also .svn/dir-props and .svn/dir-prop-base files. Each of these property files («working» and «base» versions) uses a simple «hash-on-disk» file format for storing the property names and values.


[50] That is, the URL for the entry is the same as the concatenation of the parent directory's URL and the entry's name.

Пред. Уровень выше След.
Using the APIs Содержание WebDAV


Проблема разделения файлов


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

Рассматриваемую ситуацию иллюстрирует Рисунок 2.2, «Проблема потери изменений». Допустим у нас есть два со-разработчика Гарри и Салли. Они вдвоем решили одновременно поредактировать один и тот же файл из хранилища. Если первым свои изменения в хранилище сохранит Гарри, то возможно, что (несколькими минутами позже) Салли может непреднамеренно перезаписать их своей новой версией файла. Несмотря на то, что версия файла Гарри не будет полностью потеряна (так как система помнит каждое изменение) внесенные Гарри изменения не будут отражены в новой версии файла Сэлли, потому что, начиная, она, не видела изменения Гарри. Работа Гарри фактически потеряна — или, по крайней мере, отсутствует в последней версии файла — по случайности. Как раз этой ситуации мы и хотим избежать!

Рисунок 2.2. Проблема потери изменений



Продолжительность жизни информации


Еще одним замечательным свойством модели Subversion является то, что ветки и метки могут иметь конечную продолжительность жизни, так же как и все другие версионированные элементы. Например, предположим вы наконец закончили все работы в ваше личной ветке проекта calc. После объединения изменений с /calc/trunk, нет причин продолжать хранить эту ветку:

$ svn delete http://svn.example.com/repos/calc/branches/my-calc-branch \ -m "Removing obsolete branch of calc project." Committed revision 375.

Больше вашей ветки не существует. Конечно, на самом деле она не исчезла: просто ее больше нет в правке HEAD, она больше никого не отвлекает. Если воспользоваться командами svn checkout, svn switch или svn list для обращения к ранним правкам, свою старую ветку вы увидите.

Если просмотра удаленной директории не достаточно, вы всегда можете восстановить эту директорию. Восстановление информации в Subversion выполнить очень просто. Если есть директория или файл, который вы хотите вернуть обратно в HEAD, просто воспользуйтесь svn copy -r для того, что бы скопировать его из старой правки:

$ svn copy -r 374 http://svn.example.com/repos/calc/branches/my-calc-branch \ http://svn.example.com/repos/calc/branches/my-calc-branch Committed revision 376.

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

$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/branches/stable-1.0 \ -m "Creating stable branch of calc project." Committed revision 377.

После этого, разработчикам ничего не мешает продолжать добавлять в /calc/trunk новые передовые (или экспериментальные) функции, а в правилах проекта можно указать, что в /calc/branches/stable-1.0 должны фиксироваться только исправления ошибок. По мере того, как будет продвигаться работа над главной линией разработки, исправленные ошибки будут выборочно портироваться в стабильную ветку. Даже после выхода релиза стабильной ветки, она может продолжать поддерживаться долгое время — столько, сколько этот релиз будет продолжать поддерживаться для пользователей.

Пред. Уровень выше След.
Метки Содержание Подводя итоги


Programming with Memory Pools


Almost every developer who has used the C programming language has at some point sighed at the daunting task of managing memory usage. Allocating enough memory to use, keeping track of those allocations, freeing the memory when you no longer need it—these tasks can be quite complex. And of course, failure to do those things properly can result in a program that crashes itself, or worse, crashes the computer. Fortunately, the APR library that Subversion depends on for portability provides the apr_pool_t type, which represents a pool from which the application may allocate memory.

A memory pool is an abstract representation of a chunk of memory allocated for use by a program. Rather than requesting memory directly from the OS using the standard malloc() and friends, programs that link against APR can simply request that a pool of memory be created (using the apr_pool_create() function). APR will allocate a moderately sized chunk of memory from the OS, and that memory will be instantly available for use by the program. Any time the program needs some of the pool memory, it uses one of the APR pool API functions, like apr_palloc(), which returns a generic memory location from the pool. The program can keep requesting bits and pieces of memory from the pool, and APR will keep granting the requests. Pools will automatically grow in size to accommodate programs that request more memory than the original pool contained, until of course there is no more memory available on the system.

Now, if this were the end of the pool story, it would hardly have merited special attention. Fortunately, that's not the case. Pools can not only be created; they can also be cleared and destroyed, using apr_pool_clear() and apr_pool_destroy() respectively. This gives developers the flexibility to allocate several—or several thousand—things from the pool, and then clean up all of that memory with a single function call! Further, pools have hierarchy. You can make «subpools» of any previously created pool. When you clear a pool, all of its subpools are destroyed; if you destroy a pool, it and its subpools are destroyed.

Before we go further, developers should be aware that they probably will not find many calls to the APR pool functions we just mentioned in the Subversion source code. APR pools offer some extensibility mechanisms, like the ability to have custom «user data» attached to the pool, and mechanisms for registering cleanup functions that get called when the pool is destroyed. Subversion makes use of these extensions in a somewhat non-trivial way. So, Subversion supplies (and most of its code uses) the wrapper functions svn_pool_create(), svn_pool_clear(), and svn_pool_destroy().

While pools are helpful for basic memory management, the pool construct really shines in looping and recursive scenarios. Since loops are often unbounded in their iterations, and recursions in their depth, memory consumption in these areas of the code can become unpredictable. Fortunately, using nested memory pools can be a great way to easily manage these potentially hairy situations. The following example demonstrates the basic use of nested pools in a situation that is fairly common—recursively crawling a directory tree, doing some task to each thing in the tree.

Пример 8.5. Effective Pool Usage

/* Recursively crawl over DIRECTORY, adding the paths of all its file children to the FILES array, and doing some task to each path encountered. Use POOL for the all temporary allocations, and store the hash paths in the same pool as the hash itself is allocated in. */ static apr_status_t crawl_dir (apr_array_header_t *files, const char *directory, apr_pool_t *pool) { apr_pool_t *hash_pool = files->pool; /* array pool */ apr_pool_t *subpool = svn_pool_create (pool); /* iteration pool */ apr_dir_t *dir; apr_finfo_t finfo; apr_status_t apr_err; apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME; apr_err = apr_dir_open (&dir, directory, pool); if (apr_err) return apr_err; /* Loop over the directory entries, clearing the subpool at the top of each iteration. */ for (apr_err = apr_dir_read (&finfo, flags, dir); apr_err == APR_SUCCESS; apr_err = apr_dir_read (&finfo, flags, dir)) { const char *child_path; /* Clear the per-iteration SUBPOOL. */ svn_pool_clear (subpool); /* Skip entries for "this dir" ('.') and its parent ('..'). */ if (finfo.filetype == APR_DIR) { if (finfo.name[0] == '.' && (finfo.name[1] == '\0' || (finfo.name[1] == '.' && finfo.name[2] == '\0'))) continue; } /* Build CHILD_PATH from DIRECTORY and FINFO.name. */ child_path = svn_path_join (directory, finfo.name, subpool); /* Do some task to this encountered path. */ do_some_task (child_path, subpool); /* Handle subdirectories by recursing into them, passing SUBPOOL as the pool for temporary allocations. */ if (finfo.filetype == APR_DIR) { apr_err = crawl_dir (files, child_path, subpool); if (apr_err) return apr_err; } /* Handle files by adding their paths to the FILES array. */ else if (finfo.filetype == APR_REG) { /* Copy the file's path into the FILES array's pool. */ child_path = apr_pstrdup (hash_pool, child_path); /* Add the path to the array. */ (*((const char **) apr_array_push (files))) = child_path; } } /* Destroy SUBPOOL. */ svn_pool_destroy (subpool); /* Check that the loop exited cleanly. */ if (apr_err) return apr_err; /* Yes, it exited cleanly, so close the dir. */ apr_err = apr_dir_close (dir); if (apr_err) return apr_err; return APR_SUCCESS; }

The previous example demonstrates effective pool usage in both looping and recursive situations. Each recursion begins by making a subpool of the pool passed to the function. This subpool is used for the looping region, and cleared with each iteration. The result is memory usage is roughly proportional to the depth of the recursion, not to total number of file and directories present as children of the top-level directory. When the first call to this recursive function finally finishes, there is actually very little data stored in the pool that was passed to it. Now imagine the extra complexity that would be present if this function had to alloc() and free() every single piece of data used!

Pools might not be ideal for every application, but they are extremely useful in Subversion. As a Subversion developer, you'll need to grow comfortable with pools and how to wield them correctly. Memory usage bugs and bloating can be difficult to diagnose and fix regardless of the API, but the pool construct provided by APR has proven a tremendously convenient, time-saving bit of functionality.

Пред. Уровень выше След.
WebDAV Содержание Contributing to Subversion


RA-DAV (Repository Access Using HTTP/DAV)


The libsvn_ra_dav library is designed for use by clients that are being run on different machines than the servers with which they communicating, specifically servers reached using URLs that contain the http: or https: protocol portions. To understand how this module works, we should first mention a couple of other key components in this particular configuration of the Repository Access Layer—the powerful Apache HTTP Server, and the Neon HTTP/WebDAV client library.

Subversion's primary network server is the Apache HTTP Server. Apache is a time-tested, extensible open-source server process that is ready for serious use. It can sustain a high network load and runs on many platforms. The Apache server supports a number of different standard authentication protocols, and can be extended through the use of modules to support many others. It also supports optimizations like network pipelining and caching. By using Apache as a server, Subversion gets all of these features for free. And since most firewalls already allow HTTP traffic to pass through, system administrators typically don't even have to change their firewall configurations to allow Subversion to work.

Subversion uses HTTP and WebDAV (with DeltaV) to communicate with an Apache server. You can read more about this in the WebDAV section of this chapter, but in short, WebDAV and DeltaV are extensions to the standard HTTP 1.1 protocol that enable sharing and versioning of files over the web. Apache 2.0 and later versions come with mod_dav, an Apache module that understands the DAV extensions to HTTP. Subversion itself supplies mod_dav_svn, though, which is another Apache module that works in conjunction with (really, as a back-end to) mod_dav to provide Subversion's specific implementations of WebDAV and DeltaV.

When communicating with a repository over HTTP, the RA loader library chooses libsvn_ra_dav as the proper access module. The Subversion client makes calls into the generic RA interface, and libsvn_ra_dav maps those calls (which embody rather large-scale Subversion actions) to a set of HTTP/WebDAV requests. Using the Neon library, libsvn_ra_dav transmits those requests to the Apache server. Apache receives these requests (exactly as it does generic HTTP requests that your web browser might make), notices that the requests are directed at a URL that is configured as a DAV location (using the <Location> directive in httpd.conf), and hands the request off to its own mod_dav module. When properly configured, mod_dav knows to use Subversion's mod_dav_svn for any filesystem-related needs, as opposed to the generic mod_dav_fs that comes with Apache. So ultimately, the client is communicating with mod_dav_svn, which binds directly to the Subversion Repository Layer.

That was a simplified description of the actual exchanges taking place, though. For example, the Subversion repository might be protected by Apache's authorization directives. This could result in initial attempts to communicate with the repository being rejected by Apache on authorization grounds. At this point, libsvn_ra_dav gets back the notice from Apache that insufficient identification was supplied, and calls back into the Client Layer to get some updated authentication data. If the data is supplied correctly, and the user has the permissions that Apache seeks, libsvn_ra_dav's next automatic attempt at performing the original operation will be granted, and all will be well. If sufficient authentication information cannot be supplied, the request will ultimately fail, and the client will report the failure to the user.

By using Neon and Apache, Subversion gets free functionality in several other complex areas, too. For example, if Neon finds the OpenSSL libraries, it allows the Subversion client to attempt to use SSL-encrypted communications with the Apache server (whose own mod_ssl can «speak the language»). Also, both Neon itself and Apache's mod_deflate can understand the «deflate» algorithm (the same one used by the PKZIP and gzip programs), so requests can be sent in smaller, compressed chunks across the wire. Other complex features that Subversion hopes to support in the future include the ability to automatically handle server-specified redirects (for example, when a repository has been moved to a new canonical URL) and taking advantage of HTTP pipelining.



RA-Local (Direct Repository Access)


Not all communications with a Subversion repository require a powerhouse server process and a network layer. For users who simply wish to access the repositories on their local disk, they may do so using file: URLs and the functionality provided by libsvn_ra_local. This RA module binds directly with the repository and filesystem libraries, so no network communication is required at all.

Subversion requires that the server name included as part of the file: URL be either localhost or empty, and that there be no port specification. In other words, your URLs should look like either file://localhost/path/to/repos or file:///path/to/repos.

Also, be aware that Subversion's file: URLs cannot be used in a regular web browser the way typical file: URLs can. When you attempt to view a file: URL in a regular web browser, it reads and displays the contents of the file at that location by examining the filesystem directly. However, Subversion's resources exist in a virtual filesystem (see «Repository Layer»), and your browser will not understand how to read that filesystem.



RA-SVN (Custom Protocol Repository Access)


In addition to the standard HTTP/WebDAV protocol, Subversion also provides an RA implementation that uses a custom protocol. The libsvn_ra_svn module implements its own network socket connectivity, and communicates with a stand-alone server—the svnserve program—on the machine that hosts the repository. Clients access the repository using the svn:// schema.

This RA implementation lacks most of the advantages of Apache mentioned in the previous section; however, it may be appealing to some system administrators nonetheless. It is dramatically easier to configure and run; setting up an svnserve process is nearly instantaneous. It is also much smaller (in terms of lines of code) than Apache, making it much easier to audit, for security reasons or otherwise. Furthermore, some system administrators may already have an SSH security infrastructure in place, and want Subversion to use it. Clients using ra_svn can easily tunnel the protocol over SSH.



Рабочие копии


Вы уже читали о рабочих копиях; теперь мы покажем как Subversion-клиент создает и использует их.

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

После того, как вы внесли изменения в файлы вашей рабочей копии и убедились в том, что они корректно работают, Subversion предлагает вам команды «публикации» (записи в хранилище) ваших изменений, в результате чего они станут доступными для всех участников проекта. Если другие участники проекта опубликовали свои изменения, Subversion предлагает вам команды для объединения (путем чтения информации из хранилища) этих изменений с вашей рабочей копией.

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

Как правило, хранилище Subversion содержит файлы (или исходный код) нескольких проектов; обычно каждый проект представляется в виде подкаталога файловой системы хранилища. При таком подходе, пользовательская рабочая копия обычно соответствует отдельному подкаталогу хранилища.

Например, предположим, что у вас есть хранилище, содержащее два программных проекта: paint и calc. Каждый проект располагается в своем собственном каталоге, как показано на Рисунок 2.6, «Файловая система хранилища».

Рисунок 2.6. Файловая система хранилища

Для того чтобы создать рабочую копию, вам нужно получить какую-либо из подкаталогов хранилища. (Возможно, термин получить звучит как что-то связанное с блокированием или резервированием ресурсов, но это не так; эта команда просто создает для вас личную копию проекта.) Например, если вы получите /calc, у вас будет рабочая копия, наподобие этой:

$ svn checkout http://svn.example.com/repos/calc A calc/Makefile A calc/integer.c A calc/button.c Checked out revision 56. $ ls -A calc Makefile integer.c button.c .svn/

Буквы А говорят о том, что Subversion добавил этот элемент в вашу рабочую копию. Теперь у вас есть личная копия каталога /calc хранилища, с одним небольшим добавлением — каталогом .svn, содержащим, как было указано выше, дополнительную информацию, необходимую Subversion.

URL хранилища

Получить доступ к хранилищу Subversion можно различными способами — на локальном диске или через ряд сетевых протоколов. Местоположение хранилища всегда определяется при помощи URL. Таблица Таблица 2.1, «URL для доступа к хранилищу.» показывает соответствие разных URL-схем возможным методам доступа.

Таблица 2.1. URL для доступа к хранилищу.

СхемаМетод доступа
file:///прямой доступ к хранилищу (на локальном диске)
http://доступ через протокол WebDAV (если Subversion-сервер работает через Apache)
https://тоже что и http:// но с SSL-шифрованием
svn://доступ через собственный протокол к серверу svnserve
svn+ssh://тоже что и svn://, но через SSH-соединение

Подробнее о том, как Subversion обрабатывает URL, см. в «Subversion Repository URLs».

Предположим, вы внесли изменения в button.c. Так как каталог .svn помнит дату изменения файла и его оригинальное содержимое, Subversion может сказать о том, что вы изменили файл. Subversion не публикует ваших изменений пока вы не прикажете это сделать. Публикация ваших изменений более известна как фиксация (или checking in) изменений в хранилище.

Для того, что бы опубликовать ваши изменения вы можете воспользоваться командой commit:

$ svn commit button.c Sending button.c Transmitting file data . Committed revision 57.

Теперь ваши изменения в button.c зафиксированы в хранилище; если другой пользователь создаст рабочую копию /calc, он увидит ваши изменения в последней версии файла.

Предположим, у вас есть партнер, Салли, которая создала рабочую копию /calc одновременно с вами. Когда вы зафиксировали изменения в button.c, рабочая копия Салли осталась не измененной; Subversion модифицирует рабочие копии только по запросу пользователей.

Для приведения рабочей копии в актуальное состояние, Салли может попросить Subversion обновить её рабочую копию, используя команду Subversion update. Это внедрит ваши изменения в ее рабочую копию вместе с другими изменениями, которые были зафиксированы с момента когда она создавала рабочую копию.

$ pwd /home/sally/calc $ ls -A .svn/ Makefile integer.c button.c $ svn update U button.c Updated to revision 57.

Вывод команды svn update говорит, что Subversion обновила содержимое button.c. Обратите внимание, что Салли не должна указывать, какой файл обновить; для определения файлов, которые необходимо привести в актуальное состояние, Subversion использует информацию в каталоге .svn, а также информацию из хранилища.



Работа с веткой


После создания ветки проекта, можно создать новую рабочую копию для начала ее использования:

$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch A my-calc-branch/Makefile A my-calc-branch/integer.c A my-calc-branch/button.c Checked out revision 341.

В этой рабочей копии нет ничего особенного; она является просто отражением другой директории хранилища. Когда вы фиксируете изменения, то если Салли сделает обновление, она их даже не увидит. Ее рабочая копия является копией /calc/trunk. (Прочтите далее в этой главе раздел «Переключение рабочей копии»: команда svn switch является альтернативным способом создания рабочей копии ветки.)

Предположим, что прошла неделя и были сделаны следующие фиксации:

Вы внесли изменения в /calc/branches/my-calc-branch/button.c, с созданием правки 342.

Вы внесли изменения в /calc/branches/my-calc-branch/integer.c, с созданием правки 343.

Салли внесла изменения в /calc/trunk/integer.c, с созданием правки 344.

Теперь есть два независимых направления разработки файла integer.c, которые показывает Рисунок 4.4, «История ветвления для одного файла».

Рисунок 4.4. История ветвления для одного файла

Если посмотреть историю сделанных изменений для вашей копии integer.c, можно увидеть интересные вещи:

$ pwd /home/user/my-calc-branch $ svn log --verbose integer.c ------------------------------------------------------------------------ r343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/branches/my-calc-branch/integer.c * integer.c: frozzled the wazjub. ------------------------------------------------------------------------ r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: A /calc/branches/my-calc-branch (from /calc/trunk:340) Creating a private branch of /calc/trunk. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: changed a docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: adding this file to the project. ------------------------------------------------------------------------

Обратите внимание на то, что Subversion прослеживает историю ветки integer.c во времени полностью, в том числе пересекая точку создания копии. Создание ветки показывается как событие в истории, потому что файл integer.c был неявно скопирован, при копировании всей директории /calc/trunk/. Теперь давайте посмотрим, что будет когда такую же команду Салли выполнит для своей копии файла:

$ pwd /home/sally/calc $ svn log --verbose integer.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: fix a bunch of spelling errors. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: changed a docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: adding this file to the project. ------------------------------------------------------------------------

Салли увидит свои собственные изменения правки 344, а ваши сделанные в правке 343 нет. Subversion позаботилась о том, что бы эти две фиксации затронули разные файлы, имеющие разное расположение в хранилище. Тем не менее, Subversion будет показывать то, что два файла имеют одну историю. До создания в правке 341 ветки (или копии) это был один файл. Поэтому и вы и Салли видите изменения сделанные в правке 303 и 98.



Repository Access Layer


If the Subversion Repository Layer is at «the other end of the line», the Repository Access Layer is the line itself. Charged with marshalling data between the client libraries and the repository, this layer includes the libsvn_ra module loader library, the RA modules themselves (which currently includes libsvn_ra_dav, libsvn_ra_local, and libsvn_ra_svn), and any additional libraries needed by one or more of those RA modules, such as the mod_dav_svn Apache module with which libsvn_ra_dav communicates or libsvn_ra_svn's server, svnserve.

Since Subversion uses URLs to identify its repository resources, the protocol portion of the URL schema (usually file:, http:, https:, or svn:) is used to determine which RA module will handle the communications. Each module registers a list of the protocols it knows how to «speak» so that the RA loader can, at runtime, determine which module to use for the task at hand. You can determine which RA modules are available to the Subversion command-line client, and what protocols they claim to support, by running svn --version:

$ svn --version svn, version 1.2.3 (r15833) compiled Sep 13 2005, 22:45:22 Copyright (C) 2000-2005 CollabNet. Subversion is open source software, see http://subversion.tigris.org/ This product includes software developed by CollabNet (http://www.Collab.Net/). The following repository access (RA) modules are available: * ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol. - handles 'http' scheme - handles 'https' scheme * ra_svn : Module for accessing a repository using the svn network protocol. - handles 'svn' scheme * ra_local : Module for accessing a repository on local disk. - handles 'file' scheme

Repository Layer


When referring to Subversion's Repository Layer, we're generally talking about two libraries—the repository library, and the filesystem library. These libraries provide the storage and reporting mechanisms for the various revisions of your version-controlled data. This layer is connected to the Client Layer via the Repository Access Layer, and is, from the perspective of the Subversion user, the stuff at the «other end of the line.»

The Subversion Filesystem is accessed via the libsvn_fs API, and is not a kernel-level filesystem that one would install in an operating system (like the Linux ext2 or NTFS), but a virtual filesystem. Rather than storing «files» and «directories» as real files and directories (as in, the kind you can navigate through using your favorite shell program), it uses one of two available abstract storage backends—either a Berkeley DB database environment, or a flat-file representation. (To learn more about the two repository back-ends, see «Repository Data Stores».) However, there has been considerable interest by the development community in giving future releases of Subversion the ability to use other back-end database systems, perhaps through a mechanism such as Open Database Connectivity (ODBC).

The filesystem API exported by libsvn_fs contains the kinds of functionality you would expect from any other filesystem API: you can create and remove files and directories, copy and move them around, modify file contents, and so on. It also has features that are not quite as common, such as the ability to add, modify, and remove metadata («properties») on each file or directory. Furthermore, the Subversion Filesystem is a versioning filesystem, which means that as you make changes to your directory tree, Subversion remembers what your tree looked like before those changes. And before the previous changes. And the previous ones. And so on, all the way back through versioning time to (and just beyond) the moment you first started adding things to the filesystem.

All the modifications you make to your tree are done within the context of a Subversion transaction. The following is a simplified general routine for modifying your filesystem:

Begin a Subversion transaction.

Make your changes (adds, deletes, property modifications, etc.).

Commit your transaction.

Once you have committed your transaction, your filesystem modifications are permanently stored as historical artifacts. Each of these cycles generates a single new revision of your tree, and each revision is forever accessible as an immutable snapshot of «the way things were.»

The Transaction Distraction

The notion of a Subversion transaction, especially given its close proximity to the database code in libsvn_fs, can become easily confused with the transaction support provided by the underlying database itself. Both types of transaction exist to provide atomicity and isolation. In other words, transactions give you the ability to perform a set of actions in an «all or nothing» fashion—either all the actions in the set complete with success, or they all get treated as if none of them ever happened—and in a way that does not interfere with other processes acting on the data.

Database transactions generally encompass small operations related specifically to the modification of data in the database itself (such as changing the contents of a table row). Subversion transactions are larger in scope, encompassing higher-level operations like making modifications to a set of files and directories which are intended to be stored as the next revision of the filesystem tree. If that isn't confusing enough, consider this: Subversion uses a database transaction during the creation of a Subversion transaction (so that if the creation of Subversion transaction fails, the database will look as if we had never attempted that creation in the first place)!

Fortunately for users of the filesystem API, the transaction support provided by the database system itself is hidden almost entirely from view (as should be expected from a properly modularized library scheme). It is only when you start digging into the implementation of the filesystem itself that such things become visible (or interesting).

Most of the functionality provided by the filesystem interface comes as an action that occurs on a filesystem path. That is, from outside of the filesystem, the primary mechanism for describing and accessing the individual revisions of files and directories comes through the use of path strings like /foo/bar, just as if you were addressing files and directories through your favorite shell program. You add new files and directories by passing their paths-to-be to the right API functions. You query for information about them by the same mechanism.

Unlike most filesystems, though, a path alone is not enough information to identify a file or directory in Subversion. Think of a directory tree as a two-dimensional system, where a node's siblings represent a sort of left-and-right motion, and descending into subdirectories a downward motion. Рисунок 8.1, «Files and directories in two dimensions» shows a typical representation of a tree as exactly that.

Рисунок 8.1. Files and directories in two dimensions

Of course, the Subversion filesystem has a nifty third dimension that most filesystems do not have—Time! [47] In the filesystem interface, nearly every function that has a path argument also expects a root argument. This svn_fs_root_t argument describes either a revision or a Subversion transaction (which is usually just a revision-to-be), and provides that third-dimensional context needed to understand the difference between /foo/bar in revision 32, and the same path as it exists in revision 98. Рисунок 8.2, «Versioning time—the third dimension!» shows revision history as an added dimension to the Subversion filesystem universe.

Рисунок 8.2. Versioning time—the third dimension!

As we mentioned earlier, the libsvn_fs API looks and feels like any other filesystem, except that it has this wonderful versioning capability. It was designed to be usable by any program interested in a versioning filesystem. Not coincidentally, Subversion itself is interested in that functionality. But while the filesystem API should be sufficient for basic file and directory versioning support, Subversion wants more—and that is where libsvn_repos comes in.

The Subversion repository library (libsvn_repos) is basically a wrapper library around the filesystem functionality. This library is responsible for creating the repository layout, making sure that the underlying filesystem is initialized, and so on. Libsvn_repos also implements a set of hooks—scripts that are executed by the repository code when certain actions take place. These scripts are useful for notification, authorization, or whatever purposes the repository administrator desires. This type of functionality, and other utilities provided by the repository library, are not strictly related to implementing a versioning filesystem, which is why it was placed into its own library.

Developers who wish to use the libsvn_repos API will find that it is not a complete wrapper around the filesystem interface. That is, only certain major events in the general cycle of filesystem activity are wrapped by the repository interface. Some of these include the creation and commit of Subversion transactions, and the modification of revision properties. These particular events are wrapped by the repository layer because they have hooks associated with them. In the future, other events may be wrapped by the repository API. All of the remaining filesystem interaction will continue to occur directly via the libsvn_fs API, though.

For example, here is a code segment that illustrates the use of both the repository and filesystem interfaces to create a new revision of the filesystem in which a directory is added. Note that in this example (and all others throughout this book), the SVN_ERR() macro simply checks for a non-successful error return from the function it wraps, and returns that error if it exists.

Пример 8.1. Using the Repository Layer

/* Create a new directory at the path NEW_DIRECTORY in the Subversion repository located at REPOS_PATH. Perform all memory allocation in POOL. This function will create a new revision for the addition of NEW_DIRECTORY. */ static svn_error_t * make_new_directory (const char *repos_path, const char *new_directory, apr_pool_t *pool) { svn_error_t *err; svn_repos_t *repos; svn_fs_t *fs; svn_revnum_t youngest_rev; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_str; /* Open the repository located at REPOS_PATH. */ SVN_ERR (svn_repos_open (&repos, repos_path, pool)); /* Get a pointer to the filesystem object that is stored in REPOS. */ fs = svn_repos_fs (repos); /* Ask the filesystem to tell us the youngest revision that currently exists. */ SVN_ERR (svn_fs_youngest_rev (&youngest_rev, fs, pool)); /* Begin a new transaction that is based on YOUNGEST_REV. We are less likely to have our later commit rejected as conflicting if we always try to make our changes against a copy of the latest snapshot of the filesystem tree. */ SVN_ERR (svn_fs_begin_txn (&txn, fs, youngest_rev, pool)); /* Now that we have started a new Subversion transaction, get a root object that represents that transaction. */ SVN_ERR (svn_fs_txn_root (&txn_root, txn, pool)); /* Create our new directory under the transaction root, at the path NEW_DIRECTORY. */ SVN_ERR (svn_fs_make_dir (txn_root, new_directory, pool)); /* Commit the transaction, creating a new revision of the filesystem which includes our added directory path. */ err = svn_repos_fs_commit_txn (&conflict_str, repos, &youngest_rev, txn, pool); if (! err) { /* No error? Excellent! Print a brief report of our success. */ printf ("Directory '%s' was successfully added as new revision " "'%ld'.\n", new_directory, youngest_rev); } else if (err->apr_err == SVN_ERR_FS_CONFLICT) { /* Uh-oh. Our commit failed as the result of a conflict (someone else seems to have made changes to the same area of the filesystem that we tried to modify). Print an error message. */ printf ("A conflict occurred at path '%s' while attempting " "to add directory '%s' to the repository at '%s'.\n", conflict_str, new_directory, repos_path); } else { /* Some other error has occurred. Print an error message. */ printf ("An error occurred while attempting to add directory '%s' " "to the repository at '%s'.\n", new_directory, repos_path); } /* Return the result of the attempted commit to our caller. */ return err; }

In the previous code segment, calls were made to both the repository and filesystem interfaces. We could just as easily have committed the transaction using svn_fs_commit_txn(). But the filesystem API knows nothing about the repository library's hook mechanism. If you want your Subversion repository to automatically perform some set of non-Subversion tasks every time you commit a transaction (like, for example, sending an email that describes all the changes made in that transaction to your developer mailing list), you need to use the libsvn_repos-wrapped version of that function—svn_repos_fs_commit_txn(). This function will actually first run the pre-commit hook script if one exists, then commit the transaction, and finally will run a post-commit hook script. The hooks provide a special kind of reporting mechanism that does not really belong in the core filesystem library itself. (For more information regarding Subversion's repository hooks, see «Hook Scripts».)

The hook mechanism requirement is but one of the reasons for the abstraction of a separate repository library from the rest of the filesystem code. The libsvn_repos API provides several other important utilities to Subversion. These include the abilities to:

create, open, destroy, and perform recovery steps on a Subversion repository and the filesystem included in that repository.

describe the differences between two filesystem trees.

query for the commit log messages associated with all (or some) of the revisions in which a set of files was modified in the filesystem.

generate a human-readable «dump» of the filesystem, a complete representation of the revisions in the filesystem.

parse that dump format, loading the dumped revisions into a different Subversion repository.

As Subversion continues to evolve, the repository library will grow with the filesystem library to offer increased functionality and configurable option support.



Revision Numbers Are Different Now


In CVS, revision numbers are per-file. This is because CVS stores its data in RCS files; each file has a corresponding RCS file in the repository, and the repository is roughly laid out according to the structure of your project tree.

In Subversion, the repository looks like a single filesystem. Each commit results in an entirely new filesystem tree; in essence, the repository is an array of trees. Each of these trees is labeled with a single revision number. When someone talks about «revision 54», they're talking about a particular tree (and indirectly, the way the filesystem looked after the 54th commit).

Technically, it's not valid to talk about «revision 5 of foo.c». Instead, one would say «foo.c as it appears in revision 5». Also, be careful when making assumptions about the evolution of a file. In CVS, revisions 5 and 6 of foo.c are always different. In Subversion, it's most likely that foo.c did not change between revisions 5 and 6.

For more details on this topic, see «Правки».

Пред.   След.
mod_dav_svn Содержание Directory Versions


Ручной контроль слияния


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

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

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

Что это означает для вас, как пользователя? Это означает, что до того момента, пока у Subversion не появится этой функции, вам придется контролировать слияние информации самостоятельно. Лучшим местом для этого является лог-сообщение. Как было показано в предыдущих примерах, рекомендуется, что бы в лог-сообщении был указан конкретный номер правки (или диапазон правок) которые были слиты в вашу ветку. После этого, для того, что бы просмотреть какие изменения ваша ветка уже содержит, вы можете запустить команду svn log. Это позволит быть аккуратнее при выполнении команды svn merge, что бы не пересечься с уже портированными изменениями.

В следующем разделе мы на примерах рассмотрим эту технику в действии.



Servers


В файле servers находятся настройки, относящиеся к работе Subversion через сеть. Он содержит два специальных раздела — groups и global. Раздел groups представляет собой просто перекрестную таблицу. Ключи этого раздела являются именами последующих разделов файла; значения ключей представляют собой обобщения — текстовые блоки, которые могут содержать подстановочные символы — сравниваемые с именами машин, к которым Subversion направляет запросы.

[groups] beanie-babies = *.red-bean.com collabnet = svn.collab.net [beanie-babies] … [collabnet] …

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

Раздел global содержит настройки, используемые для всех серверов, не подпадающих ни под одно обобщение раздела groups. Здесь указываются те-же, что и для остальных серверных разделов файла параметры (конечно, за исключением специального раздела groups), используемые параметры приведены ниже:

http-proxy-host

Указывает имя компьютера-посредника, через который Subversion должна отправлять HTTP-запросы. По умолчанию, этот параметр имеет пустое значение, которое говорит Subversion о том, что она должна направлять HTTP-запросы не через компьютер-посредник, а связываться с целевой машиной напрямую.

http-proxy-port

Указывает номер используемого порта на промежуточном компьютере. По умолчанию имеет пустое значение.

http-proxy-username

Указывает имя пользователя, передаваемого компьютеру-посреднику. По умолчанию имеет пустое значение.

http-proxy-password

Указывает пароль, передаваемый компьютеру-посреднику. По умолчанию имеет пустое значение.

http-timeout

Указывает, в секундах, промежуток времени ожидания ответа сервера. Если при низкоскоростном сетевом соединении у вас возникает проблема превышения времени ожидания, следует увеличить это значение. Значение по умолчанию 0 означает для низлежащей HTTP библиотеки, Neon, использовать свое собственное значение времени ожидания.

http-compression

Указывает, должна или нет Subversion использовать сжатие сетевых запросов, выполняющихся к DAV-серверам. Значением по умолчанию является yes (однако выполняться сжатие будет только если такая возможность поддерживается сетевым слоем). Установите этот параметр в no, для отключения сжатия, например при отладке сетевых транзакций.

neon-debug-mask

Целочисленная маска, которая используется низлежащей HTTP-библиотекой, Neon, для определения типа выводимой отладочной информации. По умолчанию установлено значение 0, скрывающие весь отладочный вывод. Подробнее о том как Subversion использует Neon читайте в разделе Глава 8, Информация для разработчиков.

ssl-authority-files

Разделенный точкой с запятой перечень путей к файлам, содержащим сертификаты авторизации (или CAs), используемые Subversion-клиентом при обращении к хранилищу через HTTPS.

ssl-trust-default-ca

Установите значение этой переменной в yes, если хотите чтобы Subversion автоматически доверяла набору поставляемых вместе с OpenSSL сертификатов (CAs).

ssl-client-cert-file

Если хост (или хосты) требуют SSL сертификат клиента, у вас будет запрошен путь к вашему сертификату. Установите значение этой переменной и Subversion сможет автоматически находить ваш сертификат, без запроса. Нет стандартного места для хранения сертификата на диске; Subversion будет использовать тот, который располагается по указанному вами пути.

ssl-client-cert-password

Если ваш клиентский SSL сертификат защищен паролем, при обращении к нему Subversion запросит у вас пароль. Если это вам надоедает (и вас не пугает хранить пароль в файле servers), можно присвоить значению этой переменной пароль сертификата. После этого пароль больше запрашиваться не будет.