Как откатиться назад на стабильный commit и при этом сохранить полезный код, который ты сделал после допущенной ошибки?

Недавно я начал знакомство с GIT и у меня возник вопрос.

Представим такую ситуацию.

День 1. Я создал файл script.js. Написал немного кода. Проверил, чтобы всё было без ошибок. Сделал commit.
Теперь у меня есть стабильный файл script.js. Если что-то случится в будущем, то я могу откатиться на этот commit.

День 2. Вот я снова начал писать код в файл script.js и допустил незаметную ошибку, из-за которой в будущем могут возникнуть серьезные проблемы и которую нельзя просто так исправить. Из-за этой ошибки в любом случае придётся откатывать проект снова на "День 1". Но сейчас я про это не знаю, поэтому довольный делаю commit.

День 3. На следующий день, я снова начал работать с файлом script.js. Написал ПОЛЕЗНЫЙ код, сделал commit.
И так я работал в течении нескольких дней. После "День 2", когда я допустил фатальную ошибку, я еще написал очень много ПОЛЕЗНОГО кода в "День 3", "День 4" и т.д. Добавил много разных фич и т.д.

Вот в определенный момент я обнаруживаю, что оказывается когда-то я допустил ошибку. И теперь придётся откатываться к стабильному commit. Но из-за этой ошибки пропадает много полезного кода. Как быть в такой ситуации?
День 1, 2, 3 это лишь пример для упрощения ситуации. Подобная проблема может возникнуть на любой стадии разработки.
Как откатиться назад на стабильный commit и при этом сохранить полезный код, который ты сделал после допущенной ошибки?
  • Вопрос задан
  • 354 просмотра
Решения вопроса 1
На практике редко ошибки правятся "выдиранием" одного коммита из истории, но такая операция вполне себе возможна.
Вариант номер один - интерактивный ребейз, и в нем указываешь какие коммиты дропнуть. Если коммитов много, то можно задолбаться решать конфликты
Вариант номер два - просто делаешь новый коммит с реверсом изменений из коммита, который привел к проблемам
Вариант третий - делаешь новый бранч, откатываешся до проблемного коммита, потом из полного бранча накатываешь остальные изменения.

Все сценарии приблизительные, потому что каждая проблема требует комплексоного подхода и знания возможностей инструмента, поэтому не поленись, а почитай вот это внимательно и полностью
https://git-scm.com/book/en/v2
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Erik_Mironov
@Erik_Mironov
Старые вопросы: *Dies from cringe*
Временно переключиться на другой коммит:

Вы можете временно переключиться на другой коммит:

git checkout <your_commit_sha>

Если вы хотите делать коммиты, пока вы временно на другой ветке:

git checkout -b old-state <your_commit_sha>

Чтобы вернуться туда, где вы были, просто снова checkout ветку, в которой вы были. (Если вы внесли изменения, при переключении веток, вам придется обращаться с ними соответствующим образом.

Отменить раннее опубликованные коммиты новыми коммитами:

Если вы опубликовали изменения, вы, вероятно, не захотите сбрасывать ветку, так как это фактически перепишет историю коммитов. Создайте коммит с обратным патчем, чтобы отменить его. Таким образом, вы не переписываете историю коммитов. Вы можете поступить следующим образом:

# Это создаст три отдельных коммита возврата:
git revert <your_commit_sha1> < your_commit_sha2> <your_commit_sha3>
# Это вернет последние два коммита. Также принимает диапазоны:
git revert HEAD~2..HEAD
# Точно так же вы можете отменить ряд коммитов, используя хэши коммитов (не включая первый хеш):
git revert <your_commite_sha>
# Отмена мердж коммита:
git revert -m 1 <merge_commit_sha>
# Чтобы получить только один коммит, вы можете использовать 'rebase -i', 
# Или вы можете сделать это вручную (обязательно сделайте это на верхнем уровне вашего репозитория)
# Привести ваш индекс и дерево в нужное состояние, не меняя HEAD:
git checkout <your_target_commit_sha>
# После чего обязательно зафиксируйте коммит. Будьте уверены в том, что вы сделали на 150% и напишите хорошее сообщение с описанием того, что вы только что сделали:
git commit


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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы