git stash
Временное сохранение незафиксированных изменений для последующего применения
Описание
git stash временно «прячет» незафиксированные изменения рабочего каталога и индекса, возвращая репозиторий к чистому состоянию последнего коммита. Изменения сохраняются в специальное хранилище (stash stack) и могут быть восстановлены позже. Это позволяет быстро переключиться на другую задачу, не делая «грязного» коммита.
Stash работает по принципу стека (LIFO): каждый новый git stash push кладёт запись наверх. Записи адресуются как stash@{0} (последняя), stash@{1} (предыдущая) и т.д. По умолчанию stash сохраняет изменения отслеживаемых файлов (tracked) — как staged, так и unstaged. Неотслеживаемые (untracked) и игнорируемые файлы требуют явных флагов.
Типичные сценарии: срочный hotfix когда работаешь над фичей; переключение контекста между задачами; перенос изменений на другую ветку; временное «откладывание» экспериментального кода перед pull или rebase.
Синтаксис
Флаги и опции
| Флаг / подкоманда | Описание |
|---|---|
push |
Основная подкоманда: сохранить текущие изменения в stash (вызывается и без слова push) |
pop |
Применить последний (или указанный) stash и удалить его из стека |
apply |
Применить stash, не удаляя из стека (можно применить несколько раз) |
list |
Показать все сохранённые stash-записи с их индексами |
show |
Показать статистику изменений stash; с -p — полный diff |
drop |
Удалить указанную stash-запись без применения |
clear |
Удалить все stash-записи безвозвратно |
branch <ветка> |
Создать новую ветку от коммита, на котором был создан stash, и применить его там |
-m, --message |
Добавить описание к stash-записи для удобной идентификации |
-u, --include-untracked |
Включить в stash неотслеживаемые (untracked) файлы |
-a, --all |
Включить в stash всё: untracked и игнорируемые файлы (.gitignore) |
-p, --patch |
Интерактивный выбор фрагментов изменений для сохранения в stash |
-k, --keep-index |
Сохранить в stash только unstaged изменения; staged оставить в индексе |
--index |
При apply/pop: восстановить и staged, и unstaged состояние как было |
Паттерны использования
Срочный hotfix при незавершённой работе
# Спрятать текущую работу git stash push -m "wip: feature/payment refactoring" # Переключиться и исправить git switch main git switch -c hotfix/critical-bug # ... исправить ... git commit -m "fix: critical null pointer in checkout" git switch main git merge --no-ff hotfix/critical-bug # Вернуться к своей задаче git switch feature/payment git stash pop
Управление несколькими stash
# Просмотр всех stash
git stash list
# stash@{0}: On main: wip: login form
# stash@{1}: On feature/x: experiment
# Применить конкретный stash
git stash apply stash@{1}
# Просмотр содержимого stash
git stash show -p stash@{0}
Перенести изменения на другую ветку
# Начал работать не на той ветке! git stash push -m "feature work on wrong branch" git switch correct-feature-branch git stash pop # Изменения теперь на правильной ветке
Stash с untracked-файлами
# Стандартный stash НЕ включает новые файлы git stash push # новые файлы остаются! # Включить все файлы git stash push -u -m "full wip with new files" # Или всё включая .gitignore git stash push -a -m "complete snapshot"
Создать ветку из stash
# Если stash pop конфликтует — создать ветку
git stash branch feature/recovered stash@{0}
# Git:
# 1. Создаст ветку от точки, где был stash
# 2. Применит stash
# 3. Удалит запись из стека
Частичный stash (--patch)
# Выбрать конкретные изменения интерактивно git stash push -p -m "only layout changes" # Для каждого фрагмента: # y = спрятать # n = оставить в рабочем каталоге # s = разбить на меньшие фрагменты
Советы и подводные камни
stash@{3}: WIP on main: abc1234 some commit ни о чём не скажет, а stash@{3}: wip: refactoring auth service — переход на JWT — объяснит сразу. Используйте git stash push -m "описание" как привычку.
-k сохраняет staged изменения в рабочем каталоге. Это полезно для тестирования: прячем unstaged «незаконченные» изменения, проверяем что staged часть работает, потом git stash pop.
git stash clear удаляет все stash-записи навсегда. В отличие от удалённых коммитов, stash-записи не отображаются в git reflog после удаления. Перед очисткой просмотрите список: git stash list. Для удаления конкретной записи используйте git stash drop stash@{N}.