Установка рассматривается на примере Debian 4.0 Etch. Без премудростей, штатными средствами, через apt-get
# apt-get install subversion
Subversion входит в состав этого дистибутива и имеет версию:
$ svn --version svn, version 1.4.2 (r22196) compiled Nov 10 2006, 17:39:50
Для хранилища лучше подобрать место понадёжнее. Если возможно - на отдельном разделе жесткого диска. Если настрой совсем серьёзный - то на отдельном диске. У меня подобные вещи хранятся в /home (на отдельном разделе). Для SVN - хранилища /home/svn
Создаём новое хранилище для проекта
$ svnadmin create /home/svn/test $ ls -l /home/svn/test итого 28 drwxr-xr-x 2 r-asian r-asian 4096 2008-01-03 17:57 conf drwxr-xr-x 2 r-asian r-asian 4096 2008-01-03 17:57 dav drwxr-sr-x 5 r-asian r-asian 4096 2008-01-03 17:57 db -r--r--r-- 1 r-asian r-asian 2 2008-01-03 17:57 format drwxr-xr-x 2 r-asian r-asian 4096 2008-01-03 17:57 hooks drwxr-xr-x 2 r-asian r-asian 4096 2008-01-03 17:57 locks -rw-r--r-- 1 r-asian r-asian 229 2008-01-03 17:57 README.txt
svnadmin создаёт каталог хранилища /home/svn/test для нашего проекта. 1. По своей сути хранилище subversion — это своя файловая система, хранящая информацию по всем производимым в проекте изменениям.
Итак, хранилище для проекта test было создано в разделе 2.1. Самое время разместить в нём наш проект - произвести импорт.
Создадим каталог /tmp/test и в нём 3 подкаталога: branches, tags, trunk и в trunk скопируем файлы нашего проекта
$ tree --dirsfirst /tmp/test
/tmp/test
|-- branches
|-- tags
`-- trunk
|-- css
| `-- main.css
|-- images
| |-- logo.jpg
| |-- person.png
| |-- talks.png
| `-- tools.png
|-- js
| `-- scripts.js
|-- libs
| |-- config.lib.php
| `-- users.lib.php
`-- index.php
7 directories, 9 files
Импортируем каталоги проекта в хранилище
$ svn import /tmp/test file:///home/svn/test -m "Комментарий к импорту" Adding /tmp/test/trunk Adding /tmp/test/trunk/images Adding (bin) /tmp/test/trunk/images/logo.jpg Adding (bin) /tmp/test/trunk/images/talks.png Adding (bin) /tmp/test/trunk/images/tools.png Adding (bin) /tmp/test/trunk/images/person.png Adding /tmp/test/trunk/css Adding /tmp/test/trunk/css/main.css Adding /tmp/test/trunk/libs Adding /tmp/test/trunk/libs/config.lib.php Adding /tmp/test/trunk/libs/users.lib.php Adding /tmp/test/trunk/js Adding /tmp/test/trunk/js/scripts.js Adding /tmp/test/trunk/index.php Adding /tmp/test/branches Adding /tmp/test/tags Committed revision 1.
Таким образом создана ревизия(правильнее её называть редакцией)проекта за номером 1.
Вся работа с SVN ведётся по схеме:
Под локальной копией будем понимать совокупность файлов проекта и служебных файлов subversion, скопированных для изменения в отдельный каталог.
Все правки проекта, как уже говорилось, проводятся не в самом хранилище, а с его локальной копией. Локальную копию можно сделать как с самой последней редакции(ревизии) проекта, так и с произвольной, имевшей место в прошлом.
Выясним какие редакции проекта лежат в хранилище:
$ svn log file:///home/svn/test ------------------------------------------------------------------------ r1 | r-asian | 2008-01-03 19:08:54 +0400 (Чтв, 03 Янв 2008) | 1 line Комментарий к импорту ------------------------------------------------------------------------
Чтобы узнать какие файлы были затроныты во время каждой редакции, добавим ключик -v
$ svn log -v file:///home/svn/test ------------------------------------------------------------------------ r1 | r-asian | 2008-01-03 19:08:54 +0400 (Чтв, 03 Янв 2008) | 1 line Changed paths: A /branches A /tags A /trunk A /trunk/css A /trunk/css/main.css A /trunk/images A /trunk/images/logo.jpg A /trunk/images/person.png A /trunk/images/talks.png A /trunk/images/tools.png A /trunk/index.php A /trunk/js A /trunk/js/scripts.js A /trunk/libs A /trunk/libs/config.lib.php A /trunk/libs/users.lib.php Комментарий к импорту ------------------------------------------------------------------------
Чтобы вывести редакции только с номерами в определённом диапазоне(в нашем случае у нас пока только одна редакция), воспользуемся конструкцией -r {начальный номер редакции}:{конечный номер редакции}
$ svn log -r 1:1 file:///home/svn/test ------------------------------------------------------------------------ r1 | r-asian | 2008-01-03 19:08:54 +0400 (Чтв, 03 Янв 2008) | 1 line Комментарий к импорту ------------------------------------------------------------------------
Если мы попытаемся указать в диапазоне несуществующий номер редакции, будет выведено сообщение об ошибке:
$ svn log -r 1:2 file:///home/svn/test svn: No such revision 2
Так же можно вывести список редакций, у которых дата помещения в хранилище лежит в определённом диапазоне. Например для получения списка редакций в диапазоне от 3 янваля 2008 г. 00:00 по 4 янваля 2008 г. 00:00:
$ svn log -r {2008-01-03}:{2008-01-04} file:///home/svn/test
------------------------------------------------------------------------
r1 | r-asian | 2008-01-03 19:08:54 +0400 (Чтв, 03 Янв 2008) | 1 line
Комментарий к импорту
------------------------------------------------------------------------
Получим самую последнюю по времени редакцию проекта из хранилища, и разместим её в /tmp/workcopy:
$ svn checkout file:///home/svn/test/trunk /tmp/workcopy A /tmp/workcopy/images A /tmp/workcopy/images/logo.jpg A /tmp/workcopy/images/talks.png A /tmp/workcopy/images/tools.png A /tmp/workcopy/images/person.png A /tmp/workcopy/css A /tmp/workcopy/css/main.css A /tmp/workcopy/libs A /tmp/workcopy/libs/config.lib.php A /tmp/workcopy/libs/users.lib.php A /tmp/workcopy/js A /tmp/workcopy/js/scripts.js A /tmp/workcopy/index.php Checked out revision 1.
Это и будет наша локальная копия. Если вывести полный список того, что в ней получилось:
$ tree -ad /tmp/workcopy
/tmp/workcopy
|-- .svn
| |-- prop-base
| |-- props
| |-- text-base
| `-- tmp
| |-- prop-base
| |-- props
| `-- text-base
|-- css
| `-- .svn
| |-- prop-base
| |-- props
| |-- text-base
| `-- tmp
| |-- prop-base
| |-- props
| `-- text-base
|-- images
| `-- .svn
| |-- prop-base
| |-- props
| |-- text-base
| `-- tmp
| |-- prop-base
| |-- props
| `-- text-base
|-- js
| `-- .svn
| |-- prop-base
| |-- props
| |-- text-base
| `-- tmp
| |-- prop-base
| |-- props
| `-- text-base
`-- libs
`-- .svn
|-- prop-base
|-- props
|-- text-base
`-- tmp
|-- prop-base
|-- props
`-- text-base
44 directories
Видно, что кроме файлов и каталогов проекта есть специальный скрытый каталог .svn. В нем хранится информация о расположении и содержании файлов в текущем каталоге копии проекта. Такие скрытые подкаталоги есть во всех каталогах. Они не подлежат ни удалению ни изменению, являясь связующим звеном между локальной копией и хранилищем. Находящиеся в них файлы тоже не стоит править.
Поскольку работа над проектом может вестись совместно, то в её ходе один из участников может в какой-то момент слить свою локальную копию(с внесёнными изменениями) в хранилище, оформив очередную редакцию проекта. Если такое произошло, то копии остальных участников работы перестают быть актуальными. Для восстановления актуальности необходимо обновить свою рабочую копию:
$ svn update /tmp/workcopy/ At revision 1.
В этом случае локальная копия будет обновлена до последней по времени редакции. Если необходимо обновить до редакции с определённым номером — воспользуемся ключом -r
$ svn update -r 1 /tmp/workcopy/ At revision 1.
Предположим, что был добавлен файл /tmp/workcopy/images/import_icon.jpg. Включим его в список файлов локальной копии хранилища.
$ svn add /tmp/workcopy/images/import_icon.jpg A (bin) /tmp/workcopy/images/import_icon.jpg
Теперь SVN может отслеживать изменения этого файла. До момента добавления этого файла как бы не существует, и никакие операции subversion с ним не проводит.
Если файлов добавляется достаточно большое количество, и все они лежат в известном нам каталоге, то можно ограничится указанием соответствующего каталога, а SVN добавит ещё не добавленые, а для добавленных выведет предупреждение. Предположим, что в локальной копии мы создали файлы: /tmp/workcopy/images/crazytux.png, /tmp/workcopy/libs/auth.lib.php. Добавим в локальное хранилище все недобавленные файлы в /tmp/workcopy/libs:
$ svn add /tmp/workcopy/libs/* A /tmp/workcopy/libs/auth.lib.php svn: warning: '/tmp/workcopy/libs/config.lib.php' is already under version control svn: warning: '/tmp/workcopy/libs/users.lib.php' is already under version control
и в/tmp/workcopy/images
$ svn add /tmp/workcopy/images/* A (bin) /tmp/workcopy/images/crazytux.png svn: warning: '/tmp/workcopy/images/import_icon.jpg' is already under version control svn: warning: '/tmp/workcopy/images/logo.jpg' is already under version control svn: warning: '/tmp/workcopy/images/person.png' is already under version control svn: warning: '/tmp/workcopy/images/talks.png' is already under version control svn: warning: '/tmp/workcopy/images/tools.png' is already under version control
Предположим, что в index.php в 1-х строчках заменили:
<?php
include_once("libs/config.lib.php");
на
<?php
include_once("libs/auth.lib.php");
include_once("libs/config.lib.php");
Посмотрим чем отличается локальная копия проекта от последней по времени редакции в хранилище.
$ svn diff /tmp/workcopy/
Index: /tmp/workcopy/images/import_icon.jpg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: /tmp/workcopy/images/import_icon.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: /tmp/workcopy/images/crazytux.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: /tmp/workcopy/images/crazytux.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: /tmp/workcopy/libs/auth.lib.php
===================================================================
--- /tmp/workcopy/libs/auth.lib.php (revision 0)
+++ /tmp/workcopy/libs/auth.lib.php (revision 0)
@@ -0,0 +1,117 @@
+<?php
+ //....... Текст файла ........
+?>
Index: /tmp/workcopy/index.php
===================================================================
--- /tmp/workcopy/index.php (revision 1)
+++ /tmp/workcopy/index.php (working copy)
@@ -1,4 +1,5 @@
<?php
+ include_once("libs/auth.lib.php");
include_once("libs/config.lib.php");
header("Content-type: text/html; charset=windows-1251");
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
Тут отражены все изменения, которые были проведены с локальной копией с момента последнего копирования из хранилища.
Если необходимо получить сравнение локальной копии с определённой редакцией проекта, воспользуемся уже хорошо известным ключиком -r.
$ svn diff -r 1 /tmp/workcopy/
Предположим, что ранее был добавлен файл /tmp/workcopy/.htaccess, в локальную копию хранилища.
$ touch /tmp/workcopy/.htaccess $ svn add /tmp/workcopy/.htaccess A /tmp/workcopy/.htaccess
Чтобы удалить его не только из каталога, где располагается локальная копиея, но и самой локальной копии проекта, необходимо сначала его удалить физически, а затем и из svn:
$ rm /tmp/workcopy/.htaccess $ svn delete /tmp/workcopy/.htaccess D /tmp/workcopy/.htaccess svn: '/tmp/workcopy/.htaccess' does not exist
Итак. Все необходимые изменения сделаны, и локальную копию можно слить в хранилище, оформив как очередную редакцию проекта. Для начала, крайне рекомендуется обновить локальную копию, чтобы в нашу редакцию вошли так же правки, сделанные за время нашей работы, руками других участников проекта.
$ svn update /tmp/workcopy/ At revision 1.
Если не обнаружено никаких конфликтов - можно фиксировать свои изменения:
$ svn commit /tmp/workcopy/ -m "Комментарий к редакции проекта" Adding (bin) images/crazytux.png Adding (bin) images/import_icon.jpg Sending index.php Adding libs/auth.lib.php Transmitting file data .... Committed revision 2.
Получим информацию о редакциях нашего проекта и порадуемся:
$ svn log -v file:///home/svn/test ------------------------------------------------------------------------ r2 | r-asian | 2008-01-04 17:42:42 +0400 (Птн, 04 Янв 2008) | 1 line Changed paths: A /trunk/images/crazytux.png A /trunk/images/import_icon.jpg M /trunk/index.php A /trunk/libs/auth.lib.php
Комментарий к редакции проекта ------------------------------------------------------------------------ r1 | r-asian | 2008-01-03 19:08:54 +0400 (Чтв, 03 Янв 2008) | 1 line Changed paths: A /branches A /tags A /trunk A /trunk/css A /trunk/css/main.css A /trunk/images A /trunk/images/logo.jpg A /trunk/images/person.png A /trunk/images/talks.png A /trunk/images/tools.png A /trunk/index.php A /trunk/js A /trunk/js/scripts.js A /trunk/libs A /trunk/libs/config.lib.php A /trunk/libs/users.lib.php Комментарий к импорту ------------------------------------------------------------------------
В данной статье были рассмотрены такие вопросы как:
К сожалению в статье не рассотрены многие вопросы, например создания веток проекта и их слияние, но и без этих вопросов текст оказался довольно общирен, так что лучше отложить эту тему для более подходящего момента.