# git stash _Ежедневная работа · GitLab Knowledge Base_ **TL;DR:** Прячет незакоммиченные правки в специальный стек, очищает рабочее дерево до состояния HEAD. Полезно, когда нужно срочно переключиться на другую ветку, но коммитить сейчас рано. Типичная ситуация: правишь файлы, не готов коммитить, и тут срочно нужно переключиться на другую ветку - посмотреть PR, починить hotfix. Не хочется ни коммитить «WIP», ни терять работу. `git stash` отдаст рабочее дерево в специальный «карман», после чего можно переключаться и работать. Когда вернёшься - `git stash pop` восстановит правки. ## Базовый цикл ```bash git stash # спрячь текущие правки git switch hotfix # переключись куда нужно # ... поработать ... git switch feature # вернись на ветку git stash pop # верни правки ``` По умолчанию `stash` забирает и working tree, и индекс (всё кроме untracked файлов). Чтобы включить untracked: ```bash git stash -u # + untracked git stash -a # + untracked + ignored (всё подряд) ``` ## С сообщением Без сообщения stash получит auto-имя «WIP on feature: abc123 last commit subject». Это плохо читается. Лучше с описанием: ```bash git stash push -m "поправил auth, не доделал logout" ``` ## Список и просмотр ```bash git stash list # stash@{0}: On feature: поправил auth, не доделал logout # stash@{1}: WIP on main: 7c8a1 fix typo git stash show stash@{0} # сводка git stash show -p stash@{0} # полный diff ``` ## pop vs apply - `git stash pop` - применить и удалить из списка. - `git stash apply` - применить, оставить в списке. Apply удобен, если stash может пригодиться ещё раз. Pop - когда знаешь, что больше не понадобится. По умолчанию обе команды берут `stash@{0}` (самый свежий). Можно указать другой: ```bash git stash pop stash@{2} ``` ## stash branch Если после stash ветка ушла далеко и pop приводит к конфликтам - можно достать stash как отдельную ветку: ```bash git stash branch fix-from-stash stash@{0} ``` Создаст ветку из коммита, на котором stash был сделан, и применит stash в чистой среде. Дальше можно нормально работать и сливать. ## Что физически Stash entry - это merge-коммит в `refs/stash` (не видим в обычных branch listings). У него минимум два родителя: - **первый** - HEAD на момент stash; - **второй** - коммит снимка индекса. С `-u` / `-a` добавляется ещё один родитель - коммит со снимком untracked (и ignored) файлов. Итого в `.git/objects/` под один `git stash` ложится 3-4 объекта. Stash можно восстановить через [reflog](/courses/git/kb/reflog.md) даже после `stash drop` (по `stash@{N}` SHA). ## Подводные камни - **Stash без `-u` не прячет untracked.** Untracked-файлы не «теряются» - они остаются в working tree, как лежали. Просто кажется, что «всё спрятано», а после `git switch` или `git checkout .` эти файлы видны в новом контексте. Если хочешь реально убрать untracked - `git stash -u`. - **pop с конфликтом не удаляет stash.** Если применение упало в конфликт, stash остаётся в списке. После разрешения нужно `git stash drop stash@{0}` руками. - **Долго живущий stash - антипаттерн.** Чем дольше stash лежит, тем больше main уходит вперёд, тем больнее pop. Если работа важна - лучше сделать ветку и коммит. - **`git stash clear` удаляет всё без подтверждения.** Если нужно очистить - лучше `git stash drop` по одному, чтобы случайно не потерять. ## Команды ```bash git stash ``` Спрятать текущие правки (без untracked) ```bash git stash -u -m "описание" ``` С untracked и сообщением ```bash git stash pop ``` Применить и удалить последний stash ```bash git stash branch stash@{0} ``` Достать stash как новую ветку (для случаев с конфликтом) ## См. также - [git reflog](/courses/git/kb/reflog.md) - [Ветка (branch)](/courses/git/kb/branch.md)