Назад до блога

Git undo last commit: як скасувати коміт і не втратити зміни

3 вересня 2026 р.

TL;DR: щоб скасувати останній коміт, зберігши зміни, виконайте git reset --soft HEAD~1 (зміни залишаться застейдженими) або git reset HEAD~1 (зміни залишаться у робочому дереві). Якщо коміт уже запушено — виконуйте натомість git revert HEAD: він створює новий коміт, який скасовує старий без переписування історії. Ці три команди покривають майже кожен момент «я закомітив занадто рано». Решта гайду розбирає кожен випадок із командами для копіювання, пояснює різницю між --soft, --mixed і --hard і показує, як відновитися, якщо щось пішло не так. Кожна команда нижче працює на будь-якій свіжій інсталяції Git на Linux, macOS чи Windows.

Як скасувати останній коміт, зберігши зміни?

Найпоширеніша ситуація: ви закомітили, а тоді помітили одруківку, забутий файл або зрозуміли, що зміна належить до іншого коміта. Нічого не запушено. Скасовуйте коміт і повертайте все на місце:

# Коміт зникає з історії — зміни повертаються в область стейджингу
git reset --soft HEAD~1

# Зміни повертаються в робоче дерево (нестейджені)
git reset HEAD~1

HEAD~1 означає «один коміт до того місця, куди зараз вказує HEAD». Після будь-якої з команд файли на диску недоторкані — зсунувся лише вказівник гілки. Перевірте через git status: з --soft зміни застейджені, готові до повторного коміта з виправленнями; без прапорця вони нестейджені — можна спокійно редагувати спершу.

Безпечніша звичка, коли ви просто хочете додати файли до останнього коміта, — взагалі не скасовувати його:

git add forgotten-file.txt
git commit --amend --no-edit

--amend замінює останній коміт на місці (тут — без зміни повідомлення). Зауважте: amend запушеного коміта переписує історію — про це нижче.

У чому різниця між —soft, —mixed і —hard?

Це варто запам’ятати, бо прапорець вирішує, де опиняться ваші зміни — і чи можуть вони загинути:

ПрапорецьКоміт скасовано?Зміни на дискуЗастейджені?Типове застосування
--softТакЗбереженіТакПовторний коміт з дрібними виправленнями
--mixed (типовий)ТакЗбереженіНіПерегрупувати зміни, застейджити вибірково
--hardТакВидаленіВикинути роботу повністю
git revertНі (новий коміт)ЗбереженіСкасувати вже запушений коміт

--hard — єдиний небезпечний: він викидає і коміт, і зміни. Перед будь-яким reset --hard заховайте роботу у stash або гілку:

git branch backup-before-reset   # дешеве страхування
git reset --hard HEAD~1          # коміт і зміни зникли

Якщо небезпечна версія вже виконана — не все втрачено: git reflog пам’ятає, де був HEAD:

git reflog                       # знайдіть хеш втраченого коміта
git reset --hard HEAD@{1}        # або: git reset --hard <hash>

Reflog тримає повислі коміти близько 90 днів за замовчуванням, тож «я випадково зробив hard-reset» майже завжди можна відновити, якщо встигнути до збирання смiття.

А якщо коміт уже запушено?

Якщо коміт на спільній гілці (будь-що, окрім вашої власної feature-гілки), не переписуйте історію. Використовуйте git revert: він обчислює протилежну зміну і комітить її:

git revert HEAD
git push

Кожен, хто зробить pull, просто отримає новий коміт, що прибирає зміни старого. Жодного force-push, жодних зламаних колег. Якщо треба скасувати серію комітів, робіть revert діапазону: git revert --no-commit HEAD~3..HEAD && git commit.

Альтернатива — git reset --hard HEAD~1 && git push --force-with-lease — припустима лише на гілці, на якій ніхто інший не будує, а --force-with-lease (ніколи не гола --force) — єдина безпечна форма, бо відмовляє пуш, якщо хтось ушпорив у проміжку. Force-push спільних гілок — це спосіб, яким команди втрачають коміти, а лог CI загадково перестає збігатися з чиїмось чекаутом.

Як скасувати останній коміт, але залишити його про запас?

Іноді коміт — хороша робота за неправильною адресою: не та гілка або занадто рано. Замість скасування — перенесіть його:

git branch stash-commit          # припаркуйте коміт на новій гілці
git reset --hard HEAD~1          # тоді приберіть його з поточної

Або заберіть лише цей коміт на іншу гілку, не чіпаючи поточну:

git cherry-pick <hash>           # перебуваючи на цільовій гілці

Між reset --soft, cherry-pick і revert не існує коміта, який неможливо перемістити чи анулювати — трюк у тому, щоб вибрати «перемістити» чи «скасувати» ще до того, як тягнутися за прапорцем.

Яке скасування обрати? Швидкий путівник

  1. Не запушено, хочу виправити й перезакомітитиgit reset --soft HEAD~1
  2. Не запушено, хочу застейджити вибірковоgit reset HEAD~1 (mixed)
  3. Хочу, щоб зміни зникли повністюgit reset --hard HEAD~1 (reflog знає, якщо пошкодуєте)
  4. Вже запушено на спільну гілкуgit revert HEAD
  5. Коміт належить іншій гілціcherry-pick, не скасовуйте

Остання операційна порада: якщо поганий коміт таки дістався сервера — зіпсований deploy-хук, мандрівник CI, що здурів після force-push, — наступне місце пошуку це логи машини, а не Git. На будь-якій машині з systemd journalctl -u <service> -n 100 показує точно, що виконувалося і коли; у нашій шпаргалці journalctl є патерни для копіювання. А якщо ваш робочий потік включає локальні LLM-інструменти для ревʼю дифів, ми порівняли два головні варіанти у Ollama vs LM Studio.

— mrsaynothing

— mrsaynothing

Польові нотатки про ШІ, Linux і self-hosting.

Обговорити пост на dev.to dev.to ↗

Наступний гайд — на email

Один лист на пост. Полагодили — і далі.

self-hosted · без третіх сторін · відписка в один клік

що це таке?

Шпаргалка journalctl: хвости, фільтри й живий хвіст логів

Читається добре? Таке я будую за гроші. найміть мене