Пользователь
0,0
рейтинг
21 ноября 2008 в 14:55

Разработка → Работа с ветками SVN

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

После того как вы прочли статью о ветках в svnbook, вы уже понимаете для чего нужны ветки, как с ними работать и в каких случаях их необходимо использовать. В принципе, после этого, то, что написано под катом вам уже скорее всего не нужно. Но если вам было лень читать, то может текст ниже вас заинтересует, и вы все таки прочтете статью документации. А может, просто поможет вам лучше понять то, что только что прочли в svnbook-е.

Для чего все это?

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

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

Что такое ветка?

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

* trunk — основная линия разработки. Здесь будет актуальный на данный момент код, здесь будут выполняться мелкие задачи и правки багов.
* branches — ветка для разработчиков. гсуто ветвится другими ветками. Именно в ней вы будете создавать свои ветки.
* tags — ветка тэгов. Тут создаются всякие метки, отмечающие значимые вехи развития проектов, проще говоря его стабильные и не очень версии. Нужна она для того, что бы всегда можно было вернуться до какой нибудь версии, например что бы посмотреть «почему эта хрень раньше работала а потом перестала, сцуко»

Программисты отвечают за то, что бы

* Создать ветку тогда когда это нужно для стабильного существования проекта. В общем случае если вы чувствуете что задача будет длиться больше пары дней (а иногда и дня), и все это время вы не сможете безболезненно коммититься хотя бы пару раз в день, вам нужна ветка.
* Поддерживать свою ветку в актуальном состоянии — то есть необходимо избавиться от панического страха перед командой merge как можно раньше, и мержить не реже чем комитишь. Иначе конфликтов при сливании ветки с транком не избежать.
* Удалить ветку после завершения задачи. Ветки разработчиков — временные ветки, поэтому они должны удаляться, когда задача завершена. В крайнем случае, они могут пожить еще несколько дней, для уверенности, что в задаче нет больших ошибок. Дальше ветка никому нужна не будет, её можно удалять. Все равно, через некоторое время, она так далеко отойдет от основной линии разработки, что уже никакой мердж не сможет ей вернуть актуальность.

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

Создать новую ветку очень просто. Как следует из талмуда, делается это командой copy. Допустим, мы разрабатываем некий проект — BUMP (Большой Афигенный Мега Проект). Для нашего случая, нужно выполнить такую команду:

svn copy svn://svnserver/var/bump/trunk svn://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

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

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

Для того что бы держать свою ветку в актуальном состоянии, вам необходимо периодически копировать изменения из основной ветки. Это необходимо для того, что бы избежать конфликтов при слиянии веток или при переключении в основную ветку. Поэтому мержится нужно почаще, хотя бы раз-два за день. Можно взять за правило: мержиться перед каждым коммитом. Команада merge, наверное, самая сложная из команд svn. И все дело в том, что svn не помнит о ваших предыдущих мержах (до версии 1.5). А раз не помнит, значит вы рискуете скопировать себе изменения, которые уже у вас есть, после предыдущего мержа. Но этот недостаток легко обойти. После каждого копирования изменений себе в рабочую копию, вам необходимо закомитить их в свою ветку. В комментарии укажите диапазон ревизий, включенных в ваш текущий мерж. То есть например так: «merged from trunk r1234:1256». Этот комментарий будет служить вам памяткой, и вы в любой момент сможете посмотреть когда вы последний раз мержились и какая ревизия является последней. Такие комментарии включать обязательно, иначе, будут большие проблемы и непонятки. И еще. Для того что бы быть уверенным что все смержится удачно, можно сначала, перед реальным копированием, сделать проверочное. Для этого используется параметр --dry-run который только показывает вывод, не внося изменений в рабочую копию.

Итак, посомтреть изменения из транка можно такой командой:

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 ./

И комитимся:

svn ci -m "merged from trunk r4106:4108"

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

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

svn log --stop-on-copy

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

#:~/www/bump$ svn log | grep merged
merged from trunk r4106:4108


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

svn merge -r4109:HEAD svn://svnserver/var/bump/trunk ./

Завершение работы над задачей

Если работа над задачей завершена, вам нужно

* Слить свои изменения в транк
* Удалить свою ветку что бы не мешалась

Сливаем в транк той же командой merge. Для этого выясняем ревизию создания ветки, и свитчимся в транк.

svn switch svn://svnserver/var/bump/trunk

После этого копируем изменения из своей ветки

#svn up
At revision 4155

#svn merge svn://svnserver/var/bump/trunk@4155 svn://svnserver/var/bump/branches/my-branch@4155


Если все прошло нормально, нет никаких конфликтов и доделать ничего не нужно, комитим изменения в основную ветку, а свою ветку можно теперь удалить. Она совсем не отличается от транка, и в случае надобности мы всегда сможем создать еще одну ветку. Да и стоит помнить что наша ветка конечно же не удаляется физически, просто она удаляется из HEAD, но в ранних ревизиях мы всегда сможем её отыскать, и при необходимости востановить. Так что смелее:

svn delete svn://svnserver/var/bump/branches/my-btanch -m "Removing my-branch branch."

Между прочим, удаление ветки, после слития задачи в транк, не строго обязательно. Удаление ветки обязательно при завршении задачи, а слитие в транк вовсе не означает что задача полностью завершена. Теоретически сливать свои изменения (как полностью так и частично) вы можете и несколько раз в течении работы над задачей, например, если задача разбита на этапы, каждый из которых является законченным и работоспособным. Или, например изменения которые вы сделали нужны (или могут пригодиться) другим разработчикам, но при этом не мешают работе всего приложения (новая либа, или дополнения к интерфейсу существующих либ и классов). Вообщем, решение об мёрже своих изменений в транк должен принимать программист (или группа) — владелец ветки. Что конечно не исключает варианта с кем нибудь посоветоваться в случае если есть сомнения.

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

Заключение

В этой статье содержится лишь малая часть сведений о работе с ветками. Она может служить как памятка, но не как самоучитель. Поэтому настоятельно рекомендуется прочесть соответствующий раздел svnbook. В нем содержится множество сведений которые не попали в этот опус, но необходимы для понимания того как работать с ветками.
RVK @RVK
карма
102,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (72)

  • +3
    спасибо! подчерпнул для себя новое!
    • +2
      Пожалуйста)))
  • +1
    ветки в svn довольно унылы, потому что по сути являются просто каталогами по соседству. merge tracking в svn 1.5 кое-как исправляет ситуацию, но все равно с mercurial (могу говорить только за него, git не пробовал) не сравнить.
    • +4
      Но таки свои функции они выполняют. Кстати то что ветка является просто директорией это не недостаток а фишка SVN
      • 0
        Есть неприятный эффект, что приходится как-то искуственно запоминать, с какой ревизии в прошлый раз смерджились.
        • 0
          Быстро привыкаешь и потом проблем не вызывает.
        • –2
          А почему-бы не отмечать в логах? Что бы не запоминать. Потом svn-log… и траляля
          • +2
            Перед занесением в лог надо ещё разрулить конфликты (которых в большом проекте может быть на пару дней), посидеть в интернете, выпить кофе, поддержать пользователей, проинтервьюировать очередного кандидата — тут, глядишь, и заново merge делать пора.
          • +1
            Похоже статья не прочитана. В ней об этом есть
        • +2
          В 1.5 уже не приходится.
        • +1
          Я всегда в тексте комита пишу номер ревизии, весьма информативно и удобно.
          • 0
            И это верно
          • 0
            А какой в этом глубокий смысл? Везде, где встречается такая сущность, как конкретная ревизия, мы можем лицезреть ее номер. Или я не прав?
            • 0
              До 1.5 нет точно, в логох у вас будет просто диф файлов, обычный апдейт, команда svn merge никак не залогирует номер ревизии.
        • 0
          У вас svn 1.5 запретили пользоваться?
          • 0
            Упс, простите, уже было
    • +5
      Каждый раз в каждом топике про SVN найдётся какой нить умник и скажет что SVN дерьмо, а GIT это супер пупер. Вас что заставляют читать эти топики и писать унылые коменты?
      • +1
        я был бы рад если бы мне расказали о git в тот момент когда внедрялся svn
      • –2
        ну как бы эта ситуация должна наводить на размышления тогда.

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

        п.с. а mergeinfo в file properties — это просто прелесть какое элегантное решение.
        • 0
          Отнюдь, вы думаете если каждый человек будет так просто отписывать разные мелкие коменты из трёх строк желающих прибавиться? Сомневаюсь, надо доносить своё мнение более аргументированно.
    • 0
      В Mercurial одного не хватает — хорошего GUI под Windows. Имхо, популярность SVN связана не в последнюю очередь именно с TortoiseSVN.
      TortoiseHg пока, увы, весьма неудобен и неповоротлив.
      • 0
        ну не TortoiseHg единым… хотя и он, версии 0.5, очень даже ничего. меркуриал удобно использовать и из комстроки. hg commit, hg status, hg add и т.д. — not a rocket science, как говорится. также меркуриал отлично поддерживается в NetBeans, и неплохо — в KomodoIDE.
        • 0
          TortoiseHg показывает полный diff в логе, а если коммит очень большой — он практически подвисает… По удобству не сравнить с TortoiseMerge и TortoiseBlame (хотя ничто не мешает использовать их — может быть, это сделают в дальнейшем). Похоже, одной из проблем стало отсутствие C-библиотеки для работы с Mercurial.
          Ну да, из комстроки можно, но привыкнув к TortoiseSVN, visual diff и прочим удобствам, переходить на командную строку не очень хочется.
  • +5
    Начиная с SVN 1.5 версии появились разнообразные приятности.
    Мне кажется, рассказ о ветках в SVN'е неполон без их упоминания и описания.
    • –1
      Я как то привык работать по старинке. Но это повод для знающих написать новую статью ;)
    • +2
      • +2
        Так эта… того… так весь хабр можно одной ссылкой выразить. Хочется ж простого щастья — чтобы кто-нибудь прочитал, понял и разжевал.
        • 0
          Не, это я не в том смысле, что «юзай гугл уже», а я тоже не знал :)
  • 0
    Только что этим занимался )
  • +1
    Хорошая статейка. Талмут по ссылке обязательно читну.
    В букмарки!
  • 0
    Пишу по версии 1.5 статейку.
  • –5
    Спасибо! Почитал и понял что правильно сижу на SourceSafe :-)
    • 0
      О боже…
      • –1
        Зависть — плохое чувство.
        • 0
          Дело в том что я пользовался этой штукой года 4 назад. Геморой в памяти остался до сих пор. Как таковую командную разработку с этой системой вести нереально. Принцип общего владения кодом соблюдать невозможно. Но я не исключаю что за 4 года что-то сильно поменялось, так что если хотите доказать приемущества — ждем статью.
          • –3
            Вы не пользуетесь Visual Studio?

            SourceSafe это практически единственное чем пользуются в большинстве своём все разработчики со времён ещё VS 6.0
            • 0
              я не пользуюсь VS хотя бы по причине того что в качестве OS и дома и на работе у меня Linux

              Но даже когда пользовался VSS писал я на Delphi
              • –1
                Ну тогда понятно. А мы с VS с 2000-го года и никаких неудобств при использовании SourceSafe не замечал, наоборот — уже в 2000м году мне в нём было удобно и понятно, всё интегрировано в среду разработки.

                Не знаю за что я схлопотал минусов, видимо тоже от линуксоидов которые не пробовали.
                • 0
                  Может наоборот от тех кто пробовал? ;)
                  Дело то в том что у двух систем разная философия, и главное отличие в том что в VSS необходимо блокировать файлы над которыми ты сейчас работаешь. Это означает что никто другой их править не сможет. Это порождает множетсво неудобст, начиная от невозможности делать одну и ту-же задачу в команде, и заканчивая неудобствами связанными с необходимостью переговоров при внесении изменений в файл который держит другой человек. Он должен понять что ты собрался сделать, отпустить файл, подождать пока ты внесешь изменинея и отпустишь файл в свою очередь, потом опять залочить.
                  В SVN же ничего блокировать не надо, и можно не заботиться об этом. Каждый может менять любые файлы которые заблагорассудится. При этом это безопасно.
                  • 0
                    Не обязательно блокировать эксклюзивно, Всегда в настройках репозитория VSS можно указать опцию allow multiple checkouts.

                    Вообще, VStudio + VSourceSafe — это очень удобно в работе.

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

                    SVN гораздо в этом плане надёжнее и приятнее, и к енму тоже можно докупить VS SCC-плагин для интеграции с VS.
            • +1
              Я пользуюсь Visual Studio уже 7 лет. VSS трогал последний раз к своему превеликому счастью 4 года назад. До сих пор содрогаюсь впоминая это поделие.
              • –1
                А как вы работаетет то я тогда не понял? Через проводник — бегаете по каталогам, Commit Update жмёте?

                Для нас это неприемлимо — у нас 3000 файлов в проекте
                • 0
                  Удивительно, да, но с учетом того что я работаю в idea, в котором есть замечательный плагин для работы с svn, GUI и все дела, пользуюсь я исключительно командной строкой. Скажете я извращенец, но я так привык. А файлов в проекте не многим меньше.
                  Притом что в случае с SVN количество файлов вообще неважно. Это в VSS надо бегать по каталогам и файлы лочить/разлочивать по одному. В SVN очень редко необходимо комитить 1 файл. Обычно ниже корня спускаться не приходится.

                  Так что в случае если у вас в проекте 3000 файлов, вам тем более пора отказаться от VSS.
                • 0
                  И стоит обратить наверное внимание на этот коммент)))
                  habrahabr.ru/blogs/development_tools/45203/#comment_1143897

                  P.S. Эх, вдруг удастся спасти заблудшую душу)))
                  • 0
                    Не удастся, у нас это корпоративный стандарт. :-)

                    А почтовый клиент у нас MS Outlook :-) И там всё-всё-всё, от контактов до календаря и планировщика заданий.
                    • 0
                      Зря расcказал… теперь в кошмарах сниться будет…
                      Компания не МВ случайно?
                      • 0
                        Нет :-) Обычный такой разработчик небольшой российской ERP системы с двумя десятками программистов.
                        • 0
                          Вот вот. Там я тоже ERP разрабатывал)))
                • +1
                  Не всё ли равно, сколько файлов в проекте? Commit, Update, Check for modifications делаются для корневого каталога и всё.

                  Да, поддержка SCM на уровне студии приятная штука конечно, но практика показывает, что это не более, чем приятная штука, и не может быть решающим критерием при выборе системы.
            • +1
              VisualSVN — плагин к Visual Studio, полностью интегрирует TortoiseSVN в оболочку Visual Studio. Но при этом есть возможность выполнять все действия и из проводника/командной строки.

              А о слабости SourceSafe как системы управления версиями говорит хотя бы отсутствие транзакционного коммита.
              • +1
                Да.
  • 0
    Если вы переодически мёржитесь с транка, то для реинтеграции ветки в транк нельзя копировать изменения в своей ветке, т. к. они включают в себя мёржи с транка. Вместо этого нужно наложить на транк разницу между транком и веткой, как советуют в документации.
  • –1
    Мир не стоит на месте, развивайтесь, попробуйте Git.
  • –1
    А зачем ещё писать о SVN O_o :D
    • 0
      Было бы неплохо если бы каждый кто тут продвигает свою систему расказал бы о ней. А так, языком трепать конечно легко. Докажите статьей чем ваша система лучше SVN. Между прочим очень хотел бы послушать про VSS. Юзал её 4 года назад, после неё SVN это сказка. Но вдруг за это время многое изменилось. Хотя у VSS совсем другая концепция изначально худшая и устаревшая. Но вдруг…
      • 0
        сори этот ответ нетуда)))
  • –1
    Чем запоминать ревизии, или смотреть по логам, имхо гораздо проще делать 2 копии:
    svn cp trunk branch--base
    svn cp branch--base branch
    svn co branch
    работаем в бранче

    легко посмотреть внесенные самим изминения
    svn diff branch{--base,}

    если сливаться с транком:
    svn co trunk trunk--to--merge
    svn merge branch{--base,} trunk--to--merge // лучше посмотреть насколько удачно слилось
    svn ci

    если хотим изминения из транка, то создадим еще пару бранчей и перенесем изминения из текущего
    svn cp trunk branch2--base
    svn cp branch2--base branch2
    svn co branch2
    svn merge branch{--base,} branch2
    работаем дальше в branch2

    ненужные бранчи предпочитаю сносить в архив, но можно и удалять

    • 0
      ужас… не проще ли просто один коммент в логе?
      • 0
        Для меня не проще, к тому же описанное очень просто скриптуется. Собственно, все вышеописанное и завернуто в несколькострочные баш скрипты.
        А вот смотреть каждый раз ревизию от которой отпочкавался, имхо сильно не удобно.
        А в комменты лучше писать о том что меняется в коде.
  • 0
    Было бы неплохо если бы каждый кто тут продвигает свою систему расказал бы о ней. А так, языком трепать конечно легко. Докажите статьей чем ваша система лучше SVN. Между прочим очень хотел бы послушать про VSS. Юзал её 4 года назад, после неё SVN это сказка. Но вдруг за это время многое изменилось. Хотя у VSS совсем другая концепция изначально худшая и устаревшая. Но вдруг…
    • –1
      Сначала исправьте логическую ошибку, о которой я писал выше, дабы не вводить читателей в заблуждение.
      • 0
        Ага, ошибся)))
  • 0
    Вчера попытался «смержить» в ветку изменения из основного дерева, не получилось — выдал ошибку «Malformed URL for repository». Всё проклял. Решил, что руки растут не из того места.
    Суббота началась с чтения SVN Book (http://svnbook.red-bean.com/nightly/ru/svn.branchmerge.whatis.html), благо русская версия там есть (не то, чтобы я английский не знал, но решил, что что-то не понимаю).
    Спустя пару часов понял, что ещё вчера верно уловил суть. Задумался о версии Tortoise SVN (у меня она 1.5.0), обновил до 1.5.5 — всё заработало. :)
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Самое интересное что у меня на работе, клиент (обычный из командной строки, так привык) 1.5.1 но сервер версии 1.4 и они прекрасно работают вместе, только новые фичи не поддерживаются.
      • –1
        А как понять, работает ли merge tracking или нет? TortoiseSVN по-прежнему не показывает слияние веток на графике…
        • 0
          Как это сделать с помощью TortoiseSVN не знаю, не пользуюсь им года два. Из командной строки проверить можно просто выполнив svn merge svn://rvk1.firstvds.ru/trunk --dry-run и посмотреть какие ревизии svn будет копировать

          А проще всего узнать версию сервера, например у админа ;) Если 1.5.х то поддерживает
    • +1
      Для интеграции со студией можно попробовать вот это ankhsvn.open.collab.net/, чтобы все работало нормально на машине должен стоять TortoiseSVN. Сервер под винды visualsvn.com/. У меня это нормально работает вместе.
    • 0
      сервер — обычный SVN.

      Клиентская часть:
      www.pushok.com/soft_svn.php
  • 0
    Как обещал написал продолжение
    habrahabr.ru/blogs/development_tools/45222/
  • НЛО прилетело и опубликовало эту надпись здесь

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