В чем разница между git commit —amend и squash (в git rebase)?

«В чем разница между git commit —amend и squash (в git rebase)?» — вопрос из категории Git, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Обе команды изменяют историю коммитов, но работают на разных масштабах и для разных целей.

git commit --amend

  • Что делает: Позволяет модифицировать последний коммит в текущей ветке. Можно изменить его сообщение или добавить в него новые staged-изменения.
  • Когда использовать: Для быстрого исправления опечаток в сообщении только что сделанного коммита или чтобы добавить забытый файл, не создавая отдельный "fix" коммит.
  • Пример:
    # 1. Сделали коммит
    git commit -m "Add new feture" # Опечатка!
    # 2. Исправляем сообщение
    git commit --amend -m "Add new feature"
    # ИЛИ добавляем забытый файл
    git add forgotten_file.py
    git commit --amend --no-edit  # Сохраняем старое сообщение

git rebase --interactive с squash

  • Что делает: Позволяет объединить (сжать) несколько последовательных коммитов в один (или меньшее количество) в процессе перемещения (rebase). Это инструмент для переписывания истории.
  • Когда использовать: Для очистки истории перед слиянием feature-ветки в основную (main/master). Например, чтобы объединить множество мелких "wip" или "fix" коммитов в один логический блок.
  • Пример:
    # Мы в ветке feature-branch с коммитами A-B-C-D
    git rebase -i HEAD~4  # Запускаем интерактивный rebase для последних 4 коммитов
    # В редакторе меняем 'pick' на 'squash' (или 's') для коммитов B, C, D:
    # pick a1b2c3d Add core logic
    # squash e4f5g6h Fix typo
    # squash i7j8k9l Refactor method
    # squash m1n2o3p Update README
    # После сохранения Git предложит создать одно новое сообщение для объединенного коммита.

С точки зрения DevOps-практик:

  • amend — это локальная операция для "косметических" правок в процессе работы.
  • squash — это часть стратегии поддержания чистой, линейной и понятной истории в основной ветке. Часто используется в паре с политикой "Squash and Merge" на платформах вроде GitHub/GitLab, когда все коммиты из PR сливаются в main одним коммитом.