Как откатиться назад на стабильный commit и при этом сохранить полезный код, который ты сделал после допущенной ошибки?
На практике редко ошибки правятся "выдиранием" одного коммита из истории, но такая операция вполне себе возможна.
Вариант номер один - интерактивный ребейз, и в нем указываешь какие коммиты дропнуть. Если коммитов много, то можно задолбаться решать конфликты
Вариант номер два - просто делаешь новый коммит с реверсом изменений из коммита, который привел к проблемам
Вариант третий - делаешь новый бранч, откатываешся до проблемного коммита, потом из полного бранча накатываешь остальные изменения.

Все сценарии приблизительные, потому что каждая проблема требует комплексоного подхода и знания возможностей инструмента, поэтому не поленись, а почитай вот это внимательно и полностью
https://git-scm.com/book/en/v2
Способов отменить изменения в гите множество, их варианты в ответах озвучили.
На мой вкус, для отмены изменений одного коммита, идеологически правильно выполнить git revert для этого коммита. Revert создаст новый комммит, отменяющий действия отменяемого коммита. Таким образом можно зафиксировать в истории репозитория факт отмены и, например, пометить причину совершенной отмены.
Так же, если вдруг нужно отменить не весь коммит, а только часть его изменений, можно выполнить частичный revert:
git revert <плохой_коммит> --no-commit # Revert будет подготовлен, но не закомичен
git reset # Выполнить unstage всех файлов
git add ... список плохих файлов  # Добавляем в индекс те файлы, что требуется отревертить. Используя ключ -p можно добавить часть изменений в файле, а не файл целиком.
git checkout . # Сбрасываем все прочие файлы, что не в индексе, до оригинального состояния
git commit # Коммитим revert