Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

108 lines (65 sloc) 16.178 kb

Используем Git без проблем

Здравствуйте. Меня зовут Сергей Сергеев, я работаю в Яндексе руководителем группы разработки интерфейсов.

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

В последнее время много людей переходят на эту систему, во многом благодаря популярности github. Многие из нас давно пользуются централизованными системами контроля версий, например SVN (CVS) и при переходе на децентрализованные, в частности git, у нас возникает больше проблем, чем у людей начинающих свою работу сразу с DSVC.

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

Итак начнём.

DVCS

If you are using Subversion, stop it. Just stop. Subversion = Leeches. Mercurial and Git = Antibiotics. We have better technology now.

Каждый раз начиная какой-либо рассказ о git я привожу этут цитату Джоэля Спольски, не могу не показать её и сейчас. Мы действительно уже имеем инструменты лучше, чем раньше, давайте ими пользоваться.

Но продолжим с советами, самый первый из них…

RTFM

Да, как бы нибыло это смешно или «заезжено», но опытные разработчики часто игнорируют это правило. Почему-то если дело касается инструментов, то ими сначала начинают пользоваться, а потом читают мануал. Разработчики, долгое время использующие svn, первым делам ищут мануал по запросу «svn git» первым результатом находят соответствие команд, после чего решают — git≈svn, что на самом деле не верно, поэтому копайте глубже, прочтите не только соответствие командам, но и особенности системы, способы её работы и т.д.

Давайте поговорим про особенности.

DVCS

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

Например, для того что бы синхронизировать свой репозиторий с удалённым можно вызвать git fetch, что не отразиться на вашей текущей копии кода. Для того что бы синхронизировать текущий код (ветку) мы обычно делаем git pull, что на самом деле эквивалентно запуску двух команд git fetch && git merge origin/master.

Для разработчиков переходящих с svn не всегда понятен процесс git pull — мы вытягиваем удалённую ветку и мерджим её с локальной, поэтому я рекомендую использовать параметр --rebase, что избавит историю от «лишних» сливаний и не даст повода для лишних вопросов новичкам. Что бы не указывать этот параметр постоянно есть опция для gitconfig'а — всегда делать rebase на ветке при push'е

git config branch.master.rebase true

Для push'а своих изменений в удалённую ветку используется команда git push, но как я и говорил ранее git по умолчанию синхронизирует весь репозиторий, а значит и все ветки. Это поведение может оказаться неожиданным для пользователей svn, поэтому можно делать push только своей ветки, а если не хочется делать это каждый раз, то нужно прописать параметр в .gitconfig'е

git config --global push.default tracking

Работа с Git — работа с графом истории

После работы с svn я долгое время не мог «въехать» в git, было много не понятной для меня «магии», собирая по различным мануалам знания я стал более-менее понимать, что происходит при определённых действиях. Но вот однажды я забрёл на сайт think like (a) git, где показывается, что работа с git — это работа с графом его истории, после чего многое стало понятно и очевидно (но это ведь я уже подготовился ;))

Давайте с этим разберёмся чуть подробнее.

Думаю в зале есть программисты? :) (другие тоже должны понять абстракцию, хотя бы попробовать)

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

Давайте рассмотри структуру коммита в git

структура коммита

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

То есть по сути коммит — это простая структура с указателями, и сам он является элементом однонаправленного списка. Заметьте, что коммит не хранит изменения файлов (я был свидетелем «уличной магии» некоторых пользователей git'а, которые своими действиями могли изменить состояние дерева при этом не «показывая» diff между файлами — это можно сделать изменяя состояние дерева в коммите).

Но не будем сейчас углубляться в дебри — давайте рассмотрим как упрощённо выглядит структура истории в git'е

ветки — указатели (ссылки) на конкретный коммит

Как видно из рисунка — каждый коммит указывает на своего родителя, а ветки указывают на текущий коммит. Ветки в git'е — это указатели, указатели на текущий коммит, не более (именно поэтому ветки в git'е достаточно «дешёвые») Работа в git'е с ветками сводится к работе над списком с перемещением указателей на коммиты, а merge веток — создаёт новый коммит и сдвигает ссылки на него.

Детальнее попрактиоваться можно самим, главное понять, что работа с git — это работа с графом изменений.

reset or not reset

Одной из возможностей двигать указатели в git — это reset. Его возможности довольно широки и их описание займёт гораздо больше времени, так что я «считерю» и дам вам ссылку на большую статью.

Сам reset, в зависимости от параметров, влияет на состояние рабочей копии, состояние индекса или состояние ветки. Многие пользователи путают его применения с git checkout для восстановления состояния контретного файла, поэтому пользоваться reset'ом нужно понимая что именно он делает и ни в коем случае не путать его с svn revert.

Забудьте про rebase (на время)

Все кто приходит к git в своё время сталкиваются с возможностью изменения истории работы с помощью rebase. Rebase сулит чистую историю и больший контроль над ней. Но, т.к. разработчики либо не выполняют мой первый совет, либо выполняют его лишь частично, возникает много проблем связанных с непониманием как работает эта команда и что именно она делает.

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

cherry-pick только для «мертвых» веток

Ещё один хороший инструмент который получает к себе в арсенал разработчики при использовании git'а — git cherry-pick. Эта команда более низкоуровневая — она позволяет скопировать коммит из одной ветки в другую — так это выглядет для пользователя.

Но на самом деле cherry-pick берёт изменения (diff) указанного коммита по отношению к родителю и накладывает эти изменения на текущую ветку. Отсюда вытекает особенность — при дальнейшем слиянии ветки из которой мы взяли коммит мы можем получить конфликты.

Нужно так же помнить, что в отличии от интеллектуального merge'а cherry-pick не гарантирует наличие предыдущей функциональности, что может привести к нерабочему коду.

merge, git merge

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

Мой совет — забудьте на время об алгоритмах слияния, дайте git'у делать работу за вас, используя просто merge вы понимаете что произойдёт после слияния двух веток, ну а если вам и правда нужно управлять алгоритамим, то для этого в git есть возможности, главное понимайте как они работают ;)

What's been pushed, shouldn't be rebased

Если вы всё-таки добрались до git rebase (это ведь случиться рано или поздно) постарайтесь запомнить правило на слайде — никогда, никогда не переписывайте историю веток, которые отправляете в апстрим (сервер синхронизации), потому что пользователи вашей ветки будут очень огорчены тем, что у них расходится история и не применяются патчи.

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

Ваш собственный workflow

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

Как пример я приведу удачный и документированный workflow работы с репозиторием.

В вашей команде он может отличаться, но он должен быть!

RTFM

В конце я предлагаю вам маленький набор ссылок, который помог мне и многим ребятам понять git и освоить комфортную работу в нём, дабы вы могли реализовать мой первый совет ;)

руководитель группы разработки интерфейсов

Меня по прежнему зовут Сергей Сергеев и я готов ответить на ваши вопросы.

Jump to Line
Something went wrong with that request. Please try again.