Or, as Linus would say, git is just a stupid content tracker.

Что такое Git workflow?

На всех проектах, которые мы разрабатываем как для наших клиентов, так и для себя, мы используем систему контроля версий Git. И, чтобы избавить себя от лишних проблем при командной разработке, держать историю изменений в приятном и удобном виде, применяем оговоренные «алгоритмы» действий, так называемые workflow. Конечно, все рассказанное ниже применимо и для случаев, когда команда состоит и из одного человека.

Суть в том, чтобы упорядочить работу, изначально уменьшить вероятность возникновения конфликтов (полностью это сделать, к сожалению, невозможно), и тратить больше времени непосредственно на разработку, а не размышления, что и как делать, или решения неожиданно возникших проблем с инструментами разработки, а не самим продуктом. На английском языке это очень хорошо описывается словами: reduce (or minimize) the pain and keep nice and clean commit logs.

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

Ни один из приведенных ниже workflow не является нашим ноу-хау. Все найдено на просторах интернета и адаптировано под личные нужды. Ссылки будут в конце поста.

Приступим.

Самый простой workflow.

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


$ git pull

# http://programming-motherfucker.com/
Programming, Motherfucker!

# if some problems appear and you need to fix it and push
$ git stash

# Fix the bug, Motherfucker!

$ git commit -a -m "Sector clear. Problem resolved."

$ git push

$ git stash pop

# http://programming-motherfucker.com/
Programming again, Motherfucker!

$ git commit -a -m "Here I describe what I did"

$ git push

Здесь мы заботимся о чистоте логов меньше всего, не используем ветки для фич и фиксов. А от проблем нас очень даже неплохо спасает git stash. Этот workflow очень напоминает SVN. Увлекаться им не стоит, но до определенного момента он очень даже имеет право на существование. Особенно это касается маленьких проектов, где задействован один, максимум два человека.

Второй уровень просветления


# co = checkout
# st = status

$ git pull

# create feature/bugfix branch, keep master branch clean
$ git co -b branch-name

# http://programming-motherfucker.com/
Programming, Motherfucker!

$ git st
$ git diff

$ git add .

$ git commit -m "Detailed message about changes made"

$ git co master

$ git pull

$ git co branch-name

$ git rebase master
# here you fix conflicts if there are some (in development branch, not in master)
# commit changes again if necessary
#
# if you want to squash smaller commits in development branch
# to one big commit in master
# $ git rebase -i origin/master

$ git co master

$ git merge branch-name

$ git push

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

Merge изменений из удаленного репозитория намеренно вынесен из master branch. Но можно встретить варианты, когда все происходит именно в master, что лишает нас одного уровня безопасности при возникновении проблем, так как процесс разрешения конфликтов может затянуться. Rebase из master также рекомендуется делать регулярно, чтобы ветка сохраняла свою актуальность и возможные конфликты разрешались по мере поступления изменений. А merge делается, когда работа над задачей завершена

В комментариях указана еще одна команда: git rebase -i origin/master. Она позволит перед merge’ем в master объединить все небольшие коммиты в один большой и толстый, если есть такая необходимость. Это может быть полезно в перспективе, так как сохранит лог изменений более привязанным к конкретным задачам, а не мелким этапам их реализации. Очень рекомендуется проделывать это, если ветка сделана под bugfix.

Тэги

По завершении крупных этапов разработки, например, когда происходит очередной крупный выкат обновлений на боевой сервер (deployment to production) часто бывает необходимо отметить этот этап в системе контроля версий. В этом случае помогают тэги: git tag tagname. Очень часто для названия тэга используют номер версии продукта или дату релиза.

Successful Git Branching Model

Следующий этап эволюции в установлении workflow для работы с Git — договоренности по поводу того, какие ветки должны существовать, какие регулярно создаваться и удаляться, и как их всех называть. Ну и конечно, как это все организовать так, чтобы голова не лопнула. Это тот этап, на котором мы сейчас осваиваемся и чем дальше, тем больше довольны результатами. И все благодаря решению.

Решение так и называется: successful Git branching model. Было придумано и воплощено уже давно в одной компании и после обнародования подхвачено еще очень многими.

Опишу вкратце.

Мы договариваемся о том, какой из клонов репозитория у нас является главным (origin). Как правило, это будет репозиторий, хранящийся на github или beanstaklapp, например. Или на вашем собственном сервере. В главном репозитории создается две ветки: master и develop. Ветка origin/master в HEAD содержит в себе код, который всегда отражает состояние уже выложенного в production. Т.е. по определению любые изменения, которые попадают в master считают релизом следующей версии нашего продукта.

Помимо названных двух веток на машинах разработчиков существует три типа других:

  • Feature
  • Release
  • Hotfix

Все ветки названных типов технически ничем не отличаются от master и develop. Отличия состоят в том, как ветки используются. А то, как они используются можно понять из их названий, так как в данном решении названия веток напрямую должны зависеть от того, к какому типу они принадлежат.

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

Feature ветки отделяются от и потом соединяются с только с develop веткой.

Release ветки отделяются от develop, а потом соединяются и с master и с develop.

Hotfix отделяются от master, а соединяются опять же с master и develop, формируя из фикса критической ошибки следующий минорный релиз.

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

В gist собраны очередность команд по работе с каждым видом веток.


# Feature branches

$ git checkout -b myfeature develop

$ git checkout develop
$ git merge --no-ff myfeature
$ git branch -d myfeature
$ git push origin develop

# The --no-ff flag causes the merge to always create a new commit object,
# even if the merge could be performed with a fast-forward.
# This avoids losing information about the historical existence of a
# feature branch and groups together all commits that together added the feature.

# Release branches

$ git checkout -b release-1.2 develop
# changes to bump the version
$ git commit -a -m "Bumped version number to 1.2"

$ git checkout master
$ git merge --no-ff release-1.2
$ git tag -a 1.2

$ git checkout develop
$ git merge --no-ff release-1.2

$ git branch -d release-1.2

# Hotfix branches

$ git checkout -b hotfix-1.2.1 master
# changes to bump the version
$ git commit -a -m "Bumped version number to 1.2.1"
# fix the bug
$ git commit -m "Fixed severe production problem"

$ git checkout master
$ git merge --no-ff hotfix-1.2.1
$ git tag -a 1.2.1

$ git checkout develop
$ git merge --no-ff hotfix-1.2.1

$ git branch -d hotfix-1.2.1

Нирвана

Ну и напоследок для всех постигших дзен successful Git branching model. Ее создатель написал в том числе git flow— расширение для git, которое существенно облегчает жизнь членам секты и тем, кто ленится много печатать.

Расширении сопровождено неплохим описанием по установке и описанию команд, также подробности можно почитать в посте Why aren’t you using git flow в блоге одного из фанатов.

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


$ git flow init

$ git flow feature start login

$ git flow feature finish login

$ git flow release start v0.1.0

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

Спасибо.

Обещанные ссылки на исходные материалы