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

от автора

Добрый день!

В статье я расскажу, как мы работаем с 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. Мне показалось, что она может быть полезна сообществу. Результат перед вами. 😉

ссылка на оригинал статьи http://habrahabr.ru/company/wapstart/blog/159477/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *