Как удалить или изменить коммит, находящийся далеко в истории Git
Что проверяют
Понимаете ли вы, чем переписывание истории отличается от отмены изменений, и чувствуете ли границу, за которой force push ломает работу команды. Следом спрашивают, что делать, если коммит уже в main, и чем revert отличается от reset.
Как отвечать
Покажите инструмент под каждую задачу:
- изменить старый коммит:
git rebase -i <hash>^, у нужной строкиpickменяют наedit. Git остановится на коммите, вы правите код, делаетеgit add,git commit --amendиgit rebase --continue; - поправить только сообщение:
rewordв том же списке; - убрать коммит:
dropили удалить строку. Последующие коммиты применятся заново, и конфликты придётся решать по одному; - дописать в старый коммит:
git commit --fixup=<hash>иgit rebase -i --autosquash <hash>^. Так чистят ветку перед ревью, не переставляя строки руками; - отменить в общей ветке:
git revert <hash>создаёт обратный коммит, история остаётся прежней. Для merge-коммита нужен-m 1, чтобы указать основную линию; - страховка:
git reflogпомнит, где былHEAD, и неудачный rebase откатывается черезgit reset --hard HEAD@{n}.
Фронтенд-специфика. При rebase через десятки коммитов почти неизбежен конфликт в package-lock.json или pnpm-lock.yaml. Руками его не сливают: берут одну из версий, запускают npm install или pnpm install, чтобы менеджер пакетов пересобрал lock-файл, и добавляют результат через git add. Если в истории оказался .env с ключами API, rebase недостаточно: историю чистят git filter-repo, а ключ перевыпускают, потому что он уже разошёлся по клонам.
Где спотыкаются
Путают reset и revert. git reset --hard HEAD~3 в общей ветке после пуша потребует force push и сотрёт чужую работу, а revert решает ту же задачу без переписывания истории.
Пушат переписанную ветку через --force, а не --force-with-lease. Если коллега успел добавить коммит в ту же ветку пул-реквеста, он исчезнет молча.
Решают конфликт в lock-файле через --theirs, думая, что это их версия. При rebase стороны меняются местами: ours это ветка, на которую вы переносите коммиты, а theirs ваши собственные коммиты.