Коротко:
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
[ Оригинал поста ]
The major benefit of rebasing is that you get a much cleaner project history. First, it eliminates the unnecessary merge commits required by