git undo keep changes — FAQ для всех испуганных написаний
FAQ для каждого написания «отменить коммит, но оставить работу» — одна команда отвечает за всю семью, а единственный флаг, удаляющий работу, никогда не требуется.
■ space · прозаический ряд · faq
Одна команда отвечает за всю семью — git reset --soft HEAD~1 отступает ярлыком ветки на коммит назад и возвращает вашу работу уже проиндексированной.
Undo, cancel, revert — это не три функции git. Два из них — один и тот же reset с разным акцентом; revert — странный, потому что добавляет историю, а не перематывает её.
Уже запушено? Revert, никогда не переписывать — каждый, кто сделал pull, держит старые коммиты.
git reset --soft HEAD~1 — ответ на каждое написание keep-changes: ярлык ветки отступает на коммит, работа возвращается проиндексированной, готовой к новому коммиту. Коммит уже запушен? Используйте вместо этого git revert HEAD — он добавляет обратный коммит и ничего не переписывает.ТАБЛИЦА ГЛАГОЛОВ
Каждое слово, которое люди вводят, что git делает на самом деле и выживает ли работа:
| Глагол, который вводят | Что git делает на деле | Сохраняет работу? | Команда |
|---|---|---|---|
| «undo» | Ярлык ветки отступает на коммит; изменения возвращаются проиндексированными | Да — в индексе | git reset --soft HEAD~1 |
| «cancel» | Reset по умолчанию: ярлык отступает, изменения возвращаются, но без индекса | Да — в рабочем дереве | git reset HEAD~1 |
| «revert» | Добавляется новый коммит, отменяющий старый; история никогда не переписывается | Да — в виде обратного диффа | git revert HEAD |
| «unstage» | Пути уходят из индекса; содержимое файлов не тронуто | Да — из рабочего дерева ничего не ушло | git restore --staged file.txt |
| «отложить пока» | Работа пакуется и кладётся на полку, откуда её можно достать позже | Да — в стопке stash | git stash push -m "wip" |
Единственное решение, которое важно: кто-нибудь сделал pull?
Нет — всё ещё ваше: git reset --soft HEAD~1. Ярлык отступает, работа возвращается проиндексированной. Да — кто-то сделал pull: git revert HEAD. История обрастает обратным коммитом; ничто из вытянутого не переписывается. В обоих случаях работа выживает — выбор лишь о том, чья копия истории останется истинной. А если пугающий вас флаг — --hard: это единственный член семьи, удаляющий работу, и для сохранения изменений он никогда не требуется. Вы и нашли эту страницу именно затем, чтобы никогда его не вводить.
Что --soft на самом деле сохраняет?
Всё, проиндексировано. Коммит покидает ветку, дифф возвращается в индекс ровно таким, каким был закоммичен, и git status показывает «changes to be committed». Почините то, что собирались, и закоммитьте заново — или сначала подмешайте ещё работы. Это шаг до --amend: amend переписывает последний коммит на месте; soft отменяет его и ждёт вас.
Amend — это undo?
Маленький, и только для последнего коммита. git commit --amend --no-edit подмешивает проиндексированные изменения в только что сделанный коммит — идеально для забытого файла. Правило раздела про запушенные коммиты всё ещё действует: amend запушенного коммита переписывает историю, так что на общей ветке — revert.
Когда --hard всё-таки правильный ответ?
Когда вы хотите, чтобы рабочее дерево точно совпало с коммитом, и вы посмотрели, что будет потеряно. git reset --hard HEAD~1 отбрасывает коммит и незакоммиченные правки одним движением — git не спросит дважды. Ритуал безопасности — одна строка: сначала git branch backup-before-reset; ветки бесплатны. А если уже выполнили, git reflog помнит, где был HEAD, около 90 дней — git reset --hard HEAD@{1} вернёт назад.
Как выбросить правки только в одном файле?
git restore file.txt — современное написание старого git checkout -- file. Он отбрасывает правки рабочего дерева только этого пути и больше ничего не трогает: ни движения ветки, ни изменений индекса. Чтобы вернуть файл к конкретному коммиту: git restore --source <sha> file.txt.
Куда вписывается stash в семействе?
Stash — единственный глагол, который упаковывает работу, а не перемещает её. git stash push -m "wip" откладывает правки на полку и отдаёт чистое дерево; git stash pop возвращает их. Это правильный инструмент, когда нужно переключить ветку посреди задачи — и он принимает pathspec, так что один файл можно отправить на полку, пока остальное остаётся грязным.
Я уже выполнил не ту команду. Работа потеряна?
Почти никогда. Reset двигает ярлык; revert добавляет коммит; объекты не удаляет никто. git reflog перечисляет все места, где побывал HEAD, за ~90 дней — найдите запись до ошибки, и git reset --hard HEAD@{n} вернёт вас туда. По-настоящему невосстановимо лишь узкое множество: неотслеженные файлы, удалённые git clean -f, и записи reflog, вышедшие за свой срок.
конец семейства глаголов · ничего не скачано · всё локально