В командной разработке на Git регулярно возникает ситуация: вы работаете над фичей в ветке feature/xxx, ответвившись от master. Пока вы пишете код, коллеги успевают задеплоить в master несколько других фич, которые не пересекаются с вашей, но вносят изменения в общий код (например, исправляют баги, добавляют утилиты, меняют конфигурацию). Ваша задача — обновить свою ветку так, чтобы она включила эти “чужие” изменения, но при этом не тащила в историю лишние merge-коммиты и не смешивала логику. Идеальное решение — git pull origin master --rebase. Разберём этот кейс подробно.
Проблема: устаревшая база и потенциальный конфликт
Предположим, история выглядит так:

Вы отпочковались от коммита E. В master ушли коммиты F, G, H (другие фичи или исправления). Если вы просто выполните git merge master в feature/xxx, получите merge-коммит:

Это работает, но со временем засоряет историю. При ревью и биссекте сложнее понять, какие изменения действительно относились к фиче. Кроме того, если у вас длинная ветка, накопление merge-коммитов затрудняет последующее вливание в master.
Но главная проблема даже не в эстетике. Когда другие фичи модифицируют код, находящийся рядом с вашим, вы рискуете получить конфликты на позднем этапе. rebase позволяет разрешить эти конфликты пораньше, итеративно, на каждом коммите вашей ветки.
Решение: обновить ветку через rebase
Вот пошаговый набор команд, который решает задачу “обновить код, не связанный с моей фичей, но уже задеплоенный в мастере”:
|
1 2 3 4 |
git checkout master git pull git checkout feature/xxx git rebase master |
Разберём, что происходит под капотом.
1. git checkout master → git pull
Переключаемся на локальный master и подтягиваем последние изменения из удалённого репозитория. Этот шаг гарантирует, что у вас актуальная база, на которую вы будете перебазировать свою фичу.
2. git checkout feature/xxx
Возвращаемся в рабочую ветку.
3. git rebase master
Ключевая команда. Она выполнит перебазирование на текущую ветку feature/xxx поверх актуального origin/master.
git fetch origin master— получить свежие коммиты из удалённогоmaster(но не сливать их автоматически).git rebase origin/master— перебазировать текущую веткуfeature/xxxповерх актуальногоorigin/master.
В результате история становится линейной:

Ваши коммиты A, B, C как бы “переезжают” на новую базу — коммит H. При этом их хэши меняются (A', B', C'), но содержимое (изменения относительно нового базового коммита) остаётся тем же, если нет конфликтов.
Что даёт такой подход при обновлении “чужого” кода?
- Вы получаете все изменения из
master, включая те, что были задеплоены после старта вашей фичи. Локально ваша ветка становится совместима с актуальным состоянием проекта. - Ваши коммиты не перемешиваются с merge-коммитами — история остаётся чистой, каждый коммит вашей фичи идёт подряд.
- Конфликты решаются последовательно: для каждого вашего коммита Git пытается применить его поверх текущего состояния
master. Если конфликт возник в коммитеB, вы правите его именно в контексте этого коммита, а не всё сразу в одном merge. - Финальное вливание в
masterстановится тривиальным — достаточноgit checkout master && git merge feature/xxx, и в истории появится либо fast-forward (если ветку не переключали между rebase и merge), либо стандартный merge без лишних коммитов.
Возможные проблемы и как их избежать
1. Конфликты в каждом коммите
Если ваша фича долго живёт, а другие разработчики меняют те же файлы, то при rebase конфликты могут возникать на каждом из ваших коммитов. Это нормально. Решайте их последовательно, а после исправления конфликта выполняйте git add . && git rebase --continue. Если что-то пошло не так — git rebase --abort возвращает всё как было.
2. Переписанная история (force push)
После rebase ваша локальная ветка расходится с удалённой. При попытке git push Git откажется (non-fast-forward). Придётся использовать git push --force-with-lease (или --force, если вы уверены). Важно: если кто-то ещё работает с вашей веткой feature/xxx (например, вы открыли pull request и коллеги его смотрят), force push создаст им неудобства. Поэтому rebase публичной ветки — плохая практика. Идеально применять этот подход только к веткам, где вы работаете один.
3. Потеря контекста merge-коммитов при конфликтах
В редких случаях, если в вашей ветке уже были merge-коммиты с master ранее, rebase “распрямит” их, что может вызвать повторное появление уже решённых конфликтов. Поэтому перед rebase убедитесь, что ваша ветка не содержит случайных слияний. Если содержит — лучше сделать git rebase --interactive и убрать лишние merge-коммиты.
