Руководство по svn

Материал страницы находится в разработке!

Вернуться к общему содержанию «Инструментальные средства программиста».

    Содержание

  • Введение
  • Историческая справка
  • Технические вопросы устройства
    • Две концепции, используемые для разделения файлов
    • Физическое представление репозитория
    • Логическое представление репозитория
  • Использование систем контроля версий
    • Получение справочной информации
    • Создание репозитория

Введение

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

Одной из отличительных черт данного руководства является проведение сравнений и аналогий между SVN и Git. Git был разработан несколько позже SVN, и был ориентирован на очень специфический проект — разработка ядра Linux, которая ведется очень большим кругом разработчиков разбросанных по всему миру. Архитектура и реализация Git оказалась привлекательной для ведения других программных проектов и сегодня, наверное, именно SVN и Git являются самыми популярными системами контроля версий. SVN и Git сильно отличаются по своим базовым идеям, и выбор между использованием SVN или Git должен опираться на понимание этих различий. В рамках данного руководства, мы будем не только изучать SVN и Git, но и акцентировать внимание на отличительных особенностях этих систем, что, кроме прочего, должно усилить продуктивность изучения — знакомство с тем, что и как может быть сделано по-другому, упростит запоминание материала.

Последний раздел посвящён специальным возможностям системы Git по трансформациям между своим локальным репозиторием и центральным репозиторием SVN. Многим будет интересно знать, что с центральным репозиторием SVN можно работать средствами Git. Такая синхронизация разноархитектурных репозиториев, доступная благодаря возможностям Git, поможет вам увидеть преимущества и недостатки разных подходов.

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

Историческая справка

Subversion

Subversion — система управления версиями в свободной лицензии. Известна под сокращенным именем SVN. Разработка Subversion началась в 2000 году по инициативе и финансовой поддержке компании CollabNet Inc.

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

Официальный выпуск Subversion — 2004 год.

Git

Разработка Git началась в 2005 году, по инициативе разработчика Linux — Линуса Торвальдса.

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

Технические вопросы устройства

Две концепции, используемые для разделения файлов

Чтобы разделить файловое хранилище на множество пользователей можно использовать одну из двух известных схем разделения.

  1. Lock-Modify-Unlock — чтобы внести изменение, надо заблокировать файловое хранилище, выполнить изменение и, после этого, разблокировать (вернуть в общее пользование). Такая схема может работать в полностью автоматическом режиме, так как исключает возможные коллизии изменений, и используется в многопоточном программировании для защиты критических секций данных. В файловых репозиториях, такая схема не удобна, так как исключает возможность параллельной работы пользователей над изменением файлов.
  2. Copy-Modify-Merge — каждый из пользователей работает со своей копией данных, которая потом синхронизируется с состоянием центрального репозитория. Недостатком таких схем является необходимость ручного вмешательства в процесс синхронизации разных копий, если в них содержатся изменения одного и того же фрагмента данных.

Обе системы, Subversion и Git, используют вторую схему разделения данных (Copy-Modify-Merge), но делают это немного по-разному.

Физическое представление репозитория

Subversion

SVN относится к типу централизованных систем, в отличии от Git и Mercurial, которые являются представителями класса распределенных систем. Централизованность означает работу схемы только при наличии централизованного хранилища данных.

Развертывание системы Subversion может опираться на две разные физические системы хранения данных репозитория. Исторически, первый вариант организации репозитория был основан на использовании СУБД Berkeley DB. Позже, была выполнена реализация на основе специального файлового хранилища данных (FSFS), поддерживаемое собственными программными библиотеками. Начиная с релиза 1.2 для новых хранилищ, по умолчанию, используется FSFS.

Реализацию на основе СУБД Berkley DB можно считать более капризной. Во-первых, ее настройка требует большего внимания администратора. Во-вторых, Berkley DB требовательна к выбору низлежащей файловой системы — она должна поддерживать блокировки.

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

Логическое представление репозитория

Репозиторий проекта может быть логически представлен двумерным массивом в котором вертикальным индексом является имя файла, а горизонтальным — номер ревизии — целое
число, растущее при каждой фиксации кода в хранилище. Каждая выборка из репозитория представляет собой «срез» файлов по номеру ревизии. Если номер ревизии не указывается
(обычно через опцию -r), то берется самый последний номер ревизии.

Примечание: картинка взята со страницы https://ru.wikipedia.org/wiki/Subversion

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

SVN vs Git. Здесь мы наблюдаем существенное различие в использовании, и, особенно,
администрировании систем SVN и Git. В Git, под каждый проект в любой директории
можно реализовать работу локального репозитория, чего, часто, для индивидуальной
работы, бывает достаточно. Централизованный репозиторий, при его необходимости,
так же организуется под каждый проект отдельно, позволяя для каждого проекта
построить свою политику прав доступа. Если быть более точным, то Git значительно
сосредоточен именно на средствах управления версиями и, при использовании
централизованных репозиториев, для тонкого разделения доступа к коду проекта
множества пользователей удобнее использовать дополнительные оберточные средства
администрирования Git. Cреди последних, известными являются gitolite и gitosys.

Различают понятия стержневых ревизий (peg revision) и оперативных ревизий (operative revision). Стержневая ревизия представляет собой номер ревизии предназначенный для уточнения файловых историй для оперативных ревизий по которым выполняются операции команд. Т.е. Команда может быть задана по диапазону оперативных ревизий в которых может быть коллизии файловых историй связанных с операциями копирования, перемещения и уничтожения файлов. Чтобы однозначно указать требуемую файловую историю необходимо указывать стержневую ревизию по правому краю диапазона оперативных ревизий, так как история файла однозначно отслеживается только в обратном направлении. При
отслеживании истории в прямом направлении можно столкнуться, например, с разветвлением, созданным при копировании файла. Работа пользователя с файлами проекта выполняется в рабочей копии репозитория, которая создается получением файлового снимка всего репозитория SVN или его части (через уточнение нужной поддиректории) с помощью операции svn checkout (по умолчанию будет передана последняя ревизия). Если пользователь хочет зафиксировать изменения в репозитории проекта, то он должен выполнить операцию svn commit. При каждой фиксации кода создается новая ревизия с большим номером.

Git

Основная суть организации репозитория Git в том, что он хранит файлы в виде файлов, а в качестве имени файла в репозитории используется значение хэш-функции SHA1, вычисленной по содержимому файла.

Таким образом, одинаковые файлы имеют одинаковое значение хеш-функции и хранятся один раз.

Одной из особенностей такого файлового хранения является то, что в Git не хранятся директории как таковые, а только в виде файловых путей. Следовательно, пустую директорию нельзя сохранить в репозитории Git.

Логическое представление репозитория

Объекты репозитория Git бывают четырех типов — blob, tree, commit и tag.

Использование систем контроля версий

Получение справочной информации

Subversion (SVN)

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


svn help checkout
svn help commit
svn help mkdir

Создание репозитория

Subversion (SVN)

Продумаем размещение и выберем имя для директории будущего репозитория SVN. При этом подумайте о правах доступа, если репозиторий будет разделяемый. Для простоты я
сделаю репозиторий в своем домашнем каталоге /home/knz с именем 0-svn-repository. Имя начинающееся с нуля предоставит дополнительный приоритет для данной директории для
многих типов сортировок при выводе списка директорий и такая директория не затеряется в окружении многих других директорий домашнего каталога.

Находясь в домашней директории выполним команду.

svnadmin create 0-svn-repository

Репозиторий создан. Пустой репозиторий имеет нулевой номер ревизии. Теперь в него можно добавлять проекты для управления. Дальнейшая последовательность действий может быть такая.

  1. Создадим где-нибудь начальный оригинал будущего проекта.
  2. Выполним импорт этого оригинала проекта в репозиторий SVN с помощью команды svn import.
  3. Оригинал проекта теперь стратегического смысла не имеет и его можно удалить.
  4. Создаем рабочую копию проекта из репозитория SVN с помощью команды svn checkout.
  5. Работаем с рабочей копией, вносим в нее изменения. Чтобы зафиксировать изменения необходимо передать их в репозиторий SVN с помощью команды svn commit. При
    этом, в репозитории проекта, будет создана очередная по счету ревизия.

Игнорирование файлов SVN
Сделать файл list с именами или масками, разделённые переводом строки
$ svn propset ‘svn:ignore’ -F list

Основные понятия SVN

Система контроля версий (VCS) – это программное обеспечение, которое помогает разработчикам программного обеспечения работать вместе и вести полную историю своей работы.

Ниже приведены цели системы контроля версий.

  • Разрешить разработчикам работать одновременно.
  • Не перезаписывайте изменения друг друга.
  • Поддерживать историю каждой версии всего.

VCS делится на две категории.

  • Централизованная система контроля версий (CVCS), и
  • Распределенная / децентрализованная система контроля версий (DVCS).

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

Терминология контроля версий

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

  • Репозиторий: Репозиторий является сердцем любой системы контроля версий. Это центральное место, где разработчики хранят всю свою работу. Репозиторий хранит не только файлы, но и историю. Доступ к репозиторию осуществляется через сеть, выступая в роли сервера и инструмента контроля версий, выступающего в роли клиента. Клиенты могут подключаться к хранилищу, а затем они могут сохранять / извлекать свои изменения в / из хранилища. Сохраняя изменения, клиент делает эти изменения доступными для других людей, а путем извлечения изменений клиент воспринимает изменения других людей как рабочую копию.

  • Магистраль: Магистраль – это каталог, в котором происходит вся основная разработка, и обычно проверяется разработчиками для работы над проектом.

  • Теги : каталог тегов используется для хранения именованных снимков проекта. Работа с тегами позволяет задавать описательные и запоминающиеся имена конкретной версии в репозитории.

    Например, LAST_STABLE_CODE_BEFORE_EMAIL_SUPPORT более запоминающимся, чем

    UUID репозитория: 7ceef8cb-3799-40dd-a067-c216ec2e5247 и

    Редакция: 13

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

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

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

Репозиторий: Репозиторий является сердцем любой системы контроля версий. Это центральное место, где разработчики хранят всю свою работу. Репозиторий хранит не только файлы, но и историю. Доступ к репозиторию осуществляется через сеть, выступая в роли сервера и инструмента контроля версий, выступающего в роли клиента. Клиенты могут подключаться к хранилищу, а затем они могут сохранять / извлекать свои изменения в / из хранилища. Сохраняя изменения, клиент делает эти изменения доступными для других людей, а путем извлечения изменений клиент воспринимает изменения других людей как рабочую копию.

Магистраль: Магистраль – это каталог, в котором происходит вся основная разработка, и обычно проверяется разработчиками для работы над проектом.

Теги : каталог тегов используется для хранения именованных снимков проекта. Работа с тегами позволяет задавать описательные и запоминающиеся имена конкретной версии в репозитории.

Например, LAST_STABLE_CODE_BEFORE_EMAIL_SUPPORT более запоминающимся, чем

UUID репозитория: 7ceef8cb-3799-40dd-a067-c216ec2e5247 и

Редакция: 13

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

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

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

Настройка среды SVN

Установка SVN

Subversion – это популярный инструмент контроля версий с открытым исходным кодом. Это с открытым исходным кодом и доступно бесплатно через Интернет. Он поставляется по умолчанию с большинством дистрибутивов GNU / Linux, поэтому он может быть уже установлен в вашей системе. Чтобы проверить, установлен он или нет, используйте следующую команду.

[jerry@CentOS ~]$ svn --version

Если клиент Subversion не установлен, команда сообщит об ошибке, в противном случае будет отображена версия установленного программного обеспечения.

[jerry@CentOS ~]$ svn --version
-bash: svn: command not found

Если вы используете основанную на RPM GNU / Linux, используйте для установки команду yum . После успешной установки выполните команду svn –version .

[jerry@CentOS ~]$ su -
Password: 
[root@CentOS ~]# yum install subversion

[jerry@CentOS ~]$ svn --version
svn, version 1.6.11 (r934486)
compiled Jun 23 2012, 00:44:03

А если вы используете GNU / Linux на основе Debian, то для установки используйте команду apt .

[jerry@Ubuntu]$ sudo apt-get update
[sudo] password for jerry:

[jerry@Ubuntu]$ sudo apt-get install subversion

[jerry@Ubuntu]$ svn --version
svn, version 1.7.5 (r1336830)
compiled Jun 21 2013, 22:11:49

Настройка Apache

Мы видели, как установить клиент Subversion в GNU / Linux. Давайте посмотрим, как создать новый репозиторий и разрешить доступ пользователям.

На сервере мы должны установить модуль Apache httpd и инструмент svnadmin .

[jerry@CentOS ~]$ su -
Password: 
[root@CentOS ~]# yum install mod_dav_svn subversion

Пакет mod_dav_svn позволяет получить доступ к хранилищу по HTTP, через сервер Apache httpd, а пакет subversion устанавливает инструмент svnadmin.

Subversion считывает свою конфигурацию из файла /etc/httpd/conf.d/subversion.conf . После добавления конфигурации файл subversion.conf выглядит следующим образом:

LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

<Location /svn>
   DAV svn
   SVNParentPath /var/www/svn
   AuthType Basic
   AuthName "Authorization Realm"
   AuthUserFile /etc/svn-users
   Require valid-user
</Location>

Давайте создадим пользователей Subversion и предоставим им доступ к хранилищу. Команда htpasswd используется для создания и обновления текстовых файлов, которые используются для хранения имен пользователей и паролей для базовой аутентификации пользователей HTTP. Опция ‘-c’ создает файл паролей , если файл паролей уже существует, он перезаписывается. Поэтому используйте опцию -c только в первый раз. Опция ‘-m’ включает шифрование MD5 для паролей.

Настройка пользователя

Давайте создадим пользователя Том .

[root@CentOS ~]# htpasswd -cm /etc/svn-users tom
New password: 
Re-type new password: 
Adding password for user tom

Давайте создадим пользователя Джерри

[root@CentOS ~]# htpasswd -m /etc/svn-users jerry
New password: 
Re-type new password: 
Adding password for user jerry
[root@CentOS ~]# 

Создайте родительский каталог Subversion для хранения всей работы (см. /Etc/httpd/conf.d/subversion.conf ).

[root@CentOS ~]# mkdir /var/www/svn
[root@CentOS ~]# cd /var/www/svn/

Настройка репозитория

Создайте репозиторий проекта с именем project_repo . Команда svnadmin создаст новый репозиторий и несколько других каталогов внутри него для хранения метаданных.

[root@CentOS svn]# svnadmin create project_repo

[root@CentOS svn]# ls -l project_repo
total 24
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 conf
drwxr-sr-x. 6 root root 4096 Aug  4 22:30 db
-r--r--r--. 1 root root    2 Aug  4 22:30 format
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 hooks
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 locks
-rw-r--r--. 1 root root  229 Aug  4 22:30 README.txt

Давайте изменим пользователя и группу владельцев хранилища.

[root@CentOS svn]# chown -R apache.apache project_repo/

Проверьте, включен ли SELinux или нет с помощью инструмента состояния SELinux.

[root@CentOS svn]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

Для нашего сервера SELinux включен, поэтому мы должны изменить контекст безопасности SELinux.

[root@CentOS svn]# chcon -R -t httpd_sys_content_t /var/www/svn/project_repo/

Чтобы разрешить фиксацию по HTTP, выполните следующую команду.

[root@CentOS svn]# chcon -R -t httpd_sys_rw_content_t /var/www/svn/project_repo/

Перезапустите сервер Apache, и мы закончили с настройкой сервера Apache.

[root@CentOS svn]# service httpd restart
Stopping httpd:                                            [FAILED]
Starting httpd: httpd: apr_sockaddr_info_get() failed for CentOS
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
[root@CentOS svn]# service httpd status
httpd (pid  1372) is running...
[root@CentOS svn]#

Мы успешно настроили сервер Apache, теперь настроим хранилище. Предоставить доступ к хранилищу только аутентичным пользователям и использовать файл авторизации по умолчанию; добавьте следующие строки в файл project_repo / conf / svnserve.conf .

anon-access = none
authz-db = authz

Традиционно, у каждого проекта Subversion есть каталоги стволов, тегов и веток непосредственно в корневом каталоге проекта.

Магистраль – это каталог, в котором происходит вся основная разработка, и обычно проверяется разработчиками для работы над проектом.

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

Каталог веток используется, когда вы хотите заниматься разными направлениями развития.

Давайте создадим структуру каталогов стволов, тегов и ветвей в репозитории проекта.

[root@CentOS svn]# mkdir /tmp/svn-template
[root@CentOS svn]# mkdir /tmp/svn-template/trunk
[root@CentOS svn]# mkdir /tmp/svn-template/branches
[root@CentOS svn]# mkdir /tmp/svn-template/tags

Теперь импортируйте каталоги из / tmp / svn-template в репозиторий.

[root@CentOS svn]# svn import -m 'Create trunk, branches, tags directory structure' /tmp/svn-template/ 
Adding         /tmp/svn-template/trunk
Adding         /tmp/svn-template/branches
Adding         /tmp/svn-template/tags
Committed revision 1.
[root@CentOS svn]#

Готово! Мы успешно создали хранилище и разрешили доступ Тому и Джерри . Отныне они могут выполнять все поддерживаемые операции с хранилищем.

Жизненный цикл SVN

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

Создать репозиторий:

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

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

Проверять, выписываться

Операция «Оформить заказ» используется для создания рабочей копии из хранилища. Рабочая копия – это личное рабочее место, где разработчики вносят свои изменения, а затем отправляют эти изменения в хранилище.

Обновить

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

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

Теперь рабочая копия Тома устарела. Операция обновления извлечет последние изменения Джерри из хранилища и обновит рабочую копию Тома .

Выполнить изменения

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

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

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

Операция «Переименовать» изменяет имя файла / каталога. Операция «Перемещение» используется для перемещения файлов / каталогов из одного места в другое в дереве хранилища.

Обзор изменений

Когда вы извлекаете рабочую копию или обновляете рабочую копию, ваша рабочая копия полностью синхронизируется с хранилищем. Но когда вы вносите изменения в свою рабочую копию, она становится новее, чем хранилище. Хорошей практикой является проверка ваших изменений перед операцией ‘commit’.

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

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

Исправить ошибки

Давайте предположим, что кто-то внес изменения в свою рабочую копию, но теперь он хочет отбросить эти изменения. В этой ситуации поможет операция «возврат».

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

Разрешить конфликты:

Конфликты могут возникнуть во время слияния. Операция «Слияние» автоматически обрабатывает все, что можно сделать безопасно. Все остальное считается конфликтом. Например, файл «hello.c» был изменен в ветви и удален в другой ветви. Такая ситуация требует, чтобы человек принял решение. Операция ‘resolve’ используется, чтобы помочь пользователю разобраться в вещах и проинформировать VCS о способах обработки конфликтов.

Зафиксировать изменения

Операция ‘Зафиксировать’ используется для применения изменений из рабочей копии в хранилище. Эта операция изменяет хранилище, и другие разработчики могут видеть эти изменения, обновляя свою рабочую копию.

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

Процесс проверки SVN

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

[tom@CentOS ~]$ svn checkout http://svn.server.com/svn/project_repo --username=tom

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

A    project_repo/trunk
A    project_repo/branches
A    project_repo/tags
Checked out revision 1.

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

[tom@CentOS trunk]$ pwd
/home/tom/project_repo/trunk

[tom@CentOS trunk]$ svn info

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

Path: .
URL: http://svn.server.com/svn/project_repo/trunk
Repository Root: http://svn.server.com/svn/project_repo
Repository UUID: 7ceef8cb-3799-40dd-a067-c216ec2e5247
Revision: 1
Node Kind: directory
Schedule: normal
Last Changed Author: jerry
Last Changed Rev: 0
Last Changed Date: 2013-08-24 18:15:52 +0530 (Sat, 24 Aug 2013)

[tom@CentOS trunk]$ 

SVN выполнить изменения

Джерри проверяет последнюю версию репозитория и начинает работать над проектом. Он создает файл array.c внутри директории транка.

[jerry@CentOS ~]$ cd project_repo/trunk/

[jerry@CentOS trunk]$ cat array.c

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

#include <stdio.h>
#define MAX 16

int main(void) {
   int i, n, arr[MAX];
   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   printf("Enter the elementsn");

   for (i = 0; i < n; ++i) scanf("%d", &arr[i]);
   printf("Array has following elementsn");
   for (i = 0; i < n; ++i) printf("|%d| ", arr[i]);
   
   printf("n");
   return 0;
}

Он хочет проверить свой код перед коммитом.

[jerry@CentOS trunk]$ make array
cc     array.c   -o array

[jerry@CentOS trunk]$ ./array 
Enter the total number of elements: 5
Enter the elements
1
2
3
4
5
Array has following elements
|1| |2| |3| |4| |5| 

Он скомпилировал и протестировал свой код, и все работает, как и ожидалось, теперь пришло время вносить изменения.

[jerry@CentOS trunk]$ svn status
?       array.c
?       array

Subversion показывает ‘?’ перед именами файлов, потому что он не знает, что делать с этими файлами.

Перед фиксацией Джерри необходимо добавить этот файл в список ожидающих изменений.

[jerry@CentOS trunk]$ svn add array.c 
A         array.c

Давайте проверим это с помощью операции «status». Subversion показывает A перед array.c , это означает, что файл успешно добавлен в ожидающий список изменений.

[jerry@CentOS trunk]$ svn status
?       array
A       array.c

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

[jerry@CentOS trunk]$ svn commit -m "Initial commit"
Adding         trunk/array.c
Transmitting file data .
Committed revision 2.

Теперь файл array.c успешно добавлен в хранилище, а номер ревизии увеличивается на единицу.

Изменения в обзоре SVN

Джерри уже добавил файл array.c в хранилище. Том также проверяет последний код и начинает работать.

[tom@CentOS ~]$ svn co http://svn.server.com/svn/project_repo --username=tom

Выше команда даст следующий результат.

A    project_repo/trunk
A    project_repo/trunk/array.c
A    project_repo/branches
A    project_repo/tags
Checked out revision 2.

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

[tom@CentOS trunk]$ svn log

Выше команда даст следующий результат.

------------------------------------------------------------------------
r2 | jerry | 2013-08-17 20:40:43 +0530 (Sat, 17 Aug 2013) | 1 line

Initial commit
------------------------------------------------------------------------
r1 | jerry | 2013-08-04 23:43:08 +0530 (Sun, 04 Aug 2013) | 1 line

Create trunk, branches, tags directory structure
------------------------------------------------------------------------

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

#include <stdio.h>

#define MAX 16

int main(void)
{
   int i, n, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* handle array overflow condition */
   if (n > MAX) {
      fprintf(stderr, "Number of elements must be less than %dn", MAX);
      return 1;
   }

   printf("Enter the elementsn");

   for (i = 0; i < n; ++i)
      scanf("%d", &arr[i]);

   printf("Array has following elementsn");
   for (i = 0; i < n; ++i)
      printf("|%d| ", arr[i]);
      printf("n");

   return 0;
}

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

[tom@CentOS trunk]$ svn status
M       array.c

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

[tom@CentOS trunk]$ svn diff
Index: array.c
===================================================================
--- array.c   (revision 2)
+++ array.c   (working copy)
@@ -9,6 +9,11 @@
    printf("Enter the total number of elements: ");
    scanf("%d", &n);
 
+   if (n > MAX) {
+      fprintf(stderr, "Number of elements must be less than %dn", MAX);
+      return 1;
+   }
+
    printf("Enter the elementsn");
 
    for (i = 0; i < n; ++i)

Том добавил несколько строк в файл array.c , поэтому Subversion показывает знак + перед новыми строками. Теперь он готов совершить свои изменения.

[tom@CentOS trunk]$ svn commit -m "Fix array overflow problem"

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

Sending        trunk/array.c
Transmitting file data .
Committed revision 3.

Изменения Тома успешно переданы в хранилище.

Процесс обновления SVN

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

#include <stdio.h>
#define MAX 16

void accept_input(int *arr, int n) {
   int i;
   for (i = 0; i < n; ++i) 
   scanf("%d", &arr[i]);
}

void display(int *arr, int n) {
   int i;
   for (i = 0; i < n; ++i) 
   printf("|%d| ", arr[i]);
   
   printf("n");
}

int main(void) {
   int i, n, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   printf("Enter the elementsn");
   accept_input(arr, n);

   printf("Array has following elementsn");
   display(arr, n);

   return 0;
}

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

[jerry@CentOS trunk]$ svn diff

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

Index: array.c
===================================================================
--- array.c   (revision 2)
+++ array.c   (working copy)
@@ -2,6 +2,24 @@
 
 #define MAX 16
 
+void accept_input(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i & n; ++i)
+      scanf("%d", &arr[i]);
+}
+
+void display(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      printf("|%d| ", arr[i]);
+   
+   printf("n");
+}
+
 int main(void)
 {
    int i, n, arr[MAX];
@@ -10,15 +28,10 @@
    scanf("%d", &n);
 
    printf("Enter the elementsn");
+   accept_input(arr, n);
 
-   for (i = 0; i < n; ++i)
-      scanf("%d", &arr[i]);
-
    printf("Array has following elementsn");
-   for (i = 0; i < n; ++i)
-      printf("|%d| ", arr[i]);
-   
-   printf("n");
+   display(arr, n);
 
    return 0;
 }

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

[jerry@CentOS trunk]$ svn commit -m "Add function to accept input and to display array contents"

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

Sending        trunk/array.c
svn: Commit failed (details follow):
svn: File or directory 'array.c' is out of date; try updating
svn: resource out of date; try updating

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

[jerry@CentOS trunk]$ svn update
G    array.c
Updated to revision 3.

Subversion показывает букву G перед именем файла, что означает, что этот файл был объединен.

[jerry@CentOS trunk]$ svn diff

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

Index: array.c
===================================================================
--- array.c   (revision 3)
+++ array.c   (working copy)
@@ -2,6 +2,24 @@
 
 #define MAX 16
 
+void accept_input(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      scanf("%d", &arr[i]);
+}
+
+void display(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      printf("|%d| ", arr[i]);
+   
+   printf("n");
+}

+
 int main(void)
 {
    int i, n, arr[MAX];
@@ -15,15 +33,10 @@
    }
 
    printf("Enter the elementsn");
+   accept_input(arr, n);
 
-   for (i = 0; i < n; ++i)
-      scanf("%d", &arr[i]);
-
    printf("Array has following elementsn");
-   for (i = 0; i < n; ++i)
-      printf("|%d| ", arr[i]);
-   
-   printf("n");
+   display(arr, n);
 
    return 0;
 }

Subversion показывает только изменения Джерри , но файл array.c объединен. Если вы внимательно наблюдаете, Subversion теперь показывает номер редакции 3. В предыдущем выводе он показывал номер редакции 2. Просто посмотрите, кто внес изменения в файл и для какой цели.

jerry@CentOS trunk]$ svn log
------------------------------------------------------------------------
r3 | tom   | 2013-08-18 20:21:50 +0530 (Sun, 18 Aug 2013)   | 1 line

Fix array overflow problem
------------------------------------------------------------------------
r2 | jerry | 2013-08-17 20:40:43 +0530 (Sat, 17 Aug 2013) | 1 line

Initial commit
------------------------------------------------------------------------
r1 | jerry | 2013-08-04 23:43:08 +0530 (Sun, 04 Aug 2013) | 1 line

Create trunk, branches, tags directory structure
------------------------------------------------------------------------

Теперь рабочая копия Джерри синхронизирована с хранилищем, и он может безопасно зафиксировать свои изменения.

[jerry@CentOS trunk]$ svn commit -m "Add function to accept input and to display array contents"
Sending        trunk/array.c
Transmitting file data .
Committed revision 4.

SVN исправить ошибки

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

[jerry@CentOS trunk]$ svn status

Выше команда даст следующий результат.

M       array.c

Попробуем сделать массив следующим образом:

[jerry@CentOS trunk]$ make array

Выше команда даст следующий результат.

cc     array.c   -o array
array.c: In function ‘main’:
array.c:26: error: ‘n’ undeclared (first use in this function)
array.c:26: error: (Each undeclared identifier is reported only once
array.c:26: error: for each function it appears in.)
array.c:34: error: ‘arr’ undeclared (first use in this function)
make: *** [array] Error 1

Джерри выполняет операцию возврата к файлу array.c .

[jerry@CentOS trunk]$ svn revert array.c 
Reverted 'array.c'

[jerry@CentOS trunk]$ svn status
[jerry@CentOS trunk]$

Теперь скомпилируйте код.

[jerry@CentOS trunk]$ make array
cc     array.c   -o array

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

[jerry@CentOS project_repo]$ pwd
/home/jerry/project_repo

[jerry@CentOS project_repo]$ svn revert -R trunk

До сих пор мы видели, как отменить изменения, внесенные в рабочую копию. Но что, если вы хотите отменить исправленную ревизию! Инструмент Системы контроля версий не позволяет удалять историю из хранилища. Мы можем только добавить историю. Это произойдет, даже если вы удалите файлы из хранилища. Чтобы отменить старую ревизию, мы должны отменить все изменения, внесенные в старую ревизию, и затем зафиксировать новую ревизию. Это называется обратным слиянием.

Допустим, Джерри добавляет код для операции линейного поиска. После проверки он фиксирует свои изменения.

[jerry@CentOS trunk]$ svn diff
Index: array.c
===================================================================
--- array.c   (revision 21)
+++ array.c   (working copy)
@@ -2,6 +2,16 @@
 
 #define MAX 16
 
+int linear_search(int *arr, int n, int key)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      if (arr[i] == key)
+         return i;
+   return -1;
+}
+
 void bubble_sort(int *arr, int n)
 {
    int i, j, temp, flag = 1;

[jerry@CentOS trunk]$ svn status
?       array
M       array.c

[jerry@CentOS trunk]$ svn commit -m "Added code for linear search"
Sending        trunk/array.c
Transmitting file data .
Committed revision 22.

Джерри любопытно, что делает Том. Поэтому он проверяет сообщения журнала Subversion.

[jerry@CentOS trunk]$ svn log

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

------------------------------------------------------------------------
r5 | tom   | 2013-08-24 17:15:28 +0530 (Sat, 24 Aug 2013) | 1 line

Add binary search operation
------------------------------------------------------------------------
r4 | jerry | 2013-08-18 20:43:25 +0530 (Sun, 18 Aug 2013) | 1 line

Add function to accept input and to display array contents

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

[jerry@CentOS trunk]$ svn up 
At revision 22.

[jerry@CentOS trunk]$ svn merge -r 22:21 array.c 
--- Reverse-merging r22 into 'array.c':
U    array.c

[jerry@CentOS trunk]$ svn commit -m "Reverted to revision 21"
Sending        trunk/array.c
Transmitting file data .
Committed revision 23.

Том решает добавить файл README для своего проекта. Поэтому он создает файл README и добавляет в него список TODO. После добавления этого файла хранилище находится в редакции 6.

[tom@CentOS trunk]$ cat README 
/* TODO: Add contents in README file */

[tom@CentOS trunk]$ svn status
?       README

[tom@CentOS trunk]$ svn add README 
A         README

[tom@CentOS trunk]$ svn commit -m "Added README file. Will update it's content in future."
Adding         trunk/README
Transmitting file data .
Committed revision 6. 

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

[tom@CentOS trunk]$ cat README 
* Supported operations:

1) Accept input
2) Display array elements

[tom@CentOS trunk]$ svn status
M       README

[tom@CentOS trunk]$ svn commit -m "Added supported operation in README"
Sending        trunk/README
Transmitting file data .
Committed revision 7.

Сейчас хранилище находится на 7-й редакции, а рабочая копия Джерри устарела. Джерри также обновляет файл README и пытается зафиксировать свои изменения.

Файл README Джерри выглядит следующим образом.

[jerry@CentOS trunk]$ cat README 
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.

[jerry@CentOS trunk]$ svn status
M       README

[jerry@CentOS trunk]$ svn commit -m "Updated README"
Sending        trunk/README
svn: Commit failed (details follow):
svn: File or directory 'README' is out of date; try updating
svn: resource out of date; try updating

Шаг 1: Просмотр конфликтов

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

[jerry@CentOS trunk]$ svn up
Conflict discovered in 'README'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

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

[jerry@CentOS trunk]$ svn up
Conflict discovered in 'README'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: df
--- .svn/text-base/README.svn-base	Sat Aug 24 18:07:13 2013
+++ .svn/tmp/README.tmp	Sat Aug 24 18:13:03 2013
@@ -1 +1,11 @@
-/* TODO: Add contents in README file */
+<<<<<<< .mine
+* File list
+
+1) array.c	Implementation of array operation.
+2) README	Instructions for user.
+=======
+* Supported operations:
+
+1) Accept input
+2) Display array elements
+>>>>>>> .r7
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

Шаг 2: отложить конфликты

Далее Джерри выбирает параметры отсрочки (p) , чтобы он мог разрешить конфликт.

Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: p
C    README
Updated to revision 7.
Summary of conflicts:
  Text conflicts: 1

После открытия README в текстовом редакторе он понимает, что Subversion включил и код Тома, и его код с маркерами конфликта.

[jerry@CentOS trunk]$ cat README
<<<<<<< .min
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.
=======
* Supported operations:

1) Accept input
2) Display array elements
>>>>>>> .r7

Джерри хочет изменений Тома так же, как и его, поэтому он просто удаляет строки, содержащие маркеры конфликта.

Итак, модифицированный файл README будет выглядеть следующим образом.

[jerry@CentOS trunk]$ cat README
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.

* Supported operations:

1) Accept input
2) Display array elements

Джерри разрешил конфликт и он повторил коммит.

[jerry@CentOS trunk]$ svn commit -m "Updated README"
svn: Commit failed (details follow):
svn: Aborting commit: '/home/jerry/project_repo/trunk/README' remains in conflict
 
[jerry@CentOS trunk]$ svn status
?       README.r6
?       README.r7
?       README.mine
C       README

Шаг 3: Разрешить конфликты

В приведенном выше коммите буква C указывает на наличие конфликта в файле README. Джерри разрешил конфликт, но не сказал Subversion, что он разрешил конфликт. Он использует команду разрешения, чтобы сообщить Subversion о разрешении конфликта.

[jerry@CentOS trunk]$ svn resolve --accept=working README
Resolved conflicted state of 'README'

[jerry@CentOS trunk]$ svn status
M       README

[jerry@CentOS trunk]$ svn commit -m "Updated README"
Sending        trunk/README
Transmitting file data .
Committed revision 8.

Теги SVN

Система контроля версий поддерживает работу с тегами , используя такую ​​концепцию, что можно дать осмысленное имя конкретной версии кода. Тэг позволяет дать описательные и запоминающиеся имена для конкретной версии кода. Например, BASIC_ARRAY_OPERATIONS более запоминающимся, чем редакция 4 .

Давайте посмотрим на работу тега с примером. Том решает создать тег, чтобы ему было легче получать доступ к коду.

[tom@CentOS project_repo]$ svn copy --revision=4 trunk/ tags/basic_array_operations

Выше команда даст следующий результат.

A    tags/basic_array_operations/array.c
Updated to revision 4.
A         tags/basic_array_operations

После успешного завершения новый каталог будет создан внутри каталога тегов .

[tom@CentOS project_repo]$ ls -l tags/
total 4
drwxrwxr-x. 3 tom tom 4096 Aug 24 18:18 basic_array_operations

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

[tom@CentOS project_repo]$ svn status
A  +    tags/basic_array_operations

[tom@CentOS project_repo]$ svn commit -m "Created tag for basic array operations"
Adding         tags/basic_array_operations

Committed revision 5.

SVN Ветвление

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

В этом разделе мы увидим, как создавать, обходить и объединять ветки. Джерри не счастлив из-за конфликта, поэтому он решает создать новую частную ветвь.

[jerry@CentOS project_repo]$ ls
branches  tags  trunk

[jerry@CentOS project_repo]$ svn copy trunk branches/jerry_branch
A         branches/jerry_branch

[jerry@CentOS project_repo]$ svn status
A  +    branches/jerry_branch

[jerry@CentOS project_repo]$ svn commit -m "Jerry's private branch"
Adding         branches/jerry_branch
Adding         branches/jerry_branch/README

Committed revision 9.
[jerry@CentOS project_repo]$ 

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

[jerry@CentOS project_repo]$ cd branches/jerry_branch/

[jerry@CentOS jerry_branch]$ cat array.c 

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

#include <stdio.h>
#define MAX 16

void bubble_sort(int *arr, int n)
{
   int i, j, temp, flag = 1;
   for (i = 1; i < n && flag == 1; ++i) {
      flag = 0;
      for (j = 0; j < n - i; ++j) {
         if (arr[j] > arr[j + 1]) {
            flag = 1;
            temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
         }
      }
   }
}

void accept_input(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i) 
   scanf("%d", &arr[i]);
}

void display(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i)
   printf("|%d| ", arr[i]);

   printf("n");
}

int main(void)
{
   int i, n, key, ret, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* Error handling for array overflow */
   if (n >MAX) {
      fprintf(stderr, "Number of elements must be less than %dn", MAX);
      return 1;
   }

   printf("Enter the elementsn");
   accept_input(arr, n);

   printf("Array has following elementsn");
   display(arr, n);

   printf("Sorted data isn");
   bubble_sort(arr, n);
   display(arr, n);

   return 0;
}

Джерри компилирует и тестирует свой код и готов принять его изменения.

[jerry@CentOS jerry_branch]$ make array
cc     array.c   -o array

[jerry@CentOS jerry_branch]$ ./array 

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

Enter the total number of elements: 5
Enter the elements
10
-4
2
7 
9
Array has following elements
|10| |-4| |2| |7| |9| 
Sorted data is
|-4| |2| |7| |9| |10| 

[jerry@CentOS jerry_branch]$ svn status
?       array
M       array.c

[jerry@CentOS jerry_branch]$ svn commit -m "Added sort operation"
Sending        jerry_branch/array.c
Transmitting file data .
Committed revision 10.

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

[tom@CentOS trunk]$ svn diff

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

Index: array.c
===================================================================
--- array.c   (revision 10)
+++ array.c   (working copy)
@@ -2,6 +2,27 @@
 
 #define MAX 16
 
+int bin_search(int *arr, int n, int key)
+{
+   int low, high, mid;
+
+   low   = 0;
+   high   = n - 1;
+   mid   = low + (high - low) / 2;
+
+   while (low <= high) {
+      if (arr[mid] == key)
+         return mid;
+      if (arr[mid] > key)
+         high = mid - 1;
+      else
+         low = mid + 1;
+      mid = low + (high - low) / 2;
+   }
+
+   return -1;
+}
+
 void accept_input(int *arr, int n)
 {
    int i;
@@ -22,7 +43,7 @@
 
 int main(void)
 {
-   int i, n, arr[MAX];
+   int i, n, ret, key, arr[MAX];
 
    printf("Enter the total number of elements: ");
    scanf("%d", &n);
@@ -39,5 +60,16 @@
    printf("Array has following elementsn");
    display(arr, n);
 
+   printf("Enter the element to be searched: ");
+   scanf("%d", &key);
+
+   ret = bin_search(arr, n, key);
+   if (ret < 0) {
+      fprintf(stderr, "%d element not present in arrayn", key);
+      return 1;
+   }
+
+   printf("%d element found at location %dn", key, ret + 1);
+
    return 0;
 }

После проверки он фиксирует свои изменения.

[tom@CentOS trunk]$ svn status
?       array
M       array.c

[tom@CentOS trunk]$ svn commit -m "Added search operation"
Sending        trunk/array.c
Transmitting file data .
Committed revision 11.

Но Тому любопытно, что Джерри делал в своей частной ветке.

[tom@CentOS trunk]$ cd ../branches/
[tom@CentOS branches]$ svn up
A    jerry_branch
A    jerry_branch/array.c
A    jerry_branch/README

[tom@CentOS branches]$ svn log
------------------------------------------------------------------------
r9 | jerry | 2013-08-27 21:56:51 +0530 (Tue, 27 Aug 2013) | 1 line

Added sort operation
------------------------------------------------------------------------

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

[tom@CentOS trunk]$ pwd
/home/tom/project_repo/trunk

[tom@CentOS trunk]$ svn merge ../branches/jerry_branch/
--- Merging r9 through r11 into '.':
U    array.c

После слияния массив array.c будет выглядеть следующим образом.

[tom@CentOS trunk]$ cat array.c

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

#include <stdio.h>
#define MAX 16

void bubble_sort(int *arr, int n)
{
   int i, j, temp, flag = 1;

   for (i = 1; i < n && flag == 1; ++i) {
      flag = 0;
      for (j = 0; j < n - i; ++j) {
         if (arr[j] > arr[j + 1]) {
            flag      	= 1;
            temp      	= arr[j];
            arr[j]      = arr[j + 1];
            arr[j + 1]	= temp;
         }
      }
   }
}

int bin_search(int *arr, int n, int key)
{
   int low, high, mid;

   low   = 0;
   high  = n - 1;
   mid   = low + (high - low) / 2;

   while (low <= high) {
      if (arr[mid] == key)
         return mid;
      if (arr[mid] > key)
         high = mid - 1;
      else
         low = mid + 1;
      mid = low + (high - low) / 2;
   }
   return -1;
}

void accept_input(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i)
      scanf("%d", &arr[i]);
}

void display(int *arr, int n)
{
   int i;
   for (i = 0; i < n; ++i)
      printf("|%d| ", arr[i]);
   printf("n");
}

int main(void)
{
   int i, n, ret, key, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* Error handling for array overflow */
   if (n > MAX) {
      fprintf(stderr, "Number of elements must be less than %dn", MAX);
      return 1;
   }

   printf("Enter the elementsn");
   accept_input(arr, n);

   printf("Array has following elementsn");
   display(arr, n);

   printf("Sorted data isn");
   bubble_sort(arr, n);
   display(arr, n);

   printf("Enter the element to be searched: ");
   scanf("%d", &key);

   ret = bin_search(arr, n, key);
   if (ret < 0) {
      fprintf(stderr, "%d element not present in arrayn", key);
      return 1;
   }

   printf("%d element found at location %dn", key, ret + 1);

   return 0;
}

После компиляции и тестирования Том фиксирует свои изменения в хранилище.

We’ve mentioned already that Subversion is a modern,
network-aware version control system. As we described in
the section called “Version Control Basics” (our
high-level version control overview), a repository serves as the
core storage mechanism for Subversion’s versioned data, and it’s
via working copies that users and their software programs
interact with that data. In this section, we’ll begin to
introduce the specific ways in which Subversion implements
version control.

Subversion Repositories

Subversion implements the concept of a version control
repository much as any other modern version control system
would. Unlike a working copy, a Subversion repository is an
abstract entity, able to be operated upon almost exclusively
by Subversion’s own libraries and tools. As most of a user’s
Subversion interactions involve the use of the Subversion
client and occur in the context of a working copy, we spend
the majority of this book discussing the Subversion working
copy and how to manipulate it. For the finer details of the
repository, though, check out
Chapter 5, Repository Administration.

In Subversion, the client-side object which every user
of the system has—the directory of versioned files,
along with metadata that enables the system to track them
and communicate with the server—is called
a working copy. Although other version
control systems use the term repository for
the client-side object, it is both incorrect and a common
source of confusion to use the term in that way in the
context of Subversion.

Working copies are described later, in
the section called “Subversion Working Copies”.

Revisions

A Subversion client commits (that is, communicates the
changes made to) any number of files and directories as a
single atomic transaction. By atomic transaction, we mean
simply this: either all of the changes are accepted into the
repository, or none of them is. Subversion tries to retain
this atomicity in the face of program crashes, system crashes,
network problems, and other users’ actions.

Each time the repository accepts a commit, this
creates a new state of the filesystem tree, called a
revision. Each revision is assigned a
unique natural number, one greater than the number assigned to
the previous revision. The initial revision of a freshly
created repository is numbered 0 and consists of nothing but
an empty root directory.

Figure 1.6, “Tree changes over time”
illustrates a nice way to visualize the repository. Imagine
an array of revision numbers, starting at 0, stretching from
left to right. Each revision number has a filesystem tree
hanging below it, and each tree is a snapshot
of the way the repository looked after a commit.

Figure 1.6. Tree changes over time

Tree changes over time

Addressing the Repository

Subversion client programs use URLs to identify
versioned files and directories in Subversion repositories.
For the most part, these URLs use the standard syntax,
allowing for server names and port numbers to be specified as
part of the URL.

  • http://svn.example.com/svn/project
  • http://svn.example.com:9834/repos

Subversion repository URLs aren’t limited to only
the http:// variety. Because Subversion
offers several different ways for its clients to communicate
with its servers, the URLs used to address the repository
differ subtly depending on which repository access mechanism
is employed. Table 1.1, “Repository access URLs”
describes how different URL schemes map to the available
repository access methods. For more details about
Subversion’s server options, see
Chapter 6, Server Configuration.

Table 1.1. Repository access URLs

Schema Access method
file:/// Direct repository access (on local disk)
http:// Access via WebDAV protocol to Subversion-aware
Apache server
https:// Same as http://, but with
SSL encapsulation (encryption and authentication)
svn:// Access via custom protocol to an
svnserve server
svn+ssh:// Same as svn://, but through
an SSH tunnel

Subversion’s handling of URLs has some noteworthy nuances.
For example, URLs containing the file://
access method (used for local repositories) must, in
accordance with convention, have either a server name
of localhost or no server name at
all:

  • file:///var/svn/repos
  • file://localhost/var/svn/repos

Also, users of the file:// scheme on
Windows platforms will need to use an unofficially
standard syntax for accessing repositories
that are on the same machine, but on a different drive than
the client’s current working drive. Either of the two
following URL path syntaxes will work, where
X is the drive on which the repository
resides:

  • file:///X:/var/svn/repos
  • file:///X|/var/svn/repos

Note that a URL uses forward slashes even though the
native (non-URL) form of a path on Windows uses backslashes.
Also note that when using
the file:///X|/
form at the command line, you need to quote the URL (wrap it
in quotation marks) so that the vertical bar character is not
interpreted as a pipe.

You cannot use Subversion’s file:// URLs
in a regular web browser the way you can use typical
file:// URLs. 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 the section called “Repository Layer”), and your browser
will not understand how to interact with that
filesystem.

The Subversion client will automatically encode URLs as
necessary, just like a web browser does. For example, the URL
http://host/path with space/project/españa
— which contains both spaces and upper-ASCII characters
— will be automatically interpreted by Subversion as if
you’d provided
http://host/path%20with%20space/project/espa%C3%B1a.
If the URL contains spaces, be sure to place it within
quotation marks at the command line so that your shell treats
the whole thing as a single argument to the program.

There is one notable exception to Subversion’s handling of
URLs which also applies to its handling of local paths in many
contexts, too. If the final path component of your URL or
local path contains an at sign (@), you need
to use a special syntax—described in
the section called “Peg and Operative Revisions”—in order to make
Subversion properly address that resource.

In Subversion 1.6, a new caret (^)
notation was introduced as a shorthand for the URL of
the repository’s root directory
. For example, you can
use the ^/tags/bigsandwich/ to refer to the
URL of the /tags/bigsandwich directory in
the root of the repository. Such a URL is called a
repository-relative URL. Note
that this URL syntax works only when your current working
directory is a working copy—the command-line client
knows the repository’s root URL by looking at the working
copy’s metadata. Also note that when you wish to refer
precisely to the root directory of the repository, you must do
so using ^/ (with the trailing slash
character), not merely
^. Windows users should not forget that
a caret is an escape character on their platform. Therefore,
use a double caret ^^ if you run the
Subversion client on a Windows machine.

Subversion Working Copies

A Subversion working copy is an ordinary directory
tree on your local system, containing a collection of files.
You can edit these files however you wish, and if they’re
source code files, you can compile your program from them in
the usual way. Your working copy is your own private work
area: Subversion will never incorporate other people’s
changes, nor make your own changes available to others, until
you explicitly tell it to do so. You can even have multiple
working copies of the same project.

After you’ve made some changes to the files in your
working copy and verified that they work properly, Subversion
provides you with commands to publish your
changes (by writing to the repository), thereby making them
available to the other people working with you on your
project. If other people publish their own changes,
Subversion provides you with commands to merge those changes
into your own working copy (by reading from the repository).
Notice that the central repository is the broker for
everybody’s changes in Subversion—changes aren’t passed
directly from working copy to working copy in the typical
workflow.

A working copy also contains some extra files,
created and maintained by Subversion, to help it carry out
these commands. In particular, each working copy contains a
subdirectory named .svn, also known as
the working copy’s administrative
directory
. The files in the administrative
directory help Subversion recognize which of your versioned
files contain unpublished changes, and which files are out of
date with respect to others’ work.

Prior to version 1.7, Subversion
maintained .svn administrative
subdirectories in every versioned
directory of your working copy. Subversion 1.7 offers a
completely new approach to how working copy metadata is
stored and maintained, and chief among the visible changes
to this approach is that each working copy now has only
one .svn subdirectory which is an
immediate child of the root of that working copy.

How the working copy works

For each file in a working directory, Subversion records
(among other things) two essential pieces of information:

  • What revision your working file is based on (this is
    called the file’s working
    revision
    )

  • A timestamp recording when the local copy was last
    updated by the repository

Given this information, by talking to the repository,
Subversion can tell which of the following four states a
working file is in:

Unchanged, and current

The file is unchanged in the working directory, and
no changes to that file have been committed to the
repository since its working revision. An svn
commit
of the file will do nothing, and an
svn update of the file will do
nothing.

Locally changed, and current

The file has been changed in the working directory,
and no changes to that file have been committed to the
repository since you last updated. There are local
changes that have not been committed to the repository;
thus an svn commit of the file will
succeed in publishing your changes, and an svn
update
of the file will do nothing.

Unchanged, and out of date

The file has not been changed in the working
directory, but it has been changed in the repository.
The file should eventually be updated in order to make
it current with the latest public revision.
An svn commit of the file will do
nothing, and an
svn update of the file will fold the
latest changes into your working copy.

Locally changed, and out of date

The file has been changed both in the working
directory and in the repository. An svn
commit
of the file will fail with an
out-of-date error. The file should be
updated first; an svn update command
will attempt to merge the public changes with the local
changes. If Subversion can’t complete the merge in a
plausible way automatically, it leaves it to the user to
resolve the conflict.

Fundamental working copy interactions

A typical Subversion repository often holds the files (or
source code) for several projects; usually, each project is a
subdirectory in the repository’s filesystem tree. In this
arrangement, a user’s working copy will usually correspond to
a particular subtree of the repository.

For example, suppose you have a repository that contains
two software projects, paint and
calc. Each project lives in its own
top-level subdirectory, as shown in Figure 1.7, “The repository’s filesystem”.

Figure 1.7. The repository’s filesystem

The repository's filesystem

To get a working copy, you must check
out
some subtree of the repository. (The term
check out may sound like it has something to do
with locking or reserving resources, but it doesn’t; it simply
creates a working copy of the project for you.) For example,
if you check out /calc, you will get a
working copy like this:

$ 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  button.c integer.c .svn/
$

The list of letter As in the left
margin indicates that Subversion is adding a number of items
to your working copy. You now have a personal copy of the
repository’s /calc directory, with one
additional entry—.svn—which
holds the extra information needed by Subversion, as mentioned
earlier.

Suppose you make changes
to button.c. Since
the .svn directory remembers the file’s
original modification date and contents, Subversion can tell
that you’ve changed the file. However, Subversion does not
make your changes public until you explicitly tell it to.
The act of publishing your changes is more commonly known as
committing (or checking
in
) changes to the repository.

To publish your changes, you can use
Subversion’s svn commit command:

$ svn commit button.c -m "Fixed a typo in button.c."
Sending        button.c
Transmitting file data .
Committed revision 57.
$

Now your changes to button.c have
been committed to the repository, with a note describing your
change (namely, that you fixed a typo). If another user
checks out a working copy of /calc, she
will see your changes in the latest version of the
file.

Suppose you have a collaborator, Sally, who checked out a
working copy of /calc at the same time
you did. When you commit your change to
button.c, Sally’s working copy is left
unchanged; Subversion modifies working copies only at the
user’s request.

To bring her project up to date, Sally can ask
Subversion to update her working
copy, by using the svn update command.
This will incorporate your changes into her working copy, as
well as any others that have been committed since she
checked it out.

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

The output from the svn update command
indicates that Subversion updated the contents of
button.c. Note that Sally didn’t need to
specify which files to update; Subversion uses the information
in the .svn directory as well as further
information in the repository, to decide which files need to
be brought up to date.

Mixed-revision working copies

As a general principle, Subversion tries to be
as flexible as possible. One special kind of flexibility is
the ability to have a working copy containing files and
directories with a mix of different working revision
numbers. Subversion working copies do not always correspond
to any single revision in the repository; they may contain
files from several different revisions. For example,
suppose you check out a working copy from a repository whose
most recent revision is 4:

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

At the moment, this working directory corresponds exactly
to revision 4 in the repository. However, suppose you make a
change to button.c, and commit that
change. Assuming no other commits have taken place, your
commit will create revision 5 of the repository, and your
working copy will now look like this:

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

Suppose that, at this point, Sally commits a change to
integer.c, creating revision 6. If you
use svn update to bring your working copy
up to date, it will look like this:

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

Sally’s change to integer.c will
appear in your working copy, and your change will still be
present in button.c. In this example,
the text of Makefile is identical in
revisions 4, 5, and 6, but Subversion will mark your working
copy of Makefile with revision 6 to
indicate that it is still current. So, after you do a clean
update at the top of your working copy, it will generally
correspond to exactly one revision in the repository.

Updates and commits are separate

One of the fundamental rules of Subversion is that
a push action does not cause
a pull nor vice versa. Just
because you’re ready to submit new changes to the repository
doesn’t mean you’re ready to receive changes that others
have checked in. And if you have new changes still in progress,
svn update should gracefully merge
repository changes into your own, rather than forcing you to
publish them.

The main side effect of this rule is that it means a
working copy has to do extra bookkeeping to track mixed
revisions as well as be tolerant of the mixture. It’s made
more complicated by the fact that directories themselves are
versioned.

For example, suppose you have a working copy entirely
at revision 10, while others have been committing their
changes so that the youngest revision in the repository is
now revision 14. You edit the file
foo.html and then perform
an svn commit, which creates revision
15 in the repository. After the commit succeeds, many new
users would expect the working copy to be entirely at
revision 15, but that’s not the case! Any number of
changes might have happened in the repository between
revisions 10 and 15. The client knows nothing of those
changes in the repository, since you haven’t yet
run svn update, and svn
commit
doesn’t pull down new changes. If, on
the other hand, svn commit were to
automatically download the newest changes, it would be
possible to set the entire working copy to revision
15—but then we’d be breaking the fundamental rule
of push and pull remaining
separate actions. Therefore, the only safe thing the
Subversion client can do is mark the one
file—foo.html—as being at
revision 15. The rest of the working copy remains at
revision 10. Only by running svn
update
can the latest changes be downloaded and
the whole working copy be marked as revision 15.

Mixed revisions are normal

The fact is, every time you run
svn commit your working copy ends up
with some mixture of revisions. The things you just
committed are marked as having larger working revisions than
everything else. After several commits (with no updates
in between), your working copy will contain a whole mixture
of revisions. Even if you’re the only person using the
repository, you will still see this phenomenon. To examine
your mixture of working revisions, use the svn
status
command with the --verbose
(-v) option (see
the section called “See an overview of your changes” for more
information).

Often, new users are completely unaware that their
working copy contains mixed revisions. This can be
confusing, because many client commands are sensitive to the
working revision of the item they’re examining. For
example, the svn log command is used to
display the history of changes to a file or directory (see
the section called “Generating a List of Historical Changes”). When the user
invokes this command on a working copy object, he expects
to see the entire history of the object. But if the
object’s working revision is quite old (often because
svn update hasn’t been run in a long
time), the history of the older
version of the object is shown.

Mixed revisions are useful

If your project is sufficiently complex, you’ll
discover that it’s sometimes nice to
forcibly backdate (or update to a
revision older than the one you already have) portions of
your working copy to an earlier revision; you’ll learn how
to do that in Chapter 2, Basic Usage. Perhaps you’d
like to test an earlier version of a submodule contained
in a subdirectory, or perhaps you’d like to figure out
when a bug first came into existence in a specific file.
This is the time machine aspect of a
version control system—the feature that allows you
to move any portion of your working copy forward and
backward in history.

Mixed revisions have limitations

However you make use of mixed revisions in your working
copy, there are limitations to this flexibility.

First, you cannot commit the deletion of a file or
directory that isn’t fully up to date. If a newer version
of the item exists in the repository, your attempt to delete
will be rejected to prevent you from accidentally
destroying changes you’ve not yet seen.

Second, you cannot commit a metadata change to a
directory unless it’s fully up to date. You’ll learn about
attaching properties to items in Chapter 3, Advanced Topics. A directory’s working revision
defines a specific set of entries and properties, and thus
committing a property change to an out-of-date directory may
destroy properties you’ve not yet seen.

Finally, beginning in Subversion 1.7, you cannot by
default use a mixed-revision working copy as the target of
a merge operation. (This new requirement was introduced
to prevent common problems which stem from doing so.)

Apache Subversion (SVN) is a universal and centralized open source
version control system. Subversion is currently a project under Apache Software Foundation (ASF) and is licensed under the Apache License, Version 2.0.

Subversion is designed to manage and control files and directories and track changes made to them; it acts as a reliable time machine and management tool for the collaboratively developed projects. It can easily answer the standard questions any version control system has to answer reliably. For example,

  • How did the project/file FOO look like on 12/12/2012 ?
  • What changes were introduced by USERNAME or on 20/12/2012 ?
  • Who modified the particular string since the last review?
  • and much-much more.

Versions

Version What’s new? Release Date
1.9.x Numerous usability and performance improvements 2015-08-05
1.8.x Improved rename tracking, automatic reintegration merges, inherited versioned properties, built-in conflict resolution tool 2013-06-18
1.7.x Complete rewrite of the working copy library, improved HTTP protocol usage 2011-10-11
1.6.x Identifying tree conflicts, improved interactive conflict resolution, repo-relative URLs support 2009-03-20
1.5.x Merge and branch tracking (svn:mergeinfo), interactive file conflict resolution, sparse checkouts, improved svn:externals syntax 2008-06-19
1.4.x svnsync tool for repository replication, new and improved working copy library 2006-09-10
1.3.x High-level logging of user operations on the server side, performance improvements 2005-12-30
1.2.x Support for lock-modify-unlock model (i.e. locking), DAV autoversioning, FSFS is used by default for new repositories 2005-05-21
1.1.x New repository backend (FSFS), symlink versioning 2004-09-29
1.0.x Initial public release 2004-02-23

Apache Subversion 1.9.x is currently the latest and best SVN release
that is fully supported. Subversion 1.8.x is partially supported.
Subversion 1.7.x and earlier versions are no longer supported.

Installation and initial setup

Install the svn client to start collaborating on the project that is using Subversion as its version control system.

To install Subversion, you can build it yourself from a source code release or download a binary package pre-built for your operating system. The list of sites where you can obtain a compiled Subversion client (svn ) for various operating systems is available at the official binary packages page. If you feel like compiling the software for yourself, grab the source at the Source Code page.

With Subversion, you are not limited to using only the standard svn command-line client. There are some notable graphical Subversion clients for various operating systems and most of the IDEs nowadays provide robust integration with SVN right out of the box or via plugins. For the list of graphical clients, check the Wikipedia page: https://en.wikipedia.org/wiki/Comparison_of_Subversion_clients.

Right after you install the client you should be able to run it by issuing the command svn . You should see the following:

$ svn
Type 'svn help' for usage.
 

Everything is mostly ready. Now you should create a local workspace called a working copy which is going to be connected to the remote central repository. In other words, you are going to checkout a working copy. You are going to operate with the versioned data with the help of the working copy and can publish your changes (called committing in SVN) so that others working on the same project can see them and benefit from your changes. To later fetch the future changes made by others from the repository, you would update your working copy. These basic operations are covered in other examples.

Checking out a working copy

To begin making modifications to the project’s data, you have to obtain a local copy of the versioned project. Use the command line svn client or your favorite SVN client (TortoiseSVN, for example). Your local copy of the project is called a working copy in Subversion and you get it by issuing the command svn checkout <URL> where <URL> is a repository URL. e.g.

$ svn checkout https://svn.example.com/svn/MyRepo/MyProject/trunk
 

Alternatively, you can use svn co <URL> as a shorthand in order to checkout a local copy.

As a result, you will get a working copy of the /trunk of a project called MyProject that resides in MyRepo repository. The working copy will be located in a directory called trunk on your computer relative to the directory you issued the command in.

If you wish to have a different name for your working copy you can add that as a parameter to the end of the command. e.g.

$ svn checkout https://svn.example.com/svn/MyRepo/MyProject/trunk MyProjectSource
 

This will create a working copy called MyProjectSource .

Note that instead of checking out the trunk, you could check out some branch, private shelve or a tag (assuming they already exist in the repository); you can have unlimited number of local working copies on your machine.

You could get the working copy of the whole repository MyRepo, too. But you should refrain from doing so. Generally speaking, you do not need to have a working copy of the whole repository for your work because your working copy can be instantly switched to another development branch / tag / whatever. Moreover, Subversion repository can contain a number of (un)related projects and it’s better to have a dedicated working copy for each of them, not a single working copy for all of the projects.

Checking out a working copy at a specific revision

To get version 5394 use:

svn co --revision r5394 https://svn.example.com/svn/MyRepo/MyProject/trunk
 

Or the shorter version:

svn co -r 5394 https://svn.example.com/svn/MyRepo/MyProject/trunk
 

Or by using pegged revisions:

svn co https://svn.example.com/svn/MyRepo/MyProject/trunk@5394
 

If already checked out, you can use the update command to move a to a particular revision, by doing:

svn up -rXXX
 

Committing your local changes to the repository

To publish the changes you made in your working copy, run the svn commit command.

IMPORTANT: Review your changes before committing them! Use svn status and svn diff to review the changes. Also, make sure you are in the correct path before performing a commit. If you updated many files across various directories, you should be at the appropriate level to include all of them beneath your location.

Here is an example of the commit command:

svn commit -m "My Descriptive Log Message"
 

Alternatively, svn ci is the shorthand for svn commit

Note the -m (--message) option. Good commit messages help others understand why a commit was made. Also, on the server side it’s possible to enforce non-empty messages, and even enforce that each commit message mentions an existing ticket in your bug tracking system.

Creating and applying patches

A patch is a file that show the differences between two revisions or between your local repository and the last revision your repository is pointing.

To share or save a patch of your local uncommitted changes either for peer review or to apply later, do:

svn diff > new-feature.patch
 

To get a patch from the differences between two revisions:

svn diff -r NEWER_REVISION:OLDER_REVISION > feature.patch
 

To apply a patch, run:

svn patch new-feature.patch
 

In order to apply the patch successfully, you must run the command from the same path where the patch was created.

Exporting the versioned data (plain download)

If you want to get the versioned project’s data, but you don’t need any of the version control capabilities offered by Subversion, you could run svn export <URL> command. Here is an example:

$ svn export https://svn.example.com/svn/MyRepo/MyProject/trunk
 

As a result, you will get the project’s data export, but unlike with a working copy, you won’t be able to run svn commands on it. The export is just a plain download of the data.

If some time later you’d want to convert the downloaded data to a fully-functional working copy, run svn checkout <URL> to the directory where you ran the export to.

Making changes in your local working copy

The working copy (WC) is your local and private workspace that you use to interact with the central Subversion repository. You use the working copy to modify the contents of your project and fetch changes committed by others.

The working copy contains your project’s data and looks and acts like a regular directory on your local file system, but with one major difference — the working copy tracks the status and changes of files
and directories within. You can think of the working copy as of a regular directory with a version-control flavor added by a hidden .svn metadata directory at its root.

Most of the time, you are going to perform modifications to the project’s data by modifying the contents of the working copy. As soon as you are satisfied with the modifications and you’ve reviewed them thoroughly, you are ready to publish them to the central repository.

You can perform any actions with your project’s data within the working copy, but operations that involve copying, moving, renaming and deleting must be performed using the corresponding svn commands:

  • Modifying existing files. Modify the files as you usually do using your favorite text processor, graphics editor, audio editing software, IDE, etc. As soon as you save the changes to disk, Subversion will recognize them automatically.

  • Adding new files. Put new files to the working copy and Subversion will recognize them as unversioned. It will not automatically start tracking the new files unless you run svn add command:

    svn add foo.cs
     
  • Moving files and directories. Move files and directories using svn move command:

    svn move foo.cs bar.cs
     
  • Renaming files and directories. Rename files and directories using svn rename command:

    svn rename foo.cs bar.cs
     

    NOTE: svn rename command is an alias of svn move command.

  • Copying files and directories. Copy files and directories using svn copy command:

    svn copy foo.cs bar.cs
     
  • Deleting files and directories. Delete files and directories using svn delete command:

    svn delete foo.cs
     
  • Checking the status of files and directories in the working copy. Review your changes using svn status (or svn st for short) command:

    svn status
     

    IMPORTANT: Always review your changes before committing them. This will help you to avoid committing unnecessary or irrelevant changes.

  • Reverting changes. Revert your changes using svn revert command:

    svn revert foo.c
     
  • Reverting all changes: From the repository’s root:

    svn revert -R .
     

    IMPORTANT: Reverted uncommitted changes will be lost forever. You won’t be able to recover the reverted changes. Use svn revert with caution! If you want to keep the changes but need to revert, save them in a patch. See example of how to create and apply a patch.

Revert or rollback of a file

To restore a file to the latest updated svn version, i.e. undo the local changes, you can use revert :

svn revert file
 

To restore a file to an older version (revision XXX) use update :

svn update -r XXX file
 

Warning: in both cases you will lose any local changes in the file because it will be overwritten.


To only view the older version of a file use cat :

svn cat -r XXX file
 

And to view the differences with your local version of the file:

svn diff -r XXX file
 

Reviewing the logs

Running svn log will show you all the commit messages, you probably want to review only certain revisions.

  • View the n most recent revisions:

    svn log -n

  • View a specific revision:

    svn log -c rXXX

  • View the paths affected:

    svn log -v -c rXXX

Updating a working copy

You are not the only person working on the project, right? This means that your colleagues are also making modifications to the project’s data. To stay up to date and to fetch the modifications committed by others, you should run svn update command in your working copy. As a result, your working copy will sync with the repository and download the changes made by your colleagues.

Shorthand for svn update is svn up .

It is a rule to run svn update before committing your changes.

Using a password-protected repository

A Subversion repository can be configured so that certain contents or commands are only accessible to certain users. In order to access this restricted content, you will need to specify a username and password.

Your username and password can be specified directly as part of the command:

$ svn checkout https://svn.example.com/MyRepo/trunk --username JoeUser --password topsecret
 

Unfortunately, this causes your password to appear in plaintext on the console. To avoid this possible security problem, specify a username but not a password. Doing this will cause a password prompt to appear, allowing you to enter your password without exposing it:

$ svn checkout https://svn.example.com/MyRepo/trunk --username JoeUser
Password for 'JoeUser':
 

Providing no authentication information at all causes Subversion to prompt you for both the username and password:

$ svn checkout https://svn.example.com/MyRepo/trunk
Username:  JoeUser
Password for 'JoeUser':
 

While the first method is less secure, it’s frequently seen in automated scripts since it is difficult for many types of script to provide information to an interactive prompt.

Note: commands that only operate on your working copy (such as revert or status ) will never require a password, only commands that require communicating with the repository server.

по мотивам «Subversion in Action»

  • Начало работы
  • Основы
    • Рабочие копии
    • Ревизии
    • Как рабочие копии отслеживают репозиторий
    • Смешивание рабочих копий разных ревизий
  • Экскурсия по Subversion
    • Импорт
    • Ревизии: номера, ключевые слова и даты
  • Начальное получение рабочей копии
  • Простой рабочий цикл
    • Обновление рабочей копии
    • Внесение изменений
    • Проверка изменений
    • Разрешение конфликтов
    • Фиксация изменений
  • Итоги

Начало работы

Установка редактора

Основы

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

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

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

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

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

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

$ 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-репозитория всегда задается в виде URL.

Schema Способ доступа
file:/// доступ к репозиторию в файловой системе
http:// доступ по протоколу WebDAV к преднастроенному серверу Apache
https:// то же, что и http://, но с шифрованием SSL
svn:// доступ по внутреннему протоколу к серверу svnserve
svn+ssh:// то же, что и svn://, но через SSH-туннель

Публикация изменений обычно называется фиксацией (committing) и выполняется с помощью команды commit:

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

Для обновления локальной рабочей копии используется команда update:

$ svn update
U    button.c
Updated to revision 57.

Ревизии

Каждый коммит (commit) в репозитории рассматривается в виде атомарной транзакции — фиксируются либо все изменения, либо ни одного.

При приеме коммита в репозитории создается новое состояние дерева файловой системы, называемое ревизией (revision). Каждой ревизии присваивается уникальный возрастающий целочисленный номер. Начальная ревизия имеет номер 0 и соответствует пустому корневому каталогу.

The repository

Номера ревизий в Subversion относятся ко всему дереву, а не отдельному файлу.

Как рабочие копии отслеживают репозиторий

Для каждого файла Subversion поддерживает два основных свойства в административном каталоге .svn/:

  • базовая ревизия рабочего файла (рабочая ревизия);
  • отметка времени последнего обновления локальной копии из репозитория.

Используя эту информацию Subversion, при взаимодействии с репозиторием, определяет одно из 4-х состояний рабочего файла:

  • неизменен и актуален — файл не изменялся в рабочем каталоге, и репозиторий не содержит для него изменений после рабочей ревизии. svn commit и svn update выполнятся без внесения изменений.

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

  • неизменен и устарел — файл не изменялся в рабочем каталоге, но был изменен в репозитории. svn commit выполниться без внесения изменений, а svn update затянет (fold) последние изменения в рабочую копию.

  • изменен локально и устарел — файл был изменен как локально, так и в репозитории. svn commit завершится с ошибкой, т.к. файл должен быть сначала обновлен. svn update попытается совместить (merge) изменения в репозитории с локальными изменениями. Если автоматическое слияния невозможно, то разрешение конфликта выполняется пользователем.

Смешивание рабочих копий разных ревизий

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

Обновление и комиты разделены

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

Смешивание ревизий — это норма

Закоммиченные файлы будут иметь более поздний номер рабочей ревизии, чем все остальные. Для просмотра состояния рабочих ревизий можно воспользоваться командой svn status --verbose.

Смешивание ревизий — это полезно

Смешивание ревизий дает возможность переместить определенную часть рабочей копии в истории, позволяя исследовать более ранние изменения.

Смешивание ревизий имеет ограничения

  1. Невозможно зафиксировать (commit) удаление неактуального файла.
  2. Невозможно зафиксировать изменения метаданных неактуального каталога. Рабочая ревизия каталога имеет определенный набор свойств, и фиксация изменений свойств неактуального каталога может привести к утрате свойств, неизвестных рабочей копии.

Экскурсия по Subversion

Импорт

Для импортирования нового проекта в Subversion-репозиторий используется команда import:

$ svn import -m "New import" myproj 
            http://svn.red-bean.com/repos/trunk/misc/myproj
Adding         myproj/sample.txt
...
Transmitting file data .........
Committed revision 16.

Ревизии: номера, ключевые слова и даты

Для указания ревизии используется ключ --revision (-r):

Диапазон задается указанием номеров ревизий через двоеточие:

Номера ревизий

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

$ svn commit --message "Corrected number of cheese slices."
Sending        sandwich.txt
Transmitting file data .
Committed revision 3.

Ключевые слова ревизий

Для некоторых ревизий Subversion поддерживает ключевые слова (т.е. синонимы), которые можно использовать в качестве аргументов ключа --revision:

  • HEAD — последняя (самая молодая) ревизия в репозитории.

  • BASE — номер ревизии артефакта в рабочей копии. Если артефакт был локально изменен, ревизия BASE ссылается на версию без изменений.

  • COMMITTED — последняя ревизия меньшая или равная BASE, в которой артефакт был изменен.

  • PREV — ревизия предшествующая последней ревизии в которой артефакт был изменен (технически COMMITTED - 1).

Subversion хранит оригинальную (pristine) копию каждого файла в административном каталоге .svn. Номер ревизии оригинальной копии соответствует ключевому слову BASE.

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

Примеры использования:

$ svn diff --revision PREV:COMMITTED foo.c
# покажет последние закоммиченные изменения foo.c

$ svn log --revision HEAD
# покажет сообщение лога для последнего коммита в репозитории

$ svn diff --revision HEAD
# сравнит рабочий файл (с локальными изменениями)
# с последней версией в репозитории

$ svn diff --revision BASE:HEAD foo.c
# сравнит оригинальную (pristine) версию foo.c
# с последней версией в репозитории

$ svn log --revision BASE:HEAD
# покажет логи всех коммитов с момента последнего обновления

$ svn update --revision PREV foo.c
# откатит последнее изменение foo.c
# (рабочая версия foo.c уменьшится)

Даты ревизий

Ключ --revision, также, может принимать в качестве параметра дату. В этом случае Subversion найдет наиболее позднюю ревизию на заданную дату.

$ svn checkout --revision {2002-02-17}
$ svn checkout --revision {15:30}
$ svn checkout --revision {15:30:00.200000}
$ svn checkout --revision {"2002-02-17 15:30"}
$ svn checkout --revision {"2002-02-17 15:30 +0230"}
$ svn checkout --revision {2002-02-17T15:30}
$ svn checkout --revision {2002-02-17T15:30Z}
$ svn checkout --revision {2002-02-17T15:30-04:00}
$ svn checkout --revision {20020217T1530}
$ svn checkout --revision {20020217T1530Z}
$ svn checkout --revision {20020217T1530-0500}
$ svn log --revision {2002-11-28}
------------------------------------------------------------------------
r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines
...

При указании только даты, например 2002-11-27, Subversion дополнит ее временем 00:00:00.

Поиск в диапазоне дат выполняется следующим образом:

$ svn log --revision {2002-11-20}:{2002-11-29}
...

Начальное получение рабочей копии

Извлечение (checkout) репозитория создает его рабочую копию на локальной машине. Созданная рабочая копия соответствует HEAD-ревизии удаленного репозитория.

$ svn checkout http://svn.collab.net/repos/svn/trunk
A  trunk/subversion.dsw
A  trunk/svn_check.dsp
A  trunk/COMMITTERS
A  trunk/configure.in
A  trunk/IDEAS
...
Checked out revision 2499.

Каталог для рабочей копии задается следующим образом:

$ svn checkout http://svn.collab.net/repos/svn/trunk subv
A  subv/subversion.dsw
A  subv/svn_check.dsp
A  subv/COMMITTERS
A  subv/configure.in
A  subv/IDEAS
...
Checked out revision 2499.

В этом случае рабочая копия будет располагаться в каталоге subv вместо trunk.

Простой рабочий цикл

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

  1. Обновление рабочей копии
    • svn update
  2. Внесение изменений
    • svn add
    • svn delete
    • svn copy
    • svn move
  3. Проверка изменений
    • svn status
    • svn diff
    • svn revert
  4. Слияние опубликованных изменений с локальной рабочей копией
    • svn update
    • svn resolved
  5. Фиксация изменений
    • svn commit

Обновление рабочей копии

Обновление рабочей копии до состояния последней ревизии в репозитории выполняется командой svn update:

$ svn update
U  foo.c
U  bar.c
Updated to revision 2.

Буква перед артефактом означает действие выполняемое Subversion для обновление рабочей копии.

  • U foo — файл foo был обновлен (на основе полученных от сервера изменений).
  • A foo — файл или каталог foo был добавлен в рабочую копию.
  • D foo — файл или каталог foo был удален из рабочей копии.
  • R foo — файл или каталог foo был замещен в рабочей копии, т.е. foo был удален, и артефакт с таким же именем был добавлен. Хотя имя осталось прежним репозиторий считает, что артефакты являются различными объектами с отдельной для каждого историей.
  • G foo — файл foo получил новые изменения из репозитория, но локальная копия также была отредактирована. Изменения либо не пересекались, либо были идентичными, и Subversion успешно слил (merGed) полученные изменения с локальной версией.
  • C foo — для файла foo от сервера были получены изменения, напрямую пересекающиеся с локальными. Данный конфликт должен быть разрешен с участием пользователя.

Внесение изменений

Возможные изменения в рабочей копии:

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

Основные команды изменения дерева приведены ниже:

  • svn add foo — планирует добавление в репозиторий файла, каталога или символьной ссылки. При последующем коммите foo станет дочерним артефактом по отношению к родительскому каталогу. В случае если foo является каталогом все его содержимое также будет запланировано на добавление. Для добавления каталога без содержимого необходимо указать ключ --non-recursive (-N).
  • svn delete foo — планирует удаление из репозитория файла, каталога или символьной ссылки. В случае файла или символьной ссылки удаление в локальной копии происходит сразу. При последующем коммите артефакт будет удален как из рабочей копии, так и из репозитория.
  • svn copy foo bar — создает новый артефакт bar как копию foo. Артефакт bar автоматически планируется на добавление. При последующем коммите bar добавляется в репозиторий вместе с историей отражающей факт копирования.
  • svn move foo bar — данная команда эквивалентна svn copy foo bar; svn delete foo.

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

Проверка изменений

Команда svn status показывает все изменения в файлах и каталогах.

  L     some_dir            # для some_dir svn оставил блокировку в области .svn 
M       bar.c               # содержимое bar.c было изменено локально
 M      baz.z               # только зачения свойств bar.z были изменены
X       3rd_party           # 3rd_party является частью внешнего определения
?       foo.o               # svn не отслеживает foo.o
!       some_dir            # svn отслеживает артефакт, но он отсутствует или не полон
~       qux                 # версионируется как файл/каталог/ссылка, но тип был изменен
I       .screenrc           # svn игнорирует данный артефакт
A  +    moved_dir           # добавлен с историей
M  +    moved_dir/README    # добавлен с историей и имеет локальные изменения
D       stuff/fish.c        # файл запланирован на удаление
A       stuff/loot/bloo.h   # файл запланирован на добавление
C       stuff/loot/lump.c   # текст файла содержит конфликты из-за обновления
 C      stuff/loot/glub.c   # свойства файла содержат конфликты из-за обновления
R       xyz.c               # файл запланирован на замещение
    S   stuff/squawk        # файл или каталог был переведен в ветку
     K  dog.jpg             # файл заблокирован локально; метка блокирования присутствует
     O  cat.jpg             # файл заблокирован в репозитории другим пользователем
     B  bird.jpg            # файл заблокирован локально, но блокировка имеет дефект
     T  fish.jpg            # файл заблокирован локально, но блокировка перезахвачена

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

В первой колонке печатается код статуса файла или каталога и/или их содержимого:

  • A item — файл, каталог или символьная ссылка запланированы на добавление в репозиторий.
  • C item — файл находится в состоянии конфликта, т.е. полученные от сервера изменения пересекаются с локальными изменениями в рабочей копии. Конфликт должен быть разрешен до отправки изменений в репозиторий.
  • D item — файл, каталог или символьная ссылка запланированы на удаление из репозитория.
  • M item — содержимое файла было изменено.
  • R item — файл, каталог или символьная ссылка запланированы на замещение соответствующего артефакта в репозитории, т.е. в рамках одной ревизии данный объект сначала будет удален, а после объект с таким же именем будет добавлен в репозиторий.
  • X item — каталог не версионируется, и относится к внешнему определению (externals definition) Subversion.
  • ? item — файл, каталог или символьная ссылка не версионируются. Вывод данных файлов можно опустить либо указав ключ --quiet (-q) для команды svn status, либо с помощью задания свойства svn:ignore для родительского каталога.
  • ! item — файл, каталог или символьная ссылка версионируются, но утрачены или каким-то образом повреждены. Артефакт может быть утрачен по причине удаления без использования команд Subversion. Каталог может быть поврежден в случае прерывания получения рабочей копии или обновления. Вызов svn update обновит файл или каталог из репозитория, а вызов svn revert file восстановит утраченный файл.
  • ~ item — файл, каталог или символьная ссылка находятся в репозитории в виде, отличающемся от того, что находится в рабочей копии. Например, в репозитории содержится файл, а в локальной копии — каталог с таким же именем, и при этом не использовались команды svn delete и svn add.
  • I item — файл, каталог или символьная ссылка не версионируются т.к. Subversion настроен на его игнорирование в ходе выполнения команд svn add, svn import и svn status. Такие файлы будут выводится только в случае указания ключа --no-ignore при вызове команды svn status.

Вторая колонка показывает статус свойств файла или каталога. В случае изменения свойств будет выведено M, иначе — пробел.

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

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

Пятая колонка может содержать только пробел или S. Это означает, что файл или каталог был переключен с пути остальной рабочей копии на ветку (используя svn switch).

Шестая колонка показывает информацию о блокировках (отличных от L в третьей колонке).

Получение статуса конкрентного артефакта выполняется следующим образом:

$ svn status stuff/fish.c
D      stuff/fish.c

Вызов svn status с ключем --verbose (-v) выведет статус всех артефактов в рабочей копии, в том числе не изменившихся.

$ svn status --verbose
M               44        23    sally     README
                44        30    sally     INSTALL
M               44        20    harry     bar.c
                44        18    ira       stuff
                44        35    harry     stuff/trout.c
D               44        19    ira       stuff/fish.c
                44        21    sally     stuff/things
A                0         ?     ?        stuff/things/bloo.h
                44        36    harry     stuff/things/gloo.c

Смысл первой колонки остается таким же. Вторая колонка показывает номер рабочей ревизии артефакта. Третья и четвертая колонки показывают номер ревизии последнего изменения файла и имя пользователя внесшего эти изменения соответственно.

Все, перечисленные выше, команды работают без обращения к серверу. Для получения информации об актуальности артефактов используется ключ --show-updates (-u).

$ svn status --show-updates --verbose
M      *        44        23    sally     README
M               44        20    harry     bar.c
       *        44        35    harry     stuff/trout.c
D               44        19    ira       stuff/fish.c
A                0         ?     ?        stuff/things/bloo.h
Status against revision:   46

Звездочки говорят об имеющихся на сервере обновлениях.

Для получения информации о том, какие именно были внесены изменения используется команда svn diff:

$ svn diff
Index: bar.c
===================================================================
--- bar.c	(revision 3)
+++ bar.c	(working copy)
@@ -1,7 +1,12 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>

 int main(void) {
-  printf("Sixty-four slices of American Cheese...n");
+  printf("Sixty-five slices of American Cheese...n");
 return 0;
 }

Index: README
===================================================================
--- README	(revision 3)
+++ README	(working copy)
@@ -193,3 +193,4 @@ 
+Note to self:  pick up laundry.

Index: stuff/fish.c
===================================================================
--- stuff/fish.c	(revision 1)
+++ stuff/fish.c	(working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.

Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h	(revision 8)
+++ stuff/things/bloo.h	(working copy)
+Here is a new file to describe
+things about bloo.

Вывод команды представлен в универсальном формате (unified diff format).

Соответствующий патч (patch) можно получить вызвав:

Отмена изменений выполняется с помощью команды svn revert:

$ svn revert README
Reverted 'README'

В этом случае Subversion откатит файл до оригинального состояния находящегося в административной области .svn.

Концептуально, svn revert ITEM имеет тот же эффект, что и удаление артефакта из рабочей копии с последующим вызовом svn update -r BASE ITEM, за исключением отсутствия необходимости соединения с сервером.

Все три команды — svn status, svn diff и svn revert — выполняются без взаимодействия с сервером.

Разрешение конфликтов

$ svn update
U  INSTALL
G  README
C  bar.c
Updated to revision 46.

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

При возникновении конфликта обычно происходят три вещи:

  1. Subversion выводит C при обновлении и запоминает, что файл находится в состоянии конфликта.
  2. В случае если для файла возможно контекстное, построчное слияния, в содержимое вставляются особые строки — маркеры конфлита (conflict markers), которые отделяют конфликтующие области.
  3. Для каждого конфликтующего файла Subversion создает три дополнительных неверсионируемых файла в рабочем каталоге:
    • filename.mine — файл, содержащий локальные изменения до обновления.
    • filename.rOLDREV — файл, в состоянии BASE-ревизии, т.е. перед внесением локальных изменений.
    • filename.rNEWREV — версия файла, полученная от сервера при обновлении (HEAD-ревизия репозитория).

Subversion не позволит выполнить commit при наличии данных файлов.

$ svn commit --message "Add a few more things"
svn: Commit failed (details follow):
svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict

Разрешение конфликта можно выполнить тремя способами:

  • совместить конфликтующий текст вручную (при подсказке маркеров конфликта);
  • заменить рабочий файл на один из временных;
  • выполнить svn revert <filename> для отмены всех локальных изменений.

После разрешения конфликта необходимо уведомить об этом Subversion вызвав svn resolved:

$ svn resolved sandwich.txt
Resolved conflicted state of 'sandwich.txt'

Данная команда удалит три временных файла, и Subversion больше не будет считать, что файл находится в состоянии конфликта.

Слияние конфликта вручную

$ cat sandwich.txt
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
<<<<<<< .mine
Salami
Mortadella
Prosciutto
=======
Sauerkraut
Grilled Chicken
>>>>>>> .r2
Creole Mustard
Bottom piece of bread

Текст между <<<<<<< и ======= относится к локальным изменениям, а между ======= и >>>>>>> к изменениям полученным от сервера.

Замещение рабочего файла

$ svn update
C  sandwich.txt
Updated to revision 2.
$ ls sandwich.*
sandwich.txt  sandwich.txt.mine  sandwich.txt.r2  sandwich.txt.r1
$ cp sandwich.txt.r2 sandwich.txt
$ svn resolved sandwich.txt

Редактирование по-новой

$ svn revert sandwich.txt
Reverted 'sandwich.txt'
$ ls sandwich.*
sandwich.txt

В случае отката конфликтующего файла вызов svn resolved не требуется.

Фиксация изменений

Команда svn commit отправляет все изменения в репозиторий. Для указания комментария к коммиту используется опция --message (-m).

$ svn commit --message "Corrected number of cheese slices."
Sending        sandwich.txt
Transmitting file data .
Committed revision 3.

Для получения комментария из файла используется ключ --file:

$ svn commit --file logmsg 
Sending        sandwich.txt
Transmitting file data .
Committed revision 4.

В случае отсутствия --message или --file Subversion запустит редактор по-умолчанию.

В случае наличия в репозитории изменений для закомиченного файла svn commit завершится с ошибкой:

$ svn commit --message "Add another rule"
Sending        rules.txt
svn: Commit failed (details follow):
svn: Out of date: 'rules.txt' in transaction 'g'

В этом случае необходимо запустить svn update, разрешить возникшие конфликты и повторить вызов.

Итоги

Извлечение рабочей копии

svn co svn+ssh://<host or IP>/repo\trunk [targetDir]

Обновление репозитория

Работа с файлами

svn add src/main/java/Application.java
svn delete src/main/java/Application.java
svn copy src/main/java/Service1.java src/main/java/Service2.java
svn move src/main/java/Service1.java src/main/java/Service2.java

Проверка текущего состояния

svn status --show-updates

Фиксация изменений и отправка на сервер

svn commit -m "PROJ-0001 Description"

Разрешение конфликта

svn resolved src/main/java/Application.java

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

svn changelist PROJ-0001 src/main/java/Appliaction.java 
                         src/main/java/Utils.java
svn diff --changelist PROJ-0001
svn commit --changelist PROJ-0001 -m "PROJ-0001 Description"

Просмотр истории

svn log -r 100500 --diff | less

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

Понравилась статья? Поделить с друзьями:
  • Инструкция по тушению пожаров в электроустановках 2020
  • Втс 9090 инструкция по эксплуатации на русском
  • Шьем комбинезон для собаки своими руками пошаговая инструкция
  • Иксим люпин суспензия для детей инструкция по применению
  • Епбс руководство пользователя