EMZETT.
Войти

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 отклонён