Что значит мержить ветки
Git для начинающих. Урок 9.
Слияния или мерджи веток
Видеоурок
Конспект урока
Краткое содержание урока, основные инструкции для командной строки, полезные ссылки и советы.
Подробнее о разных соглашениях мы поговорим во второй части курса.
Что такое мердж или слияние веток
Следует четко различать мердж своей ветки в мастер и мердж мастера в свою ветку.
Мердж ветки в мастер
Выполняется после завершения работы над своей веткой при помощи команды git merge. Чтобы вмерджить ветку в мастер, нужно сначала перейти в мастер, а затем выполнить git merge branch_name.
При этом возможны разные ситуации
Поговорим о них подробнее
Пока мы работали над веткой, в мастере не появилось новых коммитов
То есть мы создали ветку, поработали над ней, собрались заливать ее в мастер, а за это время новых коммитов там не появилось. Тогда слияние проходит так
Git понимает, что это новый код, который можно просто положить поверх старого. Это простая ситуация и git не задает никаких вопросов.
Не забудьте сразу запушить изменения, чтобы их увидели коллеги, и удалить локальную ветку header, если она больше не нужна.
Теперь другая ситуация.
Пока мы работали над веткой, в мастере появились коммиты от коллег
Сначала переключаемся на мастер
Почему «is up-to-date»? Потому что мы еще не сделали git pull. Делаем
Мерджим свою ветку в мастер
И не забываем запушить изменения
Что если сначала не подтягивать мастер, а смерджить свою ветку
Принципиально ничего не изменится, но лучше сначала сделать актуальной ветку мастер, а уже потом заливать свои изменения. А еще лучше держать актуальной свою ветку относительно мастера. Это значит, что стоит почаще подтягивать мастер в свою ветку. Таким образом мы в своей ветке будем работать с актуальным кодом и у нас меньше риска что-нибудь поломать. А если поломаем, то лучше чинить это в своей ветке, а не в мастере.
Как вмерджить мастер в свою ветку
Сначала идем в мастер, подтягиваем изменения с сервера, то есть делаем git pull. Затем переключаемся в свою ветку и делаем git merge master
Затем проверяем, что ничего не поломалось и продолжаем работать.
Мердж коммиты
Чем чаще мерджить между собой ветки, тем больше появляется так называемых мердж-коммитов. Такой коммит появляется каждый раз, когда мы подтягиваем мастер в свою ветку или сливаем свою ветку в мастер. Эти коммиты не хранят изменений, они хранят только факт мерджа одной ветки в другую.
Посмотрим список коммитов и найдем мердж-коммит с хэшем 051f754
Посмотрим его содержимое
То есть информация только о том, что в мастер была залита ветка news. Сами изменения в файлах, которые мы делали в ветке news, лежат в других коммитах.
Споры о том, есть польза от таких коммитов, ведутся годами и не закончатся, видимо, никогда.
Мерджи всегда проходят так гладко?
В этом уроке мы намеренно упрощали ситуацию и рассматривали случаи, когда наши коллеги делают изменения в других участках кода. То есть мы с ними даже не пересекались. В реальной жизни так происходит не всегда. Иногда мы правим одни и те же участки кода и тогда при их слиянии git не может понять, чей вариант правильный. Это называется возникновения конфликта.
Подробнее о конфликтах и их разрешении мы поговорим в следующем уроке.
Как правильно мержить ветки в git?
Когда я сделал это, я наткнулся на ряд неприятных моментов с которыми не смог разобраться. Итак конкретный пример:
— в test1 я создал файл index.php
— дальше я перешел (git checkout development) в ветку разработки
— и попытался смержить: git merge test1
Теперь этот подлый index.php пропал из test1 и появился в development. Это так и должно быть?
Теперь я хочу продолжить разработку в test1, а у меня нет моего inde.php что делать?
Объясните пожалуйста как правильно мерджить ветки. Вот это дело вычитал в доках, но не понял почему так вышло.
git checkout
будет вам разворачивать поддерево то одного проекта в ваш рабочий каталог, то другого. Это во-первых, жутко неоптимально с точки зрения той же производительности, а во-вторых вы так совсем запутаетесь, тем более раз вы ещё включили в рабочий процесс слияния между этими ветками. Конфликтов слияния и трудностей таким образом можно достигнуть множество. Пожалуйста, обратите внимание на работающие подходы, используемые для разработки с использованием Git:
Если в ваших частях проекта выражена очень разная функциональность, то можно создать два отдельных репозитория (к примеру, fronted и backend), а затем, при необходимости, соединить их в один Git-суперрепозиторий в качестве его подмодулей.
Да, и merge не удаляет изменения, а просто применяет все коммиты из одной ветки в другую.
Та да, не получается пока освоить гит для дальнейшей работы. =(
Вот я не все знал про checkout. По поводу удаленного файла, походу коммит не сделал в 1 из веток. Я начал на боевом проекте тестировать в результате чего все запорол =).
Таким образом, используя checkout, Вы просто переключаетесь на определенный слепок файлов, идентифицируя его по хешу коммита/ветке/тегу. Если Вы что-то не закоммитили и переходите в другую ветку, изменения потеряются, но git должен об этом предупредить.
Касательно Вашего момента:
Да, git checkout test1, разработка и мерджить с dev. Если Вы уже вливали test2 в dev, до этого, то ничего страшного в этом нет, это вполне штатная ситуация, git все сольет как надо, а что не сможет, выдаст Вам в виде конфликта, который нужно решить.
@nepster09 в общем, вот вам нормальный рабочий процесс под которым работают все команды (называется github flow): https://guides.github.com/introduction/flow/index.html
Git. Урок 5.
Слияние изменений и продвинутая
работа с ветками.
Команды: merge, cherry-pick, rebase.
1. Что такое слияние и зачем оно нужно.
2. Слияние в Git. Команда git merge.
2.1 Явное слияние
2.2 Неявное слияние (fast-forward)
2.3 В чем разница между fast-forward и явным слиянием?
3. Разрешение конфликтов слияния.
3.1. Ручное разрешение конфликта
3.2. Выбор одного из двух файлов
3.3. Тонкости разрешения merge-конфликтов.
3.4. Инструменты для разрешения merge-конфликтов.
4. Еще один способ объединения изменений из разных веток. Команда git rebase.
5. Интерактивный git rebase. Редактирование коммитов любой давности.
6. Берем вишенку с торта. Команда git cherry-pick.
То есть общий ход нашей работы выглядит следующим образом:
1. Решили добавить новую функцию – создали отдельную ветку. Дальше работаем в новой ветке.
2. Написали функцию, протестировали ее работу, внесли все необходимые исправления, еще раз протестировали и убедились, что функция работает исправно и не привнесла ошибок в остальной код.
3. Теперь нужно как-то перенести изменения с тестовой ветки на основную – в продакшн. Тут нам на помощь и приходит слияние: мы просто сливаем (т.е. переносим) изменения с нашей тестовой ветки в основную.
Итак, дадим определения:
Команда git merge
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать слияние и вернуть все к моменту начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить слияние после разрешения всех конфликтов.
2. 1. Явное слияние
Допустим, у нас есть граф вида:
Флаг —no-ff в данной ситуации необходим, поскольку мы хотим выполнить именно явное слияние. Подробнее о смысле этого флага мы поговорим чуть позже.
2.2. Неявное слияние
Давайте рассмотрим пример. Допустим, у нас есть все тот же граф репозитория:
Очень часто во время слияния веток оказывается, что ваши изменения удаляют или переписывают информацию в уже существующих файлах. Такая ситуация называется файловым конфликтом. Git останавливает выполнение слияния, пока вы не разрешите конфликт.
По сути, Git сталкивается с проблемой: у него есть два файла с одним и тем же именем, и он не знает, какой из них взять. Поэтому обращается к нам за помощью.
Давайте сразу начнем с примера и по ходу будем учиться разрешению конфликтов. Так будет нагляднее. Итак, допустим есть следующий репозиторий:
3.1. Ручное разрешение конфликта
3.2. Выбор одного из двух файлов
Дальше все стандартно: откроется редактор сообщения коммита. В сообщении следует указать, какие ветки вы сливали, и вкратце перечислить внесенные изменения.
3.3. Тонкости разрешения merge-конфликтов.
Теперь мы имеем представление, как разрешать конфликты слияния, и пришло время углубиться в эту тему. Поговорим о тонкостях, которые помогут вам понять, как правильно разрешить конфликт. Подчеркиваем: «правильно», поскольку разрешить конфликт не составляет труда, но если сделать это неверно, можно потерять код, написанный другими разработчиками.
Видно, что файлы различаются, но из этого представления совсем непонятно, что именно должно войти в итоговый файл. Если бы это был ваш личный проект, вы бы прекрасно знали, какой из файлов выбрать, но это чужой репозиторий и цена ошибки велика. Конечно, можно потратить много времени, перебирая коммиты из обеих веток, разбираясь, как менялись файлы, чтобы понять, что должно быть в итоговом файле. Но можно поступить проще. Прежде всего, давайте изучим немного теории.
Итак, при слиянии двух веток используются четыре состояния, и три из них необходимы, чтобы разрешить конфликт правильно. Давайте разбираться, что это за состояния.
Эти состояния можно изобразить на диаграмме следующим образом.
Чтобы понять, что изображено на диаграмме, полезно будет вспомнить, что такое дельта.
Дельта – это разность каких-то двух состояний. То есть по сути это информация о том, какие изменения вы внесли в файлы с момента определенного коммита. Как мы помним из второго урока данного курса, коммиты хранят именно дельты, а не полностью файлы. Благодаря этому репозиторий Git занимает очень мало места.
На диаграмме выше Дельта-1 – это разность текущего состояния ветки main и базы слияния. Аналогично Дельта-2 – это разность текущего состояния ветки develop и базы слияния.
Результат слияния нам как раз и нужно получить. Git пытается получить его автоматически, совмещая Дельту-1 и Дельту-2, но если эти дельты задевают одни и те же части одного и того же файла, возникает конфликт. При возникновении конфликта Git просит нас сравнить Дельту-1 и Дельту-2, чтобы составить из них третье состояние – результат слияния.
3.4. Инструменты для разрешения merge-конфликтов.
Использование графических утилит особенно удобно при сравнении больших файлов: почти во всех есть подсветка внесенных изменений, что поможет вам не запутаться в файле. Тем не менее при сравнении маленьких файлов часто можно обойтись одной консолью. Кстати, большинство IDE имеет встроенную утилиту для разрешения конфликтов, что сделает вашу работу с кодом еще более удобной.
Если говорить кратко, git rebase переносит коммиты текущей ветки на вершину переданной. Но перед тем, как перейти непосредственно к команде, давайте разберем принцип ее действия на примере. Пусть у нас есть репозиторий со следующим графом.
Команда git rebase
-i
—interative
Эти ключи позволяют нам делать rebase в интерактивном режиме. Мы будем активно пользоваться ими при редактировании старых коммитов.
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать ребейз и вернуть все к моменту до начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить ребейз после разрешения всех конфликтов.
—skip
Ключ, использующийся только при разрешении конфликтов. Позволяет пропустить текущий коммит.
После выполнения всех вышеуказанных операций, граф репозитория будет выглядеть так.
В предыдущем уроке мы с вами разобрали, помимо прочего, как можно объединить несколько последовательных коммитов в один и как редактировать содержимое и сообщение последнего коммита ветки. Но что если мы хотим отредактировать более ранний коммит? Git предоставляет нам и такую возможность. Правда тут мы воспользуемся небольшой хитростью.
На самом деле git rebase можно выполнять для одной и той же ветки. В обычном режиме это нам ничего не даст, но вот в интерактивном режиме мы сможем поменять сообщения, содержимое и вообще манипулировать коммитами, как нам только вздумается, вплоть до удаления. Давайте на примере разберем, как происходит изменение коммитов. Итак, допустим у нас есть репозиторий, граф которого выглядит так:
Команда git cherry-pick
-e
—edit
С этим ключом вы сможете отредактировать сообщение коммита.
-n
—no-commit
С этим ключом команда не создаст коммит на вашей ветке, а только скопирует все изменения в вашу рабочую копию. То есть с этим ключом данная команда идентичная git checkout *
—abort
Ключ, использующийся только при разрешении конфликтов. Позволяет прервать операцию и вернуть все к моменту до начала операции.
—continue
Ключ, использующийся только при разрешении конфликтов. Позволяет продолжить операцию после разрешения всех конфликтов.
Берет переданный коммит и создает в текущей ветке его точную копию.
Также в команду можно передать первый и последний коммит последовательности, тогда та же операция будет выполнена для всех коммитов последовательности.
1. Случай первый. Работа в команде.
Этот случай был описан во введении к данной части. Часто в команде несколько разработчиков работают над одним и тем же участком кода, но каждый – в своей ветке. Соответственно могут возникать ситуации, когда одному из разработчиков для реализации своей части задачи потребуется часть кода, написанная другим разработчиком. Merge в данном случае делать нерационально, поскольку ни одна из веток не пришла к своему логическому завершению, а вот cherry-pick – то, что надо.
2. Случай второй. Быстрые исправления багов.
Если в коде был обнаружен баг, очень важно как можно быстрее донести исправления до конечного пользователя. В таком случае, разработчик, обнаруживший ошибку, срочно создает коммит, в котором исправляет ее. Этот коммит может быть перенесен в основную ветку с помощью cherry-pick, чтобы не задерживать исправление бага слияниями в различные пре-релизные ветки.
Гайд по Git : Часть 2 : Ветки и слияние веток
В этой статье разбираемся с понятием веток в git. Как смержить одну ветку в другую, и чем отличается Merge от Rebase.
Почти каждая система контроля версий (СКВ) в какой-то форме поддерживает ветвление. Используя ветвление, вы отклоняетесь от основной линии разработки и продолжаете работу независимо от неё, не вмешиваясь в основную линию. Во многих СКВ создание веток — это очень затратный процесс, часто требующий создания новой копии каталога с исходным кодом, что может занять много времени для большого проекта.
Ветки в Git, как и коммиты, невероятно легковесны. Ветка в Git — это простой перемещаемый указатель и ничего более. Вот почему многие фанаты Git повторяют мантру:
делай ветки сразу, делай ветки часто
Команда git branch позволяет не только создавать ветки, но и просматривать существующие. Ветка, на которой вы находитесь помечается звездочкой.
Сообщим Git, что хотим переключиться на другую ветку:
Чтобы понять, почему мы это называем ветками, переключимся на ветку main и сделаем еще один коммит там.
Напоследок вот совет, как создать новую ветку и переключиться на неё с помощью одной команды:
Merge
Мы уже знаем, как создавать ветки и коммитить наши изменения. Теперь надо понять, как объединять изменения из двух разных веток, после того как вы выполнили свою задачу в отдельной ветке.
Слияния создают особый вид коммита, который имеет сразу двух родителей. Коммит с двумя родителями обычно означает, что мы хотим объединить изменения из одного коммита с другим коммитом и всеми их родительскими коммитами.
Втащим все изменения из ветки newImage в ветку main :
А также посмотрим log, убедимся что появился новый коммит:
Rebase
Несмотря на то, что это звучит достаточно непонятно, преимущество rebase в том, что c его помощью можно делать чистые и красивые линейные последовательности коммитов. История коммитов будет чище, если вы применяете rebase.
Посмотрим, как это работает:
Git дописал копию коммита C7 за коммитом C6 и перенес туда указатель
Удалим ветку bugFix и снова проверим log:
Напоследок вот вам шпаргалка по отличию Merge от Rebase:
Сравнение Merge и Rebase
Заключение
Мы разобрались с ветками в Git и их слиянием. В идельном проекте все ветки стремятся влиться в одну.
Не забывайте создавать новые ветки от основной ветки разработки для каждой самостоятельной задачи.
Изучаем Git. Урок 24.
Мердж-реквесты и код-ревью
Видеоурок
Конспект урока
Краткое содержание урока, основные инструкции для командной строки, полезные ссылки и советы.
Что такое мердж-реквест?
Зачем нужны мердж-реквесты?
В первую очередь они нужны при работе в команде для проведения код-ревью. Чтобы коллеги увидели новый код и как минимум его просмотрели и оставили замечания или вопросы
Как правильно: merge request или pull request?
Как проходит процедура мердж-реквеста
Немного о markdown
Markdown позволяет форматировать текст: задавать заголовки, списки, цитаты, вставлять ссылки и картинки и даже форматировать код. Насчет кода, возможно, для приграммиста это самая удобная фишка markdown, так как используется достаточно часто
Изучается markdown быстро, разметка очень простая. Вот пример оформления списка, используются звездочки
А вот пример оформления кода, используются апострофы
После этого ваш текст красиво отформатируется, можете попробовать в любом markdown онлайн-редакторе, например, dillinger.io/
Совет от автора
Немного о код ревью
Это отдельная большая тема и git она не касается. Поэтому приведу только кратко причины проводить код ревью
Вопросы на код ревью могут быть совершенно разные и на разные темы. Это всего лишь краткий перечень плюсов от код ревью
Как оповестить коллег о новом мердж-реквесте
Здесь разные варианты, зависит от договоренностей в команде.
Главное договориться как будет удобнее всем в вашей команде
Кто принимает мердж-реквесты
Здесь тоже могут быть разные варианты: