Git fork. Зачем нужны форки и как с ними работать
Как и в случае с ребейзом, с форками в гите я разобрался не сразу. Вроде ничего особенного там нет, это просто копия репозитория, но натыкаешься на какие-то подводные камни и не сразу понимаешь, как их обойти. Да и вообще, зачем нужны эти форки, тоже осознаешь не сразу. Когда врубаешься, все становится просто, ну это как всегда.
Я не сторонник подхода "чо тут не понимать, тупой штоле" и попробую рассказать человеческими словами, что вообще такое форки, зачем они нужны и как с ними работать. А вы оцените, как получилось. Синьор git девелоперам статья покажется банальщиной, но тем, кто еще не успел обрести такой титул, будет полезно.
Начнем с примера.
Ты работаешь в компании Company в какой-то команде и со своими ребятами пишешь код, например, блога вашего сайта. Рядом сидят ребята из другой команды, которые занимаются админкой. У каждой команды отдельный репозиторий, вы работаете и друг другу не мешаете.
Вам приходит задача - дать возможность разрешать или запрещать комментировать статьи блога отдельным пользователям. Сами вы это сделать не можете. Такие данные о пользователях хранятся не на вашей стороне, а у ребят, занимающихся админкой. У них есть списки пользователей и все данные по ним. А вы тянете эти данные по апи. Прямо микросервисы, все как положено.
Доступа к их репозиторию нет, поэтому идете договариваться. Обсуждаете вместе детали. Так, нужно завести поле в базе, какое-нибудь булево isAllowedComments, соответственно, подготовить миграцию, вывести это поле отдельной колонкой в таблице пользователей, там поставить чекбокс и уметь сохранять это в базу. А еще в апи, которое вы дергаете, нужно добавить в респонсе это самое поле. Вроде немного, ребята говорят, окей, через пару дней сделаем. И на самом деле делают, все хорошо.
Небольшие просьбы вроде этой появляются все чаще. То вам нужно накатить миграцию и разбанить всех пользователей, которые зарегались больше года назад. То в апи в респонсе вам понадобилось количество комментов пользователя. И каждый раз вы идете с такой мелочью к соседям и просите это сделать.
Рано или поздно ребятам из админки это надоедает, потому что у них хватает и своей работы. Они предлагают вам дать права на репозиторий и пробовать такие небольшие задачи делать самим. Говорят, мол, с такой фигней типа добавления поля в респонс вы и сами справитесь. Если что, зовите, поможем. Прав на пуш в мастер, конечно, никто не даст, но свои ветки создавайте и присылайте мердж-реквесты. Мы смотрим, если все хорошо, то мерджим в мастер и выкладываем в прод. Все довольны. И нам работы меньше, и вам не ждать, пока у нас руки дойдут до вашей задачи.
Вы с командой соглашаетесь. Ты клонируешь их репозиторий и пилишь фичи. Примерно так
git clone git@bitbucket.org:company/adminka.git cd adminka git checkout -b vasya/blog-comments ... git commit -m 'Added isAllowedComments for users' git push origin vasya/blog-comments
Дальше идешь в битбакеты-гитхабы, в репозиторий админки, делаешь мердж-реквест и ждешь, когда его примут. Обычная схема. Мердж-реквест примерно везде делается одинаково: ищешь кнопку "Создать мердж-реквест" или пулл-реквест, выбираешь свою ветку, затем выбираешь, куда сливать (обычно уже по умолчанию будет мастер) и жмешь "Отправить".
Проходит пара месяцев. Ты случайно замечаешь в репозитории админки ветку petya/update-email. Спрашиваешь ребят из админки, а что за Петя вам коммитит? Те говорят, а, это чувак из отдела емейлов, мы им тоже доступ дали, как и вам. Они тоже приходили к нам по 3 раза в месяц, мы задолбались и теперь с ними работаем по вашей схеме. Ничего, все довольны.
Проходит год. Команд, которые работают по такой схеме, уже десяток. В репозитории появляются ветки
- vasya/blog-user-ban
- petya-ivanov/email_new_field
- email/migration
- blog/hotfix
- petrov/srochno-v-prod
Эти ветки множатся, мерджатся между собой и вообще живут своей жизнью. Называются они как попало, коммиты подписывают кто во что горазд, старые ветки не удаляются после мерджей. Надвигается хаос.
Конечно, ребятам из админки не очень нравится такой мусор в их репозитории. Сначала они пытаются с этим бороться и проводить разъяснительные работы. Пытаются рассказать о правилах приличия в их репозитории. Пишут доку и официальное письмо всем программистам, где все подробно рассказывают. Как именовать ветки, как подписывать коммиты, не забывать удалять старые ветки, не заводить лишние ветки без надобности и прочее.
Это дело хорошее, но бесполезное. В компании полсотни разрабов, у каждого своя команда и свои правила работы с репозиторием. Люди приходят и уходят, эти правила уже никто не помнит, да и всем пофигу, главное фичу сделать, чего там заморачиваться с ветками и коммитами. Пусть у команды админки об этом голова болит. Главное, у нас все хорошо, в своем командном проекте, потому что мы никого к себе не пускаем, ахаха. Поэтому и ветки красиво называются, и коммиты адекватно подписаны. Нас тут 5 человек работают, уж между собой-то договоримся.
А между тем в репозитории админки образуется все больший трэш. То злодеи опять пушат ветки с названиями не по ГОСТу, и тимлида бесят. То сам тимлид с похмелья выдал новому чуваку доступы на пуш в мастер, а тот на радостях запушил миграцию, которая пол-сайта уронила. То по ошибке смерджили petya/hotfix вместо vasya/hotfix. В общем весело всем, кроме ребят из админки.
И вот однажды что-то изменилось. Тебе понадобилось запилить новую фичу и ты привычно набиваешь
git checkout master git pull --rebase origin master git checkout -b vasya/fix-comments ... git push origin vasya/fix-comments waiting... Rejected
Опа, что за фигня? Пробуешь еще раз на всякий случай - снова rejected. Пишешь команде админки
- репца, привет, я чот запушить вам не могу, вы права сняли?
- привет, Петя, да, мы убрали права на пуш для всех не-членов нашей команды
- эээ, ну во-первых, я Вася, а во-вторых, как мне теперь делать?
- теперь все мердж-реквесты принимаются из форков
- окей, а на фига это надо? Все равно же в мастер нельзя было запушить, все и так через мердж-реквесты было...
- видишь ли, Вася, у нас тут столько народа, что мы уже не понимаем, кто Вася, а кто Петя, а кто вообще мимо проходил. И в ваших ветках мы тут просто тонем, git fetch невозможно сделать. Мы пытались донести до коллег, что это наш репозиторий и мы просим соблюдать простые правила работы с ним. Но народа много и все решили, что наш проект это помойка, в которой можно делать, что угодно. Все равно ж в мастер не попадет, а там разберутся. Ну и пара инцидентов с неправильно выданными правами. Да, наш косяк, но вас слишком много, чтобы за каждым уследить. Короче, форкайте репозиторий и резвитесь там, как хотите. А нам отправляйте только мердж-реквесты. Вам без разницы, а нам спокойней и в репозитории чище.
- окей, понятно
Понятно-то оно понятно, но ты с форками не работал. Ладно, думаешь, разберешься же, не тупой. Мердж-реквест что ли из форка не отправишь? К тому же ты читал git-scm и знаешь, что форк - это просто копия репозитория. Начинаешь разбираться.
Сначала идешь в гитхаб-битбакет и ищешь там в нужном репозитории кнопку Fork. Обычно она недалеко от кнопки clone. Жмешь на fork и для тебя создается проект. Если исходный был company/adminka.git, то твой будет примерно vasya/adminka.git. Ну или примерно так. Дальше клонируешь его как обычно
git clone git@bitbucket.org:vasya/adminka.git
Естественно, свой форк клонируешь, а не оригинальный. Затем там создаешь привычно ветку и пушишь ее.
git checkout -b blog/new-field ... git push origin blog/new-field
Заходишь в гитхаб-битбакет исходного репозитория, жмешь "Создать мердж-реквест", выбираешь свою ветку, она будет называться примерно vasya/adminka/blog/new-field, и ждешь, пока мердж-реквест примут.
Пока все ровно так, как ты привык, ничего нового. Мердж-реквест принимают и все хорошо.
Через месяц тебе нужно сделать еще одну задачу. Ты привычно подтягиваешь мастер и настораживаешься
git pull --rebase origin master From bitbucket.org:vasya/adminka Current branch master is up to date.
За месяц нет новых коммитов в мастере? Да не верю. Идешь в репозиторий админки, смотришь, там до фига коммитов, чуть не каждый день в мастер пушат. В чем дело?
Присматриваешься, откуда ты пулишься и видишь, что это vasya/adminka. Это твой репозиторий, твой форк. Конечно, ты его месяц не трогал и он ничего не знает о новых коммитах в исходном проекте. Их нужно подтянуть и только тогда создавать новую ветку. Можно сделать это так
git pull --rebase git@bitbucket.org:company/adminka.git master
То есть вместо origin указываешь адрес нужного репозитория. И вот теперь-то подтянется мастер именно исходного проекта, а не твоего. А еще лучше сделать так, чтобы не набивать каждый раз длинный адрес
git remote add upstream git@bitbucket.org:company/adminka.git
Теперь у тебя есть origin - твой репозиторий, твой форк, а есть upstream - оригинальный репозиторий. И ты можешь пулиться, указывая сразу upstream
git pull --rebase upstream master
Вот теперь твой мастер актуален, можешь создавать ветку и пушить в репозиторий. Пушить уже в origin, то есть свой, потому что в upstream, исходный, тебе пушить никто не даст. То есть еще раз, пулишь мастер так
git pull --rebase upstream master
а пушишь свою ветку так
git push origin branch-name
По сути это все, что нужно знать о работе с форками. После этого идешь создавать мердж-реквест, твоя ветка уже видна в исходном репозитории. Если ты работал над веткой, а за это время в мастер накидали еще коммитов, то перед отправкой мердж-реквеста стоит отребейзиться от мастера
git checkout master git pull --rebase upstream master git checkout branch-name git rebase master git push -f origin branch-name
Тут можешь делать, как хочешь, твой форк, твои правила. Можешь пушить с форсом, как у меня в примере. Если не хочешь с форсом, то можешь создать отдельную ветку и положить коммит в нее. Как угодно. Главное, чтобы твои коммиты лежали поверх свежих коммитов из мастера. Тогда никто не будет возникать при рассмотрении мердж-реквеста, а ты будешь уверен, что у тебя самые свежие обновления.
Подробнее почитать про ребейз можно здесь - git merge и rebase.
И на этом все. Главное, что нужно сделать, это добавить upstream и четко понимать, в чем его отличие от origin.
С форками можно работать и в компании на полсотни разработчиков, но особенно это популярно в опенсорсе. Возьмите какой-нибудь проект, например, vuejs, у него больше 20 тысяч форков и 3 сотни контрибьюторов. Представьте, что бы творилось в репозитории, пусти всех этих энтузиастов пушить свои правки. А так они спокойно работают со своими форками и присылают пулл-реквесты, не засоряя проект.
Всем удачи. Любите гит, он совсем не страшный :-)
P.S. Пожалуй, это самая большая статья про форки, которую можно было написать =))
P.P.S. И небольшой опрос напоследок
Все статьи о git
- Курс "Git для начинающих". Видеоуроки
- Git merge vs rebase для начинающих
- Git fork. Что такое форки и как с ними работать
- Как я перестал бояться и полюбил git
- Git bisect. Ищем баги с помощью гита
- 12 причин работать с гитом в командной строке
- Как склеить коммиты в git
- Мой набор команд при работе с git
- Как работать с git в Modx
- Как установить git в Linux Mint
- Визуализация истории git с помощью Gource
Истории из жизни айти и обсуждение кода.