Twitter GitHub

Git merge vs. rebase

Коротко:

  • git pull --rebase вместо git pull
  • git rebase -i @{u} до того как git push
  • (в «feature») git merge master чтобы сделать ветку feature совместимой с последними изменениями в master’е
  • (в «master») git merge -no-ff feature для релиза фичи

Однако избегайте merge-коммита, если ветка «feature» содержит только 1 коммит: (в «master») git cherry-pick feature.

Развернуто:

Избегайте merge-коммитов, которые возникают при «git pull»

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

Таких merge-коммитов может быть довольно много, особенно при разработке в комманде, участники которой часто пушат. Эти коммиты не содержат никакой полезной информации и только загрязняют историю проекта.

Всегда получайте изменения через git pull --rebase. Git можно настроить, чтобы он вел себя так по-умолчанию:

git config --global --bool pull.rebase true

Используйте интерактивный rebase локальных коммитов перед пушем

Перед каждым пушем делайте: git rebase -i @{u}

Буква «u» означает «upstream» (добавлено в git v1.7.0) и разолвится в последний коммит в этой ветке на сервере. Проще говоря, эта комманда переписывает только локальные коммиты, которые вы собираетесь запушить. Начиная с git v1.7.6, @{upstream} является аргументом по-умолчанию и его можно опускать.

Это дает вам возможность навести порядок в коммитах перед тем как делиться ими. Например, объединить связанные коммиты или изменить описания коммитов, если они слишком длинные или недостаточно понятные.

Предположим у вас есть 4 коммита (последние вверху):

[D] упс! исправлена опечатка в фиче A
[C] багафикс для коммита B
[B] что-то поменял
[A] ура, новая фича!

Вам определенно захочется сгруппировать коммиты A+D и B+C, оставив A и B разделенными. Смысл тут простой: не делайте баги и опечатки частью истории проекта, если вы еще не успели поделиться ими с другими.

Забирайте изменения из master’а в ветку фичи

Если вы работаете над долгоживущей веткой какой-то фичи, то стоит время от времени забирать изменения из master’а (подразумевается, что «master» — главная ветка разработки) [мое примечание: если посмотреть через призму git-flow, то тут имеется в виду ветка develop], чтобы проверять совместимость и получать последние исправления багов.

Также можно использовать rebase текущей ветки поверх master’а, но у этого способа есть недостатки:

  • если над фичей работают несколько людей, то переписывание истории усложняет рабочий процесс
  • merge-конфликты могут разрешаться проще, чем огромное количество маленьких конфликтов во время rebase

Сохраняйте merge-коммит, когда вливаете фичу в master

После завершения работы над фичей вливайте ее в master так:

git merge --no-ff feature

Флаг --no-ff гарантирует создание merge-коммита, даже если технически этого можно избежать. Merge-коммиты полезны, потому что они содержат следующую важную информацию:

  • откуда пришли изменения (в нашем случае из ветки «feature»)
  • когда и кем было выполнено слияние
  • коммиты, относящиеся к этой фиче, остаются сгруппированными

Иногда ветка состоит из одного единственного коммита, особенно если это исправление багов. При слиянии таких веток я часто решаю не создавать merge-коммит, потому что информация такого коммита почти бесполезна для комманды:

  • откуда пришли изменения уже не так важно, потому что скорее всего ветка существовала недолго, и люди в комманде не успели с ней как следует ознакомиться
  • когда и кем уже содержится в самом коммите
  • нечего группировать

Вы можете забрать отдельный коммит в master так:

git cherry-pick feature

[ Оригинал поста ]

1 комментарий