Содержание


Организация совместной разработки ПО на базе SVN+DocBook+Mantis

Часть 3. Subversion - работа с версиями проекта

Comments

Серия контента:

Этот контент является частью # из серии # статей: Организация совместной разработки ПО на базе SVN+DocBook+Mantis

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Организация совместной разработки ПО на базе SVN+DocBook+Mantis

Следите за выходом новых статей этой серии.

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

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

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

Что мы хотим получить от системы контроля версий

Первостепенными следует считать две причины:

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

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

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

Подключение к серверу Subversion

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

    $ svn checkout [путь к репозиторию] [путь к каталогу рабочей копии]]

и можно начинать работать.

Ревизии

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

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

Создание рабочей копии

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

  1. Создается новый проект и в хранилище соответственно хранится нулевая ревизия в которой нет ни одного файла.
  2. Рабочая копия создается на основе уже существующего проекта, когда в хранилище уже хранятся файлы проекта.

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

Создание рабочей копии для нового проекта

Сначала обязательно создается рабочая копия на основе нулевой ревизии хранилища, например, команда:

    $svn checkout svn+ssh://alexib@argo/srv/svn/MashGraph ~/svn/mg

создаст рабочую копию в ~/svn/mg. Каталог первоначально будет содержать только папку .svn, которая для нас будет признаком того, что здесь находится рабочая копия. Заметим, что любая рабочая копия (их количество на компьютере ничем не ограничено) привязана всегда к одному конкретному хранилищу. Папу .svn, содержащую служебную информацию модифицировать не рекомендуется.

Далее в рабочей копии создаются (заново или копируются из других папок) рабочие файлы, которые еще не находятся под контролем Subversion и другие участники проекта воспользоваться ими не смогут. Фиксация этих файлов в хранилище так же проводиться не будет. Предположим, что мы создали 4 файла: file1, file2, file3 и file4 в рабочей директории (создали вновь или скопировали из другой директории — не важно). Эти файлы не находятся под контролем системы и в случае фиксации изменений не будут фиксироваться в хранилище.

    $svn status
    ? file1
    ? file2
    ? file3.dcu
    ? file4.bak
    svn commit  -m “Попытка зафиксировать файлы, не находящиеся под контролем“ 
    $svn status
    ? file1
    ? file2
    ? file3.dcu
    ? file4.bak

Как видно ничего не произошло. Как и раньше перед именем файла стоит знак вопроса, что обозначает неподконтрольность файлов.

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

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

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

    $cat ignore.txt
    *.bak
    *.dcu
    *.~*
    svn propset svn:ignore -F ./ignore.txt .

Теперь при проверке статуса рабочей копии будут выводиться только:

    $svn status
    ? file1
    ? file2

Если надо просмотреть список файлов, включая файлы с установленным свойством svn:ignore, то следует воспользоваться командой, которая выведет информацию о всех файлах:

    $svn status --no-ignore
    ? file1
    ? file2
    I file3.dcu
    I file4.bak

Однако пока у нас нет ни одного файла, который поддерживается хранилищем. Для этого их надо добавить командой svn add. Так для файла file1 в текущей директории следует применить команду

    $svn add ./file1
    $svn status
    A file1
    ? file2
    I file3.dcu
    I file4.bak

Аналогично можно добавить и файл file2.

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

    $svn commit –m 'первая фиксация рабочей копии в хранилище'

Только после этого в хранилище проекта появятся данные — file1 и file2, которые вы определили как добавленные к проекту в вашей рабочей копии с помощью команды svn add. До этого момента было только продекларировано ваше намерение добавить их к проекту и информация об этом хранилась исключительно в служебном каталоге .svn. Естественно, что другие участники проекта не могли воспользоваться этими файлами.

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

Создание рабочей копии для существующего проекта

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

Начало создания проекта так же начинается командой

    $svn checkout svn+ssh://alexib@argo/srv/svn/MashGraph ~/svn/mg
    A	file1
    A	file2
    Checked out revision 26.

При этом происходит следующее:

  • клиент Subversion устанавливает связь с сервером ( в нашем случае через SSH-туннель);
  • создается рабочая копия как копия файловой системы из указанного хранилища;
  • создается служебный каталог .svn;
  • выводится информация о файлах, добавленных при создании рабочей копии из хранилища (file1 и file2 с атрибутом A);
  • сообщается о номере ревизии, которая была получена из хранилища.

После получения ревизии из хранилища команда

    $svn status

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

Далее можно работать до следующего сеанса обмена с хранилищем.

ВНИМАНИЕ! Одним из основополагающих принципов Subversion является независимость фиксации изменений в рабочей копии в хранилище и получение изменений, выполненных другими участниками, из хранилища, то есть

  • фиксируя СВОИ изменения в хранилище, вы не получаете ЧУЖИЕ из хранилища;
  • получая ЧУЖИЕ изменения из хранилища, вы не фиксируете СВОИ.

Статус файла

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

  • 1 — показывает статус самого файла или директории;
  • 2 — указывает на изменения в свойствах файла, при этом сам файл может не изменяться вообще;
  • 3 — информирует о блокировке специальной директории .svn;
  • 4 и 5 колонку в рамках данной статьи рассматривать не будем, поскольку они связаны с копированием с историей и созданием веток проектов.

Основные признаки статуса сведены в таблицу:

СтатусОписание
ФайлСвойствоБлокировка
AФайл или директория подготовлен для добавления в хранилище, ранее его там не было и после фиксации он будет добавлен в хранилище. Такой же признак будет и у файлов, которые вы получили из хранилища при создании рабочей копии командой svn checkout.
MФайл уже был добавлен в хранилище, после этого он был модифицирован и изменения в нем еще не зафиксированы командой commit в хранилище. После фиксации признак будет сброшен.
DПосле выполнения команды svn delete <file>, указанный в команде файл удаляется из рабочей директории, но с признаком D выводится командой svn status до фиксации изменений, что говорит, что он еще присутствует в последней ревизии хранилища.
?Subversion видит объект (файл, директорию), еще не управляет им и просит принять решение — управлять им или нет. Пока не выполнена команда svn add или svn propset svn:ignore, знак вопроса будет выводиться командой svn status. С точки зрения системы контроля версий такие объекты ничем не отличаются от объектов с установленным признаком игнорирования, однако это сигнал о том, что появился новый объект и надо принимать решение о его статусе. Такие объекты не фиксируются в хранилище.
IЗдесь уже принято решение об игнорировании Subversion этого объекта, он не виден при стандартном выводе svn status, однако такие объекты можно просмотреть используя svn status —no-ignore. Однако следует помнить, что игнорировать можно только те файлы, которые уже находятся под контролем версий.
UФайлы и директории уже есть в рабочей копии и после получения изменений из хранилища (команда svn update) в них были обнаружены изменения, не конфликтующие с вашей рабочей копией.
CПри получении файла из хранилища обнаружен конфликт между изменениями, зафиксированными в хранилище кем то из других участников проекта и изменениями в вашей рабочей копии (эти изменения еще не были зафиксированы в хранилище).
MВ процессе работы с рабочей копией были произведены изменения в свойствах (имеются в виду именно специфические свойства Subversion), в то же время изменения в самом файле могут отсутствовать вообще при отсутствии признака M в первой позиции.
CSubversion обнаружил конфликт свойств между файлом (директорией) рабочей копии и хранилища. Содержимое при этом идентично. Поскольку позиции 1 и 2 расположены рядом, а никаких заголовков нет, то следует внимательно рассмотреть в какой именно позиции находится признак.
LПоказывает, что у соответствующей директории заблокирована служебная область .svn. На причинах останавливаться в рамках статьи не будем, но проблему надо решать.

Рабочий цикл

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

  • устранению ошибок в проекте;
  • расширение функционала;
  • улучшение интерфейса.

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

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

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

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

Временная отсечкаДействие разработчикаРевизия проекта рабочей копииРевизия проекта в хранилище
1Получение задания100105
2Получение текущей копии из хранилища105105
3Работа над заданием105106
...
4Получение текущей копии из хранилища116116
5Работа над заданием116117
...
6Работа над заданием116125
7Завершение работы116130
8Фиксация изменений в хранилище131131

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

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

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

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

Запуск обновления из каталога рабочей копии

    svn update

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

U file1Updated — обновленФайл file1 есть в вашей рабочей копии, вами не менялся после последнего обмена с хранилищем, он был изменен другим членом команды и зафиксирован им в хранилище.
A file1Added — добавленФайл или директория file1 в вашей рабочей копии еще существовал и был добавлен в рабочую копию из хранилища..
D file1Deleted — удаленФайл или директория file1 были удалены из рабочей копии на основании того, что в хранилище было зафиксировано их удаление другими участниками.
R file1Replaced — замененФайл или директория file1 были заменены в рабочей копии; это значит, что file1 был удален, а новый элемент с таким же именем был добавлен из хранилища. Они могут иметь одинаковое имя, но Subversion рассматривает их как разные объекты с отдельной историей.
G file1merGed — слияниеФайл file1 получил новые изменения из хранилища, однако ваша локальная копия содержит ваши изменения. Либо изменения не пересекаются, либо они точно такие же как ваши локальные изменения поэтому Subversion успешно выполнила слияние изменений, полученных из хранилища с вашими изменениями в файле рабочей копии.
C file1Conflicting — конфликтующие измененияФайл file1 получил от сервера изменения, которые пересекаются с вашими изменениями файла. Эта ситуация требует разрешения человеком.

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

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

Среди участников проекта обязательно должны быть приняты правила разрешения конфликта:

  • кого участник, получивший конфликтный файл должен поставить в известность;
  • кто должен выступать арбитром (на ком лежит ответственность за разрешение конфликта)

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

Рассмотрим конфликт на конкретном примере. Работают два участника Игорь и Слава. Игорь создал файл menu, зафиксировал его в хранилище, при этом создалась ревизия 9. Слава выполнил команду svn update и получил тоже ревизию 9. Теперь Игорь корректирует файл и меняет текст в начале. Фиксирует изменения и в результате в хранилище — ревизия 10.

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

    $ svn commit -m 'rise'
    Sending        menu
    svn: Commit failed (details follow):
    svn: File '/menu' is out of date

Теперь Слава должен выполнить обновление:

    $ svn update
    G    menu
    Updated to revision 10.

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

Проверка статуса даст результат:

    $svn status
    M       menu

После фиксации файл будет отнесен к ревизии 11. Содержимое файлов приведено в таблице.

menu (ревизия 9)menu (ревизия 10)рабочая копия Славыфайл после слияния (ревизия 11)
завтрак
  1. сыр
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. суп
  4. грибы
  5. макароны
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. гречневая каша
  4. чай
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. суп
  4. грибы
  5. макароны
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. гречневая каша
  4. чай
завтрак
  1. сыр
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. суп
  4. грибы
  5. макароны
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. суп
  4. грибы
  5. макароны
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай

Теперь рассмотрим настоящий конфликт, который подразумевает наличие изменений, которые Subversion не может разрешить самостоятельно. Для примера возьмем тот же файл menu (ревизия 11).

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

                    $ svn update
                    Conflict discovered in 'menu'.
                    Select: (p) postpone, (df) diff-full, (e) edit,
                    (mc) mine-conflict, (tc) theirs-conflict,
                    (s) show all options:

Subversion ожидает ввода одной из предложенных команд, которые позволят:

  • (e) edit - редактировать файл с изменениями
  • (df) diff-full - показать все конфликтующие изменения
  • (r) resolved - принять файл, содержащий маркеры слияния конфликтующих изменений
  • (dc) display-conflict — показать все конфликты
  • (mf) mine-full — принять свою версию и игнорировать полученные изменения
  • (tf) theirs-full — принять полностью полученную версию файла и отказаться от своих изменений
  • (p) postpone - отметить конфликт и разрешить его позднее
  • (l) launch - использовать внешние средства для разрешения конфликта

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

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

  • от <<<<<<< .mine до ======= изменения в нашем случае Славы (он разрешает конфликт);
  • от ======= до >>>>>>> .r12 изменения, зафиксированные в ревизии 12 Игорем.

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

Правка Игоря (ревизия 12)Правка Славыфайл в котором слиты измененияфайл с разрешенным конфликтом
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. борщ
  4. шницель
  5. пюре
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. рассольник
  4. рагу
  5. картофель фри
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
<<<<<<< .mine
  1. рассольник
  2. рагу
  3. картофель фри
=======
  1. борщ
  2. шницель
  3. пюре
>>>>>>> .r12
  1. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай
завтрак
  1. яичница
  2. хлеб
  3. булочка
  4. чай
обед
  1. салат из капусты
  2. хлеб
  3. рассольник
  4. шницель
  5. картофель фри
  6. компот
ужин
  1. салат из моркови
  2. рыба
  3. рис
  4. чай

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


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=550609
ArticleTitle=Организация совместной разработки ПО на базе SVN+DocBook+Mantis: Часть 3. Subversion - работа с версиями проекта
publish-date=10182010