http://youinf.ru/imgs/svn.jpg

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

Всю проделанную над проектом работу удобно хранить в системе управления версиями Subversion.

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть все подразделы меню

Зачем это нужно

Введение

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

1. Выполнение отката всех изменений после правок в коде
2. Сложности манипулирования большим числом версий, хранящихся в отдельных папках
3. Автоматизация процесса объединения изменений, сделанных разными разработчиками

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

Система управления версиями (от англ. Version Control System) позволяет хранить несколько версий проекта и при необходимости возвращаться к более ранним версиям, определять, кто и когда сделал то или иное изменение и многое другое.

Одной из самых распространенных VCS в мире является Subversion (SVN).

SVN использует в своей основе принцип хранения версии проекта в виде патчей.

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

Каждая ревизия в SVN – это архив с патчами для всех измененных файлов.

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

Структура VCS

Обычно VCS состоит из двух частей:

  • Сервер или репозиторий — где хранятся все исходные коды программы, а также история их изменения.
  • Клиент. Каждый клиент имеет свою локальную копию (working copy) исходных кодов, с которой работает разработчик.

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

У VCS есть две модели, которые позволяют обойти эту проблему:

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

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

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

Система SVN

Система SVN

SVN является одной из клиент-серверных систем контроля версий и состоит из двух частей:

Svnserve — серверная часть. В качестве её можно использовать обычный http-сервер.
SVN — клиентская часть

Можно создать и настроить собственный SVN-сервер или использовать готовые бесплатные сервисы: code.google.com , sourceforge.net .

Команды SVN

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

Наиболее часто используемые разработчиками команды:

  • svn update – обновляет содержимое локальной копии до самой последней версии из репозитория.
  • svn commit – отправляет все изменения локальной копии в репозиторий.
  • svn add <файл/папка> – включить файл/папку в локальную копию проекта

Нередко используются команды:

  • svn move <файл/папка1> <папка2> – переместить файл/папку1 в папку2
  • svn copy <файл/папка> <папка> – скопировать файл/папку1 в папку2
  • svn delete <файл/папка> – удалить файл/папку из локальной копии проекта

Прочие полезные команды SVN:

  • svn list <URL> – просмотр каталога репозитория
  • svn log <файл> –verbose – история изменения файла по ревизиям
  • svn cat –revision <номер_ревизии> <файл> – отображение содержимого файла из данной ревизии
  • svn diff –revision <номер_ревизии1:номер_ревизии2> <файл> – отображение изменений файла между двумя ревизиями
  • svn status – отображение изменений в локальной копии относительно репозитория

Жизненный цикл проекта на SVN

Допустим, что у нас уже есть настроенный SVN-сервер, и мы хотим перенести на него проект.

У нас есть папка test, в которой лежит три файла:

Добавляем новые файлы на сервер:

Здесь svn://……../repo/test – url-адрес проекта, test – название добавляемой папки.

Получаем локальную копию файлов проекта:

project/test – адрес, где будет располагаться локальная копия.
После выполнения этой команды получим следующую структуру файлов:

Локальную копию не следует добавлять в ту папку, из которой делали import, так как при совпадении имён файлов они не будут перезаписаны.

Изменяем файлы

Допустим, на этом шаге мы хотим сделать какие-нибудь изменения в проекте, а именно:

  • изменить содержимое file1.cpp следующим образом:
    до изменений:

    после изменений:

  • удалить файл file2.cpp
Изменения в структуре файлов проекта

Стоит обратить внимание на следующую особенность SVN: содержимое файлов проекта можно менять в любых привычных редакторах, но изменения в структуре файлов проекта следует выполнять с помощью соответствующих команд svn (add, copy, move, delete, rename).

То есть, если мы просто удалим файл из папки с локальной копией, это никак не отразится на содержимом репозитория даже после успешного commit’a.

Фиксируем состояние

При фиксации происходит отправка всех изменений в локальной копии на сервер.

-m “…..” – комментарий к commit’у.
При выполнении этой команды SVN узнаёт нужную ему информацию о проекте из папки .svn

После каждого commit’а номер ревизии увеличивается на единицу.
Номер ревизии (Revision) &mdash целое число, показывающее номер состояния проекта.

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

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

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

Такая ситуация называется конфликтом. У разработчика, чей commit не удался из-за конфликтов, есть два возможных варианта действий:

  1. svn revert – возвращает файл в состояние, предшествующее модификации, путем его замены на кэшированную первоначальную копию
  2. svn update – забрать из репозитория новые версии файлов и, разрешив конфликты, снова попытаться сделать commit

Как разрешаются конфликты

Допустим, в репозитории хранится файл main.cpp ревизии 13:

В какой-то момент user1 и user2
одновременно делают update:


Оба разработчикавносят изменения
в main.cpp

Затем user2 commit’ит
свои изменения


commit user1 не удастся,
так как есть конфликт

Поэтому ему придётся сделать
update до последней версии

 

Теперь у user1 есть несколько путей разрешения конфликта:

  • убрать чужие изменения, оставив свои
  • не вносить свои изменения, оставив всё как есть
  • вручную соединить все изменения в одном файле

В последнем случае user1 имеет несколько файлов:

main.cpp – этот файл уйдёт в репозиторий после разрешений конфликта
main.cpp.mine – в этом файле хранятся изменения, сделанные user1
main.cpp.r13 – начальная версия файла без всяких изменений
main.cpp.r14 – файл, попавший в репозиторий (с изменениями user2)

После сведения всех изменений в main.cpp user1 пишет:

SVN позволяет вам также объединить любую версию с любым набором других версий с помощью своих комманд: update и merge

Справку по merge можно прочитать, набрав в консоли команду: svn help merge.

Краткий справочник по командам SVN

Краткий справочник SVN

svn checkout URL . – извлекаем файлы проекта из репозитория, сокращение: svn co

svn update – получаем обновления из репозитория, сокращение: svn up

svn update -r rev_num ./file_name – извлекаем ревизию файла с номером rev_num

svn add ./file_name – добавляем файл в репозиторий

svn commit ./file_name – заливаем файл в репозиторий

svn rename ./old_file_name ./new_file_name – переименовываем файл в репозитории

svn remove ./file_name – удаляем файл/директорию из репозитория

svn delete ./file_name – удаляем файл/директорию из репозитория, сокращение: svn del

svn status – видим локально измененные файлы, сокращение: svn st

svn status -u – видим все измененные файлы, сокращение: svn st -u

svn diff ./file_name – показывает локальные изменения в файле построчно

svn diff -r rev_num1:rev_num2 ./file_name – видим разницу между ревизиями файла

svn revert ./file_name – откатывает локальные изменения файла

svn revert -R ./ – откатывает все локальные изменения файлов

svn log ./file_name – список ревизий с комментариями

svn blame ./file_name – видим авторов правок построчно, синоним: svn annotate

svn propset svn:ignore ./file_name . – добавляем файл в список игнорируемых

svn propset svn:keywords “Id Author Date” ./file_name – установка атрибутов файла

svn cleanup – снимает блокировки с файлов

svn unlock URL/file_name – снять блокировку файла

svn info – узнать в какой ветке находимся сейчас

svn info ./file_name | grep URL – узнать URL файла

svn lock URL/file_name – установить блокировку файла

svn help command_name – выводит помощь по команде

svnadmin setlog –bypass-hooks /path/to/repository -r rev_num ./path/to/file – заменяет текстовое описание коммита, где rev_num – номер ревизии

svn merge -r rev_err:rev_ok ./file_name – откатываем ревизию номер rev_err до ревизии rev_ok, причем все изменения старше rev_err сохраняются

svn copy URL/trunk/ URL/branches/new_branch/ -m”comment” – копирует ветку trunk в ветку new_branch

svn merge -r rev_num1:rev_num2 URL/trunk/ – объединяет ревизию 1 с ревизией 2 из ветки trunk. Все изменения делаются в текущей папке.

svn merge –dry-run -r rev_num1:rev_num2 URL/trunk/ – проверяет, что будет изменено при объединении ревизий. Все изменения делаются в текущей папке.

Как работать с ветками

Как работать с ветками

Создать новую ветку очень просто. Делается это командой copy. Допустим, мы разрабатываем некий проект — BUMP. Тогда для создания ветки my-branch нужно выполнить такую команду:

svn copy https://svnserver/var/bump/trunk https://svnserver/var/bump/branches/my-branch -m="Creating a private branch of /bump/trunk"

Для того, чтобы переключиться в новую ветку:
svn switch svn://svnserver/var/bump/branches/my-branch

Для того, чтобы проверить в какой ветке находимся сейчас:
svn info

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

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

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

Команда merge, наверное, самая сложная из команд SVN. И все дело в том, что некоторые старые версии SVN могут не помнить о раннее выполненных объединениях. А раз не помнят, значит вы рискуете повторно скопировать в проект изменения, которые уже у вас есть после предыдущего объединения.

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

То есть, например так: «merged from trunk r1234:1256». Этот комментарий будет служить вам памяткой, и вы в любой момент сможете посмотреть, когда вы последний раз объединялись, и какая ревизия является последней. Такие комментарии нужно включать обязательно, иначе, могут возникнуть непонятные проблемы и нестыковки.

И еще. Для того, чтобы быть уверенным, что все объединилось удачно, можно сначала (перед реальным копированием) сделать проверочное копирование. Для этого используется параметр –dry-run, который только показывает вывод, не внося изменений в рабочую копию.

Итак, посмотреть изменения из trunk можно такой командой:
svn merge -r4106:HEAD svn://svnserver/var/bump/trunk ./ --dry-run

Получаем, например, такой вывод:

--- Merging r4107 into '.': U db/queries.txt U ejb/src/main/java/ru/bump/action/folder/MoveFolderActionLocal.java U ejb/src/main/java/ru/bump/action/user/UserRegistrationAction.java

Это означает, что в ревизии r4107 изменилось 3 файла. Отлично, все правильно, копируем изменения:
svn merge -r4106:HEAD svn://svnserver/var/bump/trunk ./

И выполняем commit:
svn ci -m "merged from trunk r4106:4108"

Число 4108- это номер текущей ревизии. Получить его просто. Достаточно выполнить команду svn up.

Заметьте, что число 4106, в этом случае, это ревизия создания нашей ветки. Когда вы будете первый раз объединяться, вам нужно будет узнать номер этой ревизии. Это легко, достаточно выполнить команду

svn log --stop-on-copy

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

Например так:
svn log | grep "merged from trunk r4106:4108"

Таким образом, чтобы объединить еще раз из trunk нужно выполнить команду:
svn merge -r4109:HEAD svn://svnserver/var/bump/trunk ./

Пример типичной сессии на SVN

Пример типичной сессии на SVN

1. Выполняем команды:

2. Вносим правки в проект, редактируем файлы и/или выполняем команды:

3. Заливаем изменения в проект:
svn commit  -m "ваш комментарий"

© Копировать пост можно лишь при наличии прямой индексируемой ссылки на youinf.ru

  

 

1 Комментарий

  1. I was reading through some of your content on this internet site and I conceive this site is rattling instructive!
    Keep on putting up.

    Голосовать: Thumb up 0 Thumb down 0

Оставьте Комментарий

 



 

Comment Spam Protection by WP-SpamFree

Trackbacks

 
 

Яндекс цитирования