Короткий ответ
Историю приводят в порядок через git rebase -i — объединяя (squash/fixup) промежуточные коммиты в логичные смысловые блоки с понятными сообщениями; это безопасно для ветки, которой пользуетесь только вы, но рискованно для ветки, которую уже вытянул себе кто-то другой, так как переписывание истории меняет хэши коммитов и ломает их локальные копии.
Как это работает подробнее
git rebase -i HEAD~15 открывает список коммитов, где можно пометить их как pick, squash, fixup или reword, после чего Git пересоздаёт их в новом виде с новыми хэшами; это чисто локальная операция, пока изменения не запушены.
Пример кода
example-485.sh
git checkout feature/login
git fetch origin
git rebase -i HEAD~15
# в открывшемся списке: оставить первый коммит pick, остальные fixup/squash,
# задать итоговое сообщение коммита
# после проверки, что тесты проходят:
git push --force-with-lease origin feature/loginЧто использовать на практике
- Рекомендация. безопасный порядок — выполнить интерактивный rebase локально, проверить, что тесты всё ещё проходят после объединения коммитов, и запушить веткой с
--force-with-lease(не просто--force, чтобы не затереть чужие изменения, появившиеся в ветке без вашего ведома). Если над той же веткой уже работает кто-то другой, перед rebase стоит явно согласовать с ним момент переписывания истории.
Подводные камни
- Ошибка. делать
git push --forceвместо--force-with-lease, рискуя затереть чужие коммиты, которые появились в ветке между вашимfetchиpush; переписывать историю ветки, из которой уже открыт PR с комментариями, привязанными к конкретным строкам конкретных коммитов — часть контекста ревью может потеряться.