Часто у разработчиков возникает выбор между Merge (слияние) и Rebase (перемещение). В Гугле вы увидите разное мнение, многие советуют не использовать Rebase, так как это может вызвать серьезные проблемы. В статье я объясню, что такое слияние и перемещение, почему вы должны (или не должны) использовать их и как это сделать.
Git Merge и Git Rebase преследуют одну и ту же цель. Они предназначены для интеграции изменений из одной ветки в другую. Хотя конечная цель одинаковая, принципы работы разные.
Некоторые считают, что вы всегда должны использовать Rebase, другие предпочитают Merge. В этом есть свои плюсы и минусы.
Слияние — обычная практика для разработчиков, использующих системы контроля версий. Независимо от того, созданы ли ветки для тестирования, исправления ошибок или по другим причинам, слияние фиксирует изменения в другом месте. Слияние принимает содержимое ветки источника и объединяет их с целевой веткой. В этом процессе изменяется только целевая ветка. История исходных веток остается неизменной.
Плюсы:
Минусы:
Как это сделать
Слейте ветку master в ветку feature, используя команды checkout и merge.
Это создаст новый «Merge commit» в ветке feature, который содержит историю обеих веток.
Rebase — еще один способ перенести изменения из одной ветки в другую. Rebase сжимает все изменения в один «патч». Затем он интегрирует патч в целевую ветку.
В отличие от слияния, перемещение перезаписывает историю, потому что она передает завершенную работу из одной ветки в другую. В процессе устраняется нежелательная история.
Плюсы:
Минусы:
Если вы сделаете перемещение неправильно, история изменится, а это может привести к серьезным проблемам, поэтому убедитесь в том, что делаете!
Как это сделать
Переместите ветку feature на главной ветке, используя следующие команды.
Это перемещает всю ветку функции в главную ветку. История проекта изменяется, создаются новые коммиты для каждого коммита в основной ветке.
Это позволяет изменять коммиты при их перемещении в новую ветку. Это лучше, чем автоматическое перемещение, поскольку обеспечивает полный контроль над историей коммитов. Как правило, используется для очистки истории до слияния ветки feature в master.
Это откроет редактор, перечислив все коммиты, которые будут перемещены.
Это точно определяет, как будет выглядеть ветка после выполнения перемещения. Упорядочивая объекты, вы можете сделать историю такой, как захотите. Вы можете использовать команды fixup, squash, edit, и так далее.
Так что же лучше? Что рекомендуют эксперты?
Трудно принять единственно правильное решение о том, что лучше использовать, поскольку все команды разные. Всё зависит от потребностей и традиций внутри команды.
Принимайте решения на основании компетенции команды в Git. Для вас важна простота или перезаписывание истории, а может быть что-то другое?
Что рекомендую я?
По мере роста команды становится сложно управлять или отслеживать изменения в разработке, применяя слияние. Чтобы иметь чистую и понятную историю коммитов, разумно использовать Rebase.
Преимущества Rebase:
Теперь вы знаете хоть и незначительную, но разницу между Merge и Rebase. Уверен, вы примете правильное решение и будете использовать то, что подходит именно вам.
Не забывайте:
Git Merge и Git Rebase преследуют одну и ту же цель. Они предназначены для интеграции изменений из одной ветки в другую. Хотя конечная цель одинаковая, принципы работы разные.
Некоторые считают, что вы всегда должны использовать Rebase, другие предпочитают Merge. В этом есть свои плюсы и минусы.
Git Merge
Слияние — обычная практика для разработчиков, использующих системы контроля версий. Независимо от того, созданы ли ветки для тестирования, исправления ошибок или по другим причинам, слияние фиксирует изменения в другом месте. Слияние принимает содержимое ветки источника и объединяет их с целевой веткой. В этом процессе изменяется только целевая ветка. История исходных веток остается неизменной.
Плюсы:
- простота;
- сохраняет полную историю и хронологический порядок;
- поддерживает контекст ветки.
Минусы:
- история коммитов может быть заполнена (загрязнена) множеством коммитов;
- отладка с использованием git bisect может стать сложнее.
Как это сделать
Слейте ветку master в ветку feature, используя команды checkout и merge.
$ git checkout feature
$ git merge master
(or)
$ git merge master feature
Это создаст новый «Merge commit» в ветке feature, который содержит историю обеих веток.
Git Rebase
Rebase — еще один способ перенести изменения из одной ветки в другую. Rebase сжимает все изменения в один «патч». Затем он интегрирует патч в целевую ветку.
В отличие от слияния, перемещение перезаписывает историю, потому что она передает завершенную работу из одной ветки в другую. В процессе устраняется нежелательная история.
Плюсы:
- Упрощает потенциально сложную историю
- Упрощение манипуляций с единственным коммитом
- Избежание слияния коммитов в занятых репозиториях и ветках
- Очищает промежуточные коммиты, делая их одним коммитом, что полезно для DevOps команд
Минусы:
- Сжатие фич до нескольких коммитов может скрыть контекст
- Перемещение публичных репозиториев может быть опасным при работе в команде
- Появляется больше работы
- Для восстановления с удаленными ветками требуется принудительный пуш. Это приводит к обновлению всех веток, имеющих одно и то же имя, как локально, так и удаленно, и это ужасно.
Если вы сделаете перемещение неправильно, история изменится, а это может привести к серьезным проблемам, поэтому убедитесь в том, что делаете!
Как это сделать
Переместите ветку feature на главной ветке, используя следующие команды.
$ git checkout feature
$ git rebase master
Это перемещает всю ветку функции в главную ветку. История проекта изменяется, создаются новые коммиты для каждого коммита в основной ветке.
Интерактивное перемещение
Это позволяет изменять коммиты при их перемещении в новую ветку. Это лучше, чем автоматическое перемещение, поскольку обеспечивает полный контроль над историей коммитов. Как правило, используется для очистки истории до слияния ветки feature в master.
$ git checkout feature
$ git rebase -i master
Это откроет редактор, перечислив все коммиты, которые будут перемещены.
pick 22d6d7c Commit message#1
pick 44e8a9b Commit message#2
pick 79f1d2h Commit message#3
Это точно определяет, как будет выглядеть ветка после выполнения перемещения. Упорядочивая объекты, вы можете сделать историю такой, как захотите. Вы можете использовать команды fixup, squash, edit, и так далее.
Какой из них использовать?
Так что же лучше? Что рекомендуют эксперты?
Трудно принять единственно правильное решение о том, что лучше использовать, поскольку все команды разные. Всё зависит от потребностей и традиций внутри команды.
Принимайте решения на основании компетенции команды в Git. Для вас важна простота или перезаписывание истории, а может быть что-то другое?
Что рекомендую я?
По мере роста команды становится сложно управлять или отслеживать изменения в разработке, применяя слияние. Чтобы иметь чистую и понятную историю коммитов, разумно использовать Rebase.
Преимущества Rebase:
- Вы разрабатываете локально: если вы не делились своей работой с кем-либо еще. На данный момент вы должны предпочесть перемещение слиянию, чтобы сохранить свою историю в порядке. Если у вас есть личная вилка репозитория, которая не используется совместно с другими разработчиками, вы можете делать rebase даже после того, как переместились в свою ветку.
- Ваш код готов к ревью: вы создали пулл реквест. Другие анализируют вашу работу и потенциально стягивают ее к своей вилке для локального ревью. На данный момент вы не должны перемещать свою работу. Вы должны создать коммит «переделать» и обновить ветку. Это помогает отслеживать запросы на пулл реквест и предотвращает случайную поломку истории.
- Ревью сделано и готово к интеграции в целевую ветку. Поздравляем! Вы собираетесь удалить свою ветку feature. Учитывая, что с этого момента другие разработчики не будут fetch-merging эти изменения, это ваш шанс изменить вашу историю. На этом этапе вы можете переписать историю и сбросить оригинальные коммиты, и эти надоедливые «переделки» и «слияние» сливаются в небольшой набор целенаправленных коммитов. Создание явного слияния для этих коммитов является необязательным, но имеет значение. Он записывает, когда функция достигла master.
Теперь вы знаете хоть и незначительную, но разницу между Merge и Rebase. Уверен, вы примете правильное решение и будете использовать то, что подходит именно вам.
Не забывайте:
code = coffee + developer