how to: Как и зачем работать с svn через git

в 12:21, , рубрики: Git, svn, wapstart, Блог компании WapStart, велосипед, Системы управления версиями, метки: , , ,

Добрый день!

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

SVN

Subversion — это централизованная система контроля версий. Это главный ее минус и главный ее плюс :)

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

Главный минус — это merge… Те, кто часто делает мерж средствами svn, понимает о чем я.
Это медленно (даже меееееееедлееенно), требует постоянного соединения с репозиторием, а еще эти svn-properties, которые мешают читать diff.

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

Причин тому несколько, и все они обусловлены наследием. Если бы мы начинали разработку сейчас, то скорей бы всего выбрали git. У нас репозиторию уже около шести лет, за это время мы создали в нем 129 проектов, а число ревизий перевалило за 88 000.
Мы используем trac в качестве багтрекера. В нем сейчас более 10 тыс тикетов. Во многих есть ссылки на коммиты, подтверждающие исправления. Это богатое наследие терять не хочется.
Так же у svn есть плюс — все проекты лежат в одном репозитории. Trac думает, что проект у нас один, что сильно облегчает работу с ним.
Другими словами, отказ от svn для нас слишком затратен, но мержи...

Решение

Пусть внутри репозитория будет svn, но все желающие будут работать с ним через git. Let's do it!

  • Устанавливаем git и git-svn. Метод установки зависит от вашей операционной системы. В моем случае сводится к простому набору команд:
    apt-get update && apt-get install subversion git git-svn
    

  • Создаем приятный к использованию ~/.gitconfig
    [user]
     email = e.kokovikhin@co.wapstart.ru
     name = Evgeniy V. Kokovikhin
    [core]
     editor = vim
    [alias]
     co = checkout
     br = branch
     ci = commit
     st = status
     di = diff --color
    

  • Клонируем svn репозиторий:
    cd /var/www/project.wapstart/ 
    mkdir project && cd project # создали папку для проекта
    git svn init --stdlayout https:/path.to.your.svn.server.ru/project # создаст пустой git репозиторий
    git svn fetch
    

    Последняя команда займет ощутимое время. На нашем репозитории — часа 4.
    --stdlayout как бы говорит нам, что расположение проекта у нас стандартное:

    project
    ├── trunk
    ├── branches
    │    ├── dovgFeature
    │    └── dovgAnotheFeature
    └── tags
         ├── 3.0.1
         └── 3.0.2
    

Собственно все.

Транк теперь называется master, все остальные бранчи именованы как обычно.
Работа с бранчами:

 git branch -r # список бранчей
 git checkout -b dovgBranch dovgBranch # создать новый локальный бранч dovgBranch из удаленного бранча dovgBranch 
 git branch # — список локальных бранчей и отметка текущего

Например:

dovg@marvin ~/job/oemdesign/www/plus1.wapstart.loc/plus1 $ git branch
 dovgUnique
 experimental
* master
 moderation
 production
 referals
 targetingCountry
 uniqueCookie
 uniqueSession
---------

И как теперь с этим работать?

  • Работа с svn
     git svn rebase # обновить текущую ветку (на самом деле не совсем так)
     git svn fetch # обновить весь репозиторий
     git svn dcommit # закоммитить локальные коммиты в svn репозиторий
     git svn branch <branch-name> # создать бранч :) больше информации в git svn help branch
     git svn info # информация о ветке svn, в которую смотрит локальная ветка
    

  • Merge. Ради этого мы и делали все это.
    git merge --log master # смержит все изменения с красивым логом из главной ветки в текущий бранч.
    

    Для мержа в master (trunk)

    git checkout master 
    git merge --no-ff <branch-name> # отмена fast forward merge
    

    Мержи проходят быстро, т.к. не требуют наличие удаленного репозитория. Их больше никто не боится.

  • Основы работы с git
    git diff — аналог
     git commit — закоммитить локально «подготовленный» файл
     git commit -a — закоммитить локально все файлы, которые уже под контролем, но в них были изменения
     git add — подготовить файл к коммиту. Тут есть отличие от svn. В svn надо добавлять только новые файлы, а в git все измененнные, если вы не пользуетесь git commit -a
     git reset --hard — прибить все локальные изменения.
    

Напоследок небольшой FAQ:

  • Сделать бранч и переключится в него: git svn branch ticket-666 && git svn fetch && git co -b ticket-666 ticket-666
  • Перенести бранч в мастер: git co ticket-666 && git merge --log --no-ff master && git svn dcommit && git co master && git merge --log --no-ff ticket-666 && git svn dcommit
  • Сдать бранч в тест (обновить из мастера и закомитить): git co ticket-666 && git merge --log --no-ff master && git svn dcommit
    Обновлять периодически репозиторий: git svn fetch

Вместо заключения

Долгое время эта статья провисела во внутренней вики Wapstart. Мне показалось, что она может быть полезна сообществу. Результат перед вами. ;)

Автор: dovg

Источник

Поделиться

* - обязательные к заполнению поля