git stash, reflog и reset: сохранение и спасение изменений
Коротко: С помощью stash вы откладываете незавершённую работу, с помощью reset откатываете состояния, а reflog помогает восстановить почти любой, казалось бы, потерянный коммит.
Подробнее: Git хранит гораздо больше, чем вы думаете: даже после reset --hard, случайно удалённой ветки или неудавшегося rebase часто можно спасти всё, если действовать быстро. Достаточно небольшого репертуара.
Подробности
git stash: отложить работу
git stash # отложить текущие изменения
git stash -u # также новые (неотслеживаемые) файлы
git stash list # список
git stash pop # вернуть последний stash (и удалить)
git stash apply stash@{1} # вернуть конкретный (сохранить)
git stash drop # удалить
git stash push -m "experiment" file.txtПолезно, когда нужно быстро переключить ветку, не делая коммит. Stash принадлежат только локально вам; важную работу лучше закоммитить в отдельную ветку.
git reset: сброс
git reset --soft HEAD~1: отменить последний коммит, изменения остаются подготовленными (staged).git reset HEAD~1(mixed): отменить коммит, изменения остаются в рабочем каталоге.git reset --hard HEAD~1: отбросить коммит и изменения (опасно!).git restore fileотбрасывает изменения файла,git restore --staged fileубирает его из области подготовки.- В общих ветках лучше
git revert <commit>, чем reset: создаёт новый коммит, отменяющий изменение без переписывания истории.
git reflog: страховочная сетка
Reflog записывает, куда указывали HEAD и ветки в последние недели:
git reflog
git reset --hard e4f5g6h # восстановить старое состояние
git branch rescued e4f5g6h # или сохранить как новую веткуТак восстанавливаются потерянные коммиты после неверного reset, rebase или удалённой ветки (по умолчанию около 90 дней, только в локальном репозитории).
Типичные спасения
- Ветка удалена случайно:
git reflog, затемgit branch name <sha>. - Rebase сломан:
git rebase --abortилиgit reset --hard ORIG_HEAD. - Закоммитили не в ту ветку:
git branch new, затем в старойgit reset --hard HEAD~1. - Файл удалён, но был закоммичен:
git restore --source=<commit> -- file. - Никогда не коммитили: тогда Git часто не может помочь; коммитьте регулярно, даже незавершённое (WIP-коммиты), и наводите порядок позже.
См. также: Git, git rebase, git bisect и cherry-pick, Разрешение конфликта слияния, Push отклонён