Антон Ларичев

Введение
Git — это распределённая система контроля версий, без которой сегодня невозможно представить работу ни одного разработчика. Если вы только начинаете, может казаться, что хватит знаний git add, git commit и git push. Но как только вы попадаете в команду, всё становится сложнее: ветки расходятся, появляются конфликты, история коммитов превращается в кашу.
В этой статье разберём, как правильно работать с ветками, чем merge отличается от rebase, как избежать типовых ошибок и выстроить процесс командной разработки.
Работа с ветками
Ветка в Git — это просто указатель на конкретный коммит. Создание ветки занимает миллисекунды и не копирует файлы, что делает ветвление дешёвой операцией.
# Создать новую ветку и переключиться на неё
git checkout -b feature/user-profile
# Современный синтаксис (Git 2.23+)
git switch -c feature/user-profile
# Посмотреть все ветки
git branch -a
# Удалить локальную ветку
git branch -d feature/old-feature
Для именования веток в команде обычно используют префиксы: feature/, bugfix/, hotfix/, refactor/. Это помогает быстро понять назначение ветки и автоматизировать CI/CD.
Стратегии ветвления
Самые популярные подходы:
- Git Flow — отдельные ветки
develop,release,hotfix. Подходит для проектов с релизными циклами. - GitHub Flow — одна основная ветка
mainи короткоживущие feature-ветки. Идеально для continuous deployment. - Trunk-Based Development — почти все работают в
main, ветки живут часы, не дни.
Merge: классическое слияние
Команда git merge объединяет изменения из одной ветки в другую, создавая специальный merge-коммит с двумя родителями.
# Переключаемся на целевую ветку
git switch main
# Сливаем изменения из feature-ветки
git merge feature/user-profile
# Если хотим всегда видеть merge-коммит даже при fast-forward
git merge --no-ff feature/user-profile
Плюсы merge: сохраняется полная история, видно, когда и какая ветка была влита. Минусы: история становится нелинейной и сложно читаемой, особенно при большом числе разработчиков.
Fast-forward vs no-ff
Если целевая ветка не уходила вперёд, Git просто передвинет указатель — это и есть fast-forward. При флаге --no-ff создаётся явный merge-коммит, что часто полезно для отслеживания фич.
Rebase: переписывание истории
git rebase берёт коммиты вашей ветки и «переносит» их поверх другой ветки, создавая линейную историю.
# Находимся в feature-ветке
git switch feature/user-profile
# Переносим коммиты поверх main
git rebase main
# Интерактивный rebase для редактирования последних 3 коммитов
git rebase -i HEAD~3
Интерактивный rebase — мощный инструмент: можно объединять коммиты (squash), переименовывать (reword), удалять (drop) или менять порядок. Это позволяет приводить историю в порядок перед отправкой Pull Request.
Золотое правило rebase
Никогда не делайте rebase веток, которые уже запушены и используются другими разработчиками. Rebase переписывает коммиты — у них меняются хэши. Если коллега уже работал поверх старых коммитов, его репозиторий «развалится».
# Безопасный push после rebase
git push --force-with-lease
Флаг --force-with-lease безопаснее обычного --force — он откажется перезаписать чужие изменения, которые появились в удалённой ветке.
Разрешение конфликтов
Конфликты возникают, когда Git не может автоматически объединить изменения в одном и том же месте файла.
# После git merge или rebase видим конфликт
git status
# Открываем файл, ищем маркеры
# <<<<<<< HEAD
# наш код
# =======
# код из другой ветки
# >>>>>>> feature/branch
После ручного разрешения:
# Помечаем файл как разрешённый
git add src/components/Profile.tsx
# Для merge — создаём финальный коммит
git commit
# Для rebase — продолжаем процесс
git rebase --continue
# Если что-то пошло не так
git rebase --abort
Полезно настроить инструмент визуального мержа, например meld, kdiff3 или встроенный в VS Code.
Работа в команде
Хорошие практики, которые экономят часы и нервы:
- Часто синхронизируйтесь с main:
git pull --rebase origin mainкаждое утро. Чем дольше ветка живёт оторвано, тем больнее будет слияние. - Маленькие Pull Requests: PR на 200 строк проверят за 15 минут, PR на 2000 строк не проверит никто.
- Атомарные коммиты: один коммит = одно логическое изменение. Сообщение в формате
тип(область): описание, напримерfeat(auth): добавить вход через GitHub. - Squash перед мержем: если в ветке 20 коммитов «fix», «опечатка», «ещё раз» — сожмите их в один осмысленный.
# Обновить feature-ветку без лишнего merge-коммита
git pull --rebase origin main
# Просмотр изменений перед коммитом
git diff --staged
Частые ошибки
Force push в общую ветку. git push --force в main или develop затирает работу всей команды. Защищайте основные ветки в настройках репозитория.
Rebase запушенных коммитов. Если ветка уже на сервере и над ней работают другие — не делайте rebase. Используйте merge.
Огромные коммиты «всё подряд». Коммит на 50 файлов с сообщением «работает» невозможно ни прочитать, ни откатить. Разбивайте работу.
Игнорирование .gitignore. Случайно закоммиченный node_modules, .env с секретами или .DS_Store — классика. Настройте .gitignore сразу.
Работа в main напрямую. Даже для одной строчки создавайте ветку. Так история чище и легче откатить изменения.
Забытый git stash. Если переключаетесь между задачами с незакоммиченными изменениями, используйте git stash вместо рискованных манипуляций.
# Сохранить текущие изменения
git stash push -m "работа над профилем"
# Посмотреть список
git stash list
# Вернуть последний stash
git stash pop
Заключение
Git становится по-настоящему мощным, когда вы понимаете не только команды, но и модель данных за ними. Ветки — это указатели, коммиты — снимки состояния, merge и rebase — два разных способа объединить историю.
Запомните главное: merge сохраняет историю как было, rebase делает её линейной и красивой, но требует осторожности. В команде договоритесь о единой стратегии ветвления, защитите основные ветки и пишите осмысленные коммит-сообщения. Эти простые правила превращают Git из источника боли в надёжный инструмент совместной работы.






Комментарии
0