Основные понятия 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; }
После компиляции и тестирования Том фиксирует свои изменения в хранилище.
Данный цикл статей посвящен введению в использование SVN, с точки зрения обычного пользователя. Статья была написана в помощь моим коллегам для быстрого освоения и использования SVN. Итак начнем с азов.
Данный материал был опубликован в журнале «Компоненты и технологии»
Введение
Subversion (SVN) — бесплатная система управления версиями с открытым исходным кодом. SVN позволяет управлять файлами и каталогами, а так же сделанными в них изменениями во времени. SVN предоставляет следующие возможности :
- Контроль изменений каталогов. SVN использует «виртуальную» файловую систему с возможностями управления версиями, которая способна отслеживать изменения во времени целых структур каталогов
- Настоящая история версий. SVN делает возможным добавление, удаление, копирование и переименование как файлов, так и каталогов. При этом каждый вновь добавленный файл начинает жизнь с чистого листа, сохраняя собственную историю изменений
- Атомарная фиксация изменений. Каждый набор изменений либо попадает в хранилище целиком, либо не попадает туда вовсе. Т.е. если при фиксации изменений проекта произошла ошибка при обработке файла, то изменения всего проекта не будут зафиксированы
- Метаданные с версиями. Каждый файл и каталог имеет собственный набор свойств, представленных в виде названия и значения. Вы можете создавать и сохранять любые необходимые пары названий свойств и их значений. Свойства файлов точно так же находятся под управлением версиями, как их содержимое
- Единый способ работы с данными. SVN обнаруживает различия между файлами с помощью специального бинарного алгоритма, который одинаково работает как с текстовыми, так и с бинарными файлами. Файлы записываются в хранилище в сжатом виде независимо от их типа, а различия между отдельными версиями могут передаваться по сети в обоих направлениях
- Эффективные ветки и метки. SVN создаёт ветки и метки путём простого копирования проекта, используя механизм, похожий на жёсткие ссылки в файловых системах. Благодаря этому, операции по созданию веток и меток занимают немного времени.
Список основных терминов
- Репозиторий (repository) — централизованное хранилище исходных кодов, рабочих материалов и документации. Любое количество клиентов подключается к хранилищу и читает или записывает эти файлы
- Рабочая копия/working copy (WC) — обычное дерево каталогов на компьютере, содержащие набор файлов для работы над проектом. Изменения в рабочей копии не доступны для других пользователей репозитория, до тех пор пока они не будут зафиксированы.
- Trunk — основное направление разработки
- Branch (»Ветка») — направление разработки, которое существует независимо от другого направления, но имеет с ним общую историю. Ветка всегда берет начало как копия чего-либо и движется от этой точки, создавая свою собственную историю
- Tag (»Метка») — выделенная явно, через создание отдельной папки версия файлов проекта в определенный момент времени.
- Revision — номер ревизии репозитория, в пределах репозитория номер ревизии уникальная величина
- Checkout – команда, которая выполняет начальное получение проекта из репозитория в WC.
- Commit – команда, которая выполняет фиксацию изменений файлов проекта в WC в Репозиторий.
- Update – команда, которая выполняет обновление файлов проекта в WC из репозитория
- Revert – команда, которая выполняет отмену любых изменений в файлах проекта в WC на основе номера ревизии репозитория.
- Merge – команда, которая выполняет слияние файлов из разных веток проекта и помещает результат слияния в WC.
- Conflict – ситуация, возникающая при фиксации изменений, когда одни и те же файлы изменяли несколько разработчиков.
- Resolve – набор правил по разрешению возникающих конфликтов.
- Import – команда, для быстрого копирования дерева файлов в Репозиторий.
- Export – команда, для экспорта проекта, отличается от checkout тем, что не создает в папках проекта служебную информацию.
- Switch – команда, которая выполняет переключение WC на другую ветку разработки.
- Create, Add, Delete, Copy, Move, Rename – команды для управления файлами и папками в репозитории или WC.
Программное обеспечение
Работа с репозиторием SVN рассмотрена на основе программного обеспечения TortoiseSVN tortoisesvn.net/ версии 1.5.8 и программы сравнения файлов ExamDiff.
Время на прочтение
6 мин
Количество просмотров 303K
По просьбам трудящихся, а так же учитывая, что есть статья по установке SVN (правда +Trac) под Linux, решил написать краткое описание установки и настройки SVN для Windows.
Ничего нового для людей, хорошо знающих и работающих с SVN, здесь не будет. Цель статьи — помочь некоторому проценту новичков, пребывающих на Хабре, таки осилить изучение этой системы контроля версий.
С самого начала сообщаю, что для SVN есть подробное руководство. Называется оно svn-book и доступно на сайте и идет вместе с CollabNet Subversion-server. Так же про установку и настройку svnserv с Apache есть описание в учебнике по TortioseSVN (довольно хорошая подробная помощь на русском).
На самом деле SVN-клиент может отлично работать и без сервера. Репозиторий (хранилище кода) можно создать в любом каталоге на собственном HDD, или в сетевом каталоге. Сервер требуется лишь для удаленного доступа к репозиторию, не больше. Локальный репозиторий годится, если над проектом работает один человек и ему просто нужна система контроля версий своего приложения и бэкапы.
Если работа ведется в команде или требуется удаленный доступ к репозиторию (через Интернет, например), нужно устанавливать SVN-сервер. Он может работать самостоятельно, либо через веб-сервер Apache. В первом случае доступ к репозиториям будет по протоколу svn://, во втором — http(s)://. Доступ через веб-сервер нужен при проблемах с файрволом, когда он пропускает только HTTP-трафик, а так же для работы некоторых утилит-примочек к SVN-серверу.
Установка сервера
Самую свежую версию svn-cервера всегда можно найти на сайте subversion.tigris.org. Чистый svn-сервер без Apache в комплекте, и без визуальных примочек доступен только для версии 1.4.6, в то время как текущая версия 1.5.0. Для версии 1.5.0 есть выбор между CollabNet Subversion-server-1.5.0 (~11 MB) и VisualSVN Server (~5 MB). Первый идет в комплекте с Apache, второй — с Apache и плагином для Windows Management Console. Так же для VisualSVN есть платная возможность интеграции с Visual Studio.
A. Установка и настройка сервера VisualSVN (svn-сервер + Apache + консоль управления) самая простая. Эту версию нельзя установить без Apache.
1) Скачиваем файл VisualSVN-Server-1.5.1.msi или новее. Запускаем установку.
2) В мастере установки указываем, использовать ли для доступа HTTPS, либо просто HTTP. Указываем порт для прослушивания по выбранному протоколу и способ аутентификации. Так же указываем каталог, в котором будут храниться репозитории.
3) После установки открываем Management Console (через Пуск, например) и создаем пользователей и репозитории.
Теперь ваши репозитории доступны через выбранный протокол (HTTP или HTTPS) по указанному при установке хосту: порту (например, localhost:8443/svn/). Их можно просматривать как из браузера (через xsl), так и из SVN-клиета.
Работа с сервером VisualSVNбезусловно самая простая.
B. Установка CollabNet Subversion Server (svn-сервер + Apache опционально).
1) Скачиваем файл CollabNetSubversion-server-1.5.0-23.win32.exe или версию новее. Запускаем его на установку.
2) Шаг Choose Components. Устанавливаем флажок SVNSERVE в любом случае. Если требуется установить так же Apache для SVN, устанавливаем флажок напротив него.
3) На шаге sunserve Configuration устанавливаем порт для sunserve (по умолчанию 3690, менять его смысла нет, если он не занят) и путь к репозиториям (каталог, где вы будете создавать отдельные репозитории в виде подкаталогов).
4) Затем настраивается Apache: хост/порт, путь к репозиториям (тот же, что и для svnserve) и префикс для URL (http://host:port/prefix). Префикс нужен на случай, если Apache будет использоваться не только для обслуживания SVN.
После установки появятся две новых службы Windows: Subversion Server (наш svnserv.exe) и Apache2.2 (если он был включен при установке). Чтобы все заработало их нужно запустить.
С. Установка svnserve 1.4.6 (чистый svn-сервер).
1) Скачиваем файл svn-1.4.6-setup.exe. Запускаем его на установку. При установке ничего кроме целевого каталога указывать не надо. После установки этот каталог надо добавить в переменную среды PATH (не помню, возможно это делается автоматически).
2) Создаем репозитории командой: svnadmin create c:repositoriesexample-repository
3) Создаем сервис. Команда в консоли: sc create svn_svr binpath= «c:Program FilesSubversionbinsvnserve.exe —service -r C:repositories» displayname= «Subversion Svr»
Здесь -r C:repositories — адрес каталога с репозиториями, т.е. от него потом будут вычисляться пути. Например, если есть 2 репозитория: C:repositoriesproj1 и C:repositoriesproj2, то указав параметром -r C:repositories потом пути к репозиториям будут: svn://localhost:3690/proj1 и svn://localhost:3690/proj2 соответственно. Порт 3690 устанавливается по умолчанию, но его можно поменять (подробности в svn book).4) Запускается сервис автоматически при старте Windows или из списка служб.
Именно эту работу (если не считать установку Apache) сделал за вас установщик CollabNet Subversion Server. В случае установки svnserve 1.4.6 доступ к репозиторию будет только по протоколу svn://.
D. Создание репозитория. Выделяю этот пункт отдельным разделом. Если в VisualSVN создание репозитория производится кликом мыши, то для svnserve (в том числе в версии от CollabNet) репозиторий создается из консоли. В поставке snv-сервера есть файл snv-install-folderbinsvnadmin.exe. Если путь к snv-install-folderbin еще не прописан в PATH, сделайте это.
Чтобы создать репозиторий, откройте консоль (cmd) и перейдите в каталог для хранения репозиториев, который вы указывали при установке (CollabNet) или создании сервиса (svnserve 1.4.6). Создайте новый пустой подкаталог (например, example-repository). В консоли выполните команду: svnadmin create example-repository. В только что созданном каталоге появится структура файлов svn. В них есть много полезных «штук», о которых можно почитать в svn-book и учебнике.
В подкаталоге conf можно настроить основные параметры репозитория. Прежде всего требуется закрыть доступ в репозиторий кому-попало. В файле svnserve.conf раскомментируем строки
# anon-access = read
# auth-access = write
Не забудьте убрать так же пробел после #, т.к. иначе будет ошибка чтения конфига. anon-access определяет доступ анонимным пользователям, auth-access — зарегистрированным. Они могут принимать значения «write», «read» и «none». Обычно anon-access = none и auth-access = write.
Далее надо раскомментировать # password-db = passwd, а в файл passwd в этом же каталоге добавить строку user = password.
Для начала такое определение доступа годится, но в последствии конечно пароли надо шифровать (читаем svn-book).
На этом установка сервера закончена и можно установить клиент.
Установка клиента.
Некоторые профессионалы предпочитают работать с консолью. Наверное это не самый удобный способ, особенно для новичков, поэтому рассматривать его не будем. Другие работают с SVN через плагины к своим IDE. Это самый лучший способ, но поскольку разных IDE много и плагинов к ним тоже, в этой статье работу с ними не описываем.
Самым популярным и признанным клиентом SVN под Windows является TortoiseSVN. После его установки вы не получите отдельной программы, которую можно «классически запустить», клиент встраивается в проводник Windows, а команды для него доступны из контекстного меню файла (в т.ч. и в Total Commander).
Описывать установку клиента нет никакого смысла, там все элементарно просто.
О том, как работать с TortoiseSVN, подробно расписано в руководстве TortoiseSVN Клиент Subversion для Windows.
Дублировать это подробное руководство, конечно, желания нет, но все же super-fast-start work with tsvn опишу.
1) Для просмотра любого репозитория после установки TortoiseSVN вызовите контекствное меню на любом файле в системе, выберите меню TortoiseSVN→Repo-browser. В открывшемся окошке введите адрес репозитория с протоколом (например, localhost:8443/svn/test или svn://someserver:3690/proj1/trunc). Откроется окно просмотра репозитория (с помощью кнопки напротив строки адреса можно выбрать, какую ревизию просмотреть; HEAD — это последняя ревизия).
2) Для создания локального репозитория (не используя сервер) запускается пункт меню TortoiseSVN→Create repository here… на нужном каталоге. В Repo-browser такой репозиторий доступен по протоколу file:///.
3) Для скачки себе версии из существующего репозитория запускается пункт меню TortoiseSVN→SVN Checkout на каталоге, в который сольется версия.
4) Если вы еще не использовали SVN и хотите залить на сервер свою текущую версию исходников, запустите пункт меню TortoiseSVN→Import… на каталоге, в котором лежит версия (при этом не забудьте, что разрабатываемую ветку надо лить в trunk).
5) TortoiseSVN→Export… используется для получения чистой версии исходников из репозитория (без служебных файлов контроля версий).
6) Если контекстное меню вызвать на каталоге, который является локальной (рабочей) копией репозитория, контекстное меню значительно расшириться. Например, появятся пункты Update (слить последние изменения с сервера) и Commit (закачать ваши изменения на сервер).
На последок рекомендую почитать интересную серию статей Работа с Tortoise SVN.
Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%
Здравствуй, уважаемый читатель блога LifeExample. При разработке любого более-менее крупного проекта невозможно обойтись без системы контроля версиями (SVN). Настройка SVN может загнать в тупик многих начинающих web разработчиков. Я до недавнего времени также пребывал в замешательстве и больших вопросах относительно установки и настройки SVN.
Дабы уберечь вас от изучения уймы полезной и бесполезной информации, доступной в интернете, я хочу показать вам, как выглядит настройка SVN по шагам, а также рассказать, что такое система контроля версий.
Что такое система контроля версий
Система контроля версий (по англ. Version Control System, сокращенно VCS) состоит из двух частей:
- Сервер, он же хранилище, он же репозиторий — где хранятся все файлы проекта, а также история их изменения.
- Клиент — программа для работы с хранилищем, каждый клиент имеет свою локальную копию файлов проекта, с которой работает разработчик.
VCS предназначена для упрощения совместной разработки проекта, несколькими и более программистами.
Многие начинающие программисты одиночки при написании кода, создают (backup) копии папок, с программой помечая их текущей датой, или порядковым номером.
Вспомните ваш процесс разработки, какого либо проекта. Я уверен, что выше описанная ситуация вам знакома. А сталкивались ли вы с ситуацией, когда вам нужно вернуться не к последней версии, а скажем к одной из сделанных месяц назад?
Проблема в том, что с таким подходом, мы не можем с уверенностью сказать, какие были произведены изменения спустя месяц, и что было сделано на момент создания копии проекта.
Благодаря системам контроля версий, можно не только быть всегда в курсе введенных изменений относительно любой сделанной ранее копии программы, но и вести разработку проекта в команде с другими программистами.
Если вы интересовались вакансиями web разработчиков, то не могли пропустить одного из требований к кандидатам, встречаемое теперь почти в каждом предложении.
Требования к Соискателю
Умение работать с SVN (либо аналогичной системой контроля версий)
Именно система контроля версий Subversion (SVN) применяется в большинстве организаций, поэтому я и расскажу сегодня о работе и настройке с SVN.
Настройка сервера (шаг 1)
Целью статьи является не только познакомить вас с системой контроля версий, но и дать возможность попрактиковаться с её использованием, поэтому сервер я предлагаю разместить локально. Поскольку не у всех есть возможность выделить под него отдельный хостинг.
Примечание! Разработчики не советую пользоваться локальной версией, в режиме работы команды. Локальная версия подходит только для ведения проекта одним программистом.
Чтобы самостоятельно настроить SVN server, можно скачать, одну из предлагаемых на официальном сайте, программ с SVN сервером в комплекте, или же ограничиться чистым SVN сервером и скачать Subversion 1.7.
Так, как статья рассчитана на новичков, и предполагает что, вы уважаемые читатели, совершенно не понимаете, как самостоятельно установить и настроить SVN, я покажу вам самый кротчайший путь, от неведения к действиям, с помощью популярной в области систем контроля версий программы TortoiseSVN.
TortoiseSVN — это бесплатный клиент для системы контроля версий Subversion, выполненный как расширение оболочки Windows. Вся прелесть программы заключается в том, что она не только является клиентом, но и может автоматически в несколько кликов мыши создать локальный SVN сервер, пригодный для работы.
Таким образом, чтобы настроить SVN сервер, первым делом нам нужно скачать и установить программу TortoiseSVN.
TortoiseSVN_1.7.7 x32bit + RUS ( Скачали: 410 чел. )
TortoiseSVN_1.7.7 x64bit + RUS ( Скачали: 537 чел. )
После инсталляции программы, в контекстном меню проводника должны появиться характерные для TortoiseSVN пункты меню.
Организуем хранилище наших проектов, для этого на диске С: создадим новый каталог с именем SVNrepository, откроем его, и щелкнув правой кнопки мыши, в контекстном меню выбирем TortoiseSVN->»Создать здесь хранилище».
Каталог SVNrepository должен заполниться файлами вышеприведенной структуры, после чего можно считать, что мы завершили настройку SVN сервера и готовы к работе.
Установка клиента (Шаг 2)
Как это ни странно но, клиентское приложение мы уже установили, и можем благополучно пользоваться им. Запустить его привычным всем методом через кнопку пуск или с ярлыка на рабочем столе – не получится, поскольку оно уже успешно работает.
При установке инсталер TortoiseSVN создал соответствующие службы, которые теперь будут запускаться автоматически с запуском windows. Благодаря этим службам в контекстном меню проводника стали доступны новые пункты меню.
Собственно с их помощью, и будет происходить вся последующая работа с системой контроля версий. Такая полезная интеграция клиента SVN, прямо в проводник windows сократит до нуля, время на изучение интерфейса нового клиента, ведь в наше время все привыкли пользоваться мышкой и контекстным меню.
Настройка структуры хранилища (Шаг 3)
Закончив настройку составляющих SVN, сервера и клиента, я предлагаю немножко попрактиковаться, и посмотреть, как же все это должно выглядеть и работать.
В документации к данной программе разработчики советуют использовать в хранилище три определяющих каталога:
В каталоге trunk расположим основной проект, над которым будем вести работу.
Каталог branches будет содержать последующие копии ответвлений проекта, или проще говоря – версий проэкта.
Не совсем ясным для меня осталось назначение папки tags для копий меток, пока в голове нет четкой картины, где бы она могла понадобиться.
Разработчики в руководстве упоминают о том, что любая организация – каталога, имеет право на существование, и определяется только требованиями конкретного проекта. Именно поэтому, я создам в репозитории (хранилище), всего два каталога.
В trunk я намерен хранить текущую реализацию проекта, а в branches все разрабатываемые в прошлом и в дальнейшем версии.
Т.е. формально я представляю себе репозиторий такого вида:
/trunk /release v2 /branches /release v1 /release v2 /release v3
Из этой структуры следует, что на момент разработки версии v3 в текущий момент успешно выпущена и поддерживается версия v2.
Чтобы создать каталоги в хранилище, нужно открыть контекстное меню папки SVNrepository и выбрать пункт TortoiseSVN->»Обозреватель хранилища». Откроется окно для работы с хранилищем.
В котором с помощью все того же контекстного меню, можно будет создать необходимые каталоги.
Попутно добавим в /branches каталог /release v1, в котором будут храниться версии первой разрабатываемой версии проекта.
Заметьте при создании или редактировании файлов и каталогов, мы можем оставлять комментарии, для упрощения дальнейшей навигации по хранилищу.
Основа для работы готова, закончена настройка SVN сервера под конкретный пример, теперь давайте начнем разрабатывать наш тестовый проект.
Создание рабочей копии (Шаг 4)
В папку branches/release v1 добавим файл ReadMe.txt нашего, пока не существующего, проекта. Соответственно, нужно изначально подготовить данный файл, и осилить написать туда пару строчек текста, зачем, расскажу позже.
Перенеся файл в репозитории, мы наконец-то можем возрадоваться началу процесса разработки проекта и контроля его версий. Теперь откройте любой каталог у себя на компьютере, в котором планируете создавать проект. Пусть это будет: C:/Project1.
В контекстном меню выберите пункт «SVN извлечь«, укажите в качестве URL хранилища, путь до папки с версией v1:
file:///C:/SVNrepository/brunches/release v1
Подтвердите выбор, нажатием на кнопку «Ок«, и наблюдайте ха процессом извлечения, новой рабочей копии из репозитория.
Обратите внимание, на папке проекта C:/Project1 появилась пиктограмма в виде зеленой галочки. Это означает, что все прошло успешно и рабочая копия полностью синхронизирована с хранилищем.
Изменение файлов проекта (Шаг 5)
Следующим шагом немного изменим, содержимое файла C:Project1ReadMe.txt, можете внести любые изменения, на свое усмотрение.
Как только мы сохраним изменения система SVN установит на файле пиктограмму восклицательного знака, означающую то что, данный файл в текущей рабочей копии был изменен. Такой же знак отличия получит и папка в которой находится редактируемый файл.
После завершения всех изменений, нужно выгрузить рабочую копию обратно в репозиторий, что бы она была зафиксирована, и получила возможность быть восстановленной в любое время.
Применение изменений файлов (Шаг 6)
В контекстном меню папки Project1 выберем пункт «SVN фиксировать«, система предложит указать комментарии, перед тем как файлы будут загружены на сервер. Не ленитесь их заполнять, поскольку в последствии, они сыграют вам на руку при необходимости отката версий.
Кроме того в открывшемся окне, мы можем произвести сравнение файла с предыдущими его версиями. Если вы следовали моим советам, и изменяли строки ReadMe.txt, то сможете оценить прелесть работы встроенной в TortoiseSVN программы для стравнения текстовых файлов. Для этого выберите в контекстном меню, пункт «Cравнить с базой«.
На первый взгляд может показаться сумбурно, и не понятно, но спустя некоторое время, вы оцените удобность работы данного приложения.
Подтвердив фиксацию, изменений, папка Project1, вновь приобретет пиктограмму галочки, и вы сможете дальше работать с копией, а все изменения зафиксируются в хранилище, и в последствии, мы запросто сможем восстановить оду из копий измененных файлов.
Откат к предыдущей версии (Шаг 7)
Если спустя некоторое время, стало ясно, что все идет не так, и мы хотим вернуть файлу прежний вид, сделать это можно удобным способом. В контекстном меню файла C:Project1ReadMe.txt выберем пункт «Обновить до ревизии»
Заметьте что по умолчанию, система SVN предлагает обновиться до HEAD ревизии, т.е. до последней, но мы можем указать номер ревизии, к которой нужно откатить файл. Если номер не известен, можно использовать Журнал ревизий, и отметить именно ту версию, которая нас больше всего устраивает. Подтвердив выбор кнопкой «ОК", файл будет заменен более ранней версией.
Настройка SVN сервера как оказалось, заняла меньше времени, нежели описание процесса работы с системой контроля версий. Но зато получился неплохой мануал для начинающих. Тем кто столкнулся с проблемами в настройке SVN, или возникли вопросы по использованию TortoiseSVN, я рекомендую, не стесняясь писать комментарии к статье.
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.
по мотивам «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
и соответствует пустому корневому каталогу.
Номера ревизий в 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
.
Смешивание ревизий — это полезно
Смешивание ревизий дает возможность переместить определенную часть рабочей копии в истории, позволяя исследовать более ранние изменения.
Смешивание ревизий имеет ограничения
- Невозможно зафиксировать (commit) удаление неактуального файла.
- Невозможно зафиксировать изменения метаданных неактуального каталога. Рабочая ревизия каталога имеет определенный набор свойств, и фиксация изменений свойств неактуального каталога может привести к утрате свойств, неизвестных рабочей копии.
Экскурсия по 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.
Простой рабочий цикл
Типичный рабочий цикл выглядит следующим образом:
- Обновление рабочей копии
svn update
- Внесение изменений
svn add
svn delete
svn copy
svn move
- Проверка изменений
svn status
svn diff
svn revert
- Слияние опубликованных изменений с локальной рабочей копией
svn update
svn resolved
- Фиксация изменений
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) с изменениями пришедшими с сервера, и требуется ручное вмешательство.
При возникновении конфликта обычно происходят три вещи:
- Subversion выводит
C
при обновлении и запоминает, что файл находится в состоянии конфликта. - В случае если для файла возможно контекстное, построчное слияния, в содержимое вставляются особые строки — маркеры конфлита (conflict markers), которые отделяют конфликтующие области.
- Для каждого конфликтующего файла 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
Откат изменений