Как объединить несколько коммитов в один

«Как объединить несколько коммитов в один» — вопрос из категории Git, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для объединения (squash) коммитов я использую интерактивный rebase (git rebase -i). Это стандартный способ привести историю в порядок перед мержем в основную ветку, например, в main или master, особенно в рамках Pull/Merge Request.

Типичный сценарий: У меня есть ветка feature/auth, в которой за время разработки накопилось несколько коммитов типа "WIP", "Fix typo", "Add tests". Перед созданием PR я хочу объединить их в один логичный коммит "Implement user authentication".

Процесс:

  1. Убедиться, что я на нужной ветке и рабочая директория чиста.
    git status
    git checkout feature/auth
  2. Запустить интерактивный rebase относительно точки, от которой ответвилась моя ветка (или указав количество коммитов).
    # Способ 1: Указать хэш коммита, ПРЕДШЕСТВУЮЩИЙ первому коммиту, который нужно сквошить
    git rebase -i main
    # Способ 2: Объединить последние N коммитов от HEAD
    git rebase -i HEAD~3
  3. В открывшемся редакторе я вижу список коммитов. Для коммитов, которые нужно объединить с предыдущим, я заменяю pick на squash (или просто s). Самый старый коммит в списке оставляю как pick — он станет основой.
    pick a1b2c3d Implement user authentication logic
    squash e4f5g6h Add unit tests for auth service
    squash i7j8k9l Fix typo in login error message
  4. После сохранения и закрытия редактора Git откроет еще один редактор для редактирования итогового сообщения коммита. Я удаляю автоматически сгенерированные сообщения от сквошенных коммитов и оставляю одно четкое, например:

    Implement user authentication
    
    - Add JWT-based login and registration endpoints
    - Integrate with PostgreSQL user table
    - Add comprehensive unit and integration tests
    - Update API documentation
  5. После сохранения коммит будет создан. Так как история переписана, для отправки на удаленный репозиторий потребуется force-push.
    git push origin feature/auth --force-with-lease

    Важное предупреждение: --force-with-lease безопаснее --force, так как проверит, что никто другой не пушил в эту ветку после вашего последнего fetch. Никогда не делайте force-push в общие ветки (main, develop).

Альтернатива для простых случаев: Если нужно просто объединить последние N коммитов без переупорядочивания, можно использовать git reset --soft:

git reset --soft HEAD~3  # Перемещает HEAD на 3 коммита назад, оставляя все изменения в staged состоянии
git commit -m "New combined commit message"