Урок 01 из 8 · 3 минуты чтения

Git — ветки, коммиты и отмена изменений

Как работать в ветке от первого коммита до push, чем merge отличается от rebase, как отменять изменения и разрешать конфликты.

Ветка — для каждой задачи

Работа идёт не в main, а в отдельной ветке от её актуальной версии:

git switch main
git pull
git switch -c feature/login

Дальше цикл повторяется:

git status          # что изменилось
git diff            # как именно
git add src/login.py
git commit -m "Добавить вход по коду из письма"

Индекс (staging) — промежуточная зона: в коммит попадает только то, что добавлено через git add. Перед каждым коммитом смотрят git status и git diff — так в историю не попадают отладочные строки, лишние файлы и секреты.

Готовую ветку отправляют на сервер и открывают pull request:

git push -u origin feature/login

Хороший коммит

  • Одно логическое изменение, которое собирается и проходит тесты.
  • Сообщение — что и зачем, в повелительном наклонении: «Добавить вход по коду», «Исправить округление в итоговой сумме».
  • «fix», «wip», «правки» — плохие сообщения: через месяц никто не поймёт, что в них.

В .gitignore заносят то, что не должно попасть в репозиторий: результаты сборки, зависимости, файлы IDE и секреты.

merge и rebase

Ветка отстала от main — её нужно обновить. Есть два способа.

  • merge соединяет ветки коммитом слияния, история остаётся как была.
  • rebase переносит коммиты ветки поверх main. Получаются новые коммиты с другими хешами, история становится линейной.

Отсюда главное правило: rebase переписывает историю, поэтому его делают только с локальными или личными ветками. Переписать опубликованную общую ветку — значит сломать работу коллег, у которых остались старые коммиты. Если личную ветку после rebase нужно отправить снова — git push --force-with-lease: в отличие от --force, он не затрёт чужие новые коммиты.

Конфликты

Конфликт возникает, когда обе ветки изменили одни и те же строки. Git отмечает их в файле:

<<<<<<< HEAD
total = price * count
=======
total = round(price * count, 2)
>>>>>>> feature/rounding

Сверху — ваша версия, снизу — входящая. Нужно понять смысл обоих изменений и собрать правильный итог — часто это комбинация. Затем убрать маркеры, git add и продолжить: git commit или git rebase --continue. После — обязательно собрать проект и прогнать тесты: код без маркеров ещё не значит рабочий.

Запутались — git merge --abort или git rebase --abort вернут всё как было. Частые небольшие слияния дают меньше конфликтов, чем одно большое в конце.

Как отменить

Что нужноКоманда
Отменить правки в файлеgit restore файл
Убрать файл из индексаgit restore --staged файл
Поправить последний неопубликованный коммитgit commit --amend
Отменить локальные коммиты, сохранив правкиgit reset --soft HEAD~1
Отменить опубликованный коммитgit revert <хеш>

git reset двигает ветку назад и годится только для локальных коммитов. --hard при этом удаляет изменения — самый частый способ потерять работу. git revert создаёт новый коммит, отменяющий старый, и историю не переписывает — поэтому для опубликованного используют его.

Если всё-таки потеряли коммит — git reflog помнит, куда указывала ветка, и позволяет вернуться.

Что запомнить

  • Каждая задача — в своей ветке, каждый коммит — одно изменение.
  • Перед коммитом — git status и git diff.
  • rebase — только для неопубликованного, push после него — с --force-with-lease.
  • reset — для локального, revert — для опубликованного.

Проверка урока

Войдите, чтобы проверить себя: сданные проверки всех уроков курса отмечают его темы пройденными на карте и в ИПР.

Вопросы по теме

Читайте также

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования