Git stash: как сохранить и восстановить незакоммиченные изменения

git stash — инструмент для временного сохранения незакоммиченных изменений. Разбираем все команды: push, pop, apply, drop, show, branch — с практическими примерами.

Обложка: Git stash: как сохранить и восстановить незакоммиченные изменения

Представь: ты в середине правки, и тебя просят срочно переключиться на другую ветку. Коммитить недоделанное — плохая идея. Откатывать изменения — потеря работы. Именно для таких случаев в Git есть git stash — временное хранилище незакоммиченных изменений.

Stash работает как стопка листков: кладёшь незавершённую работу «на полку», переключаешься на другую задачу, потом возвращаешься и достаёшь обратно. В этой статье разберём все основные команды — от базовых до продвинутых сценариев.

Ключевые выводы

git stash временно сохраняет незакоммиченные изменения и очищает рабочую директорию

git stash pop применяет верхний stash и удаляет его; git stash apply применяет, но оставляет в стеке

— Флаг -u добавляет в stash неотслеживаемые файлы, флаг --keep-index оставляет staged-изменения нетронутыми

— При конфликте после pop stash не удаляется автоматически — нужно разрешить конфликты вручную

git stash branch создаёт новую ветку прямо из stash — удобно для сложных случаев

Эта статья — часть нашего полного путеводителя по Git. Там — весь маршрут: от первого коммита до продвинутых workflow.

Что такое git stash и зачем он нужен

git stash сохраняет все изменения в рабочей директории (tracked-файлы) в специальный стек внутри репозитория и возвращает рабочую директорию к последнему коммиту. Это не коммит — изменения не попадают в историю. Это временная полка.

Stash хранится локально в .git/refs/stash и не отправляется при git push. Стек может содержать любое количество записей.

			# Сохранить изменения
git stash

# Или явно через push (современный синтаксис)
git stash push
		

Именованные stash: git stash push -m

Без имени stash называется WIP on branch-name: hash message — не очень информативно. Флаг -m задаёт понятное описание:

			git stash push -m "правка формы логина — в процессе"
		

Хорошее описание особенно важно, когда в стеке накапливается несколько записей. Через неделю «WIP on main: a3f2b1c» ничего не скажет — в отличие от конкретного сообщения.

Просмотр: list и show

			# Список всех stash
git stash list
# stash@{0}: On main: правка формы логина — в процессе
# stash@{1}: WIP on feature/auth: a3f2b1c add validation

# Просмотр изменённых файлов в stash
git stash show

# Полный diff
git stash show -p

# Для конкретного stash по индексу
git stash show stash@{1}
		

Индексы в стеке работают как в массиве: stash@{0} — последний сохранённый, stash@{1} — предыдущий и так далее.

Применение и удаление: pop, apply, drop, clear

			# Применить верхний stash и удалить его из стека
git stash pop

# Применить без удаления из стека (можно применить несколько раз)
git stash apply

# Применить конкретный stash
git stash apply stash@{2}

# Удалить конкретный stash
git stash drop stash@{1}

# Очистить весь стек
git stash clear
		

Ключевое различие между pop и apply: первый удаляет запись из стека после применения, второй — нет. Используй apply, если хочешь подстраховаться и оставить stash до полной проверки результата.

Включить untracked файлы: git stash -u

По умолчанию git stash сохраняет только отслеживаемые файлы (те, что уже есть в индексе). Новые файлы, которые ещё не добавлены через git add, остаются в рабочей директории.

Флаг -u (или --include-untracked) добавляет и их:

			# Включить новые (untracked) файлы
git stash -u

# Включить всё, в том числе игнорируемые файлы из .gitignore
git stash -a  # или --all
		

Сохранить только unstaged: git stash --keep-index

Иногда нужно убрать только рабочие (unstaged) изменения, оставив всё, что уже добавлено через git add. Флаг --keep-index делает именно это:

			# Стэшнуть только unstaged-изменения
# Staged (git add) изменения останутся как есть
git stash --keep-index
		

Удобно, когда готовишь коммит: добавил нужное в staged, а незакоммиченные черновики убрал временно — и коммитишь только то, что хотел.

Конфликты при pop: что делать

Если с момента сохранения stash основная ветка ушла вперёд и изменились те же строки, при git stash pop возникнут конфликты — точно так же, как при merge.

Важно: при конфликте pop не удаляет stash из стека автоматически. Это защита от потери данных — решай конфликты спокойно.

			# Пробуем применить
git stash pop
# CONFLICT (content): Merge conflict in src/auth.js

# Смотрим что конфликтует
git status

# Разрешаем конфликты в файлах (маркеры <<<<<<<, =======, >>>>>>>)
# После разрешения:
git add src/auth.js

# Удаляем stash вручную (он остался в стеке)
git stash drop
		

Если конфликты слишком сложные — лучше использовать git stash branch, о котором расскажем ниже.

Практический сценарий: hotfix без потери текущей работы

Классическая ситуация: ты разрабатываешь новую фичу, и приходит сообщение «упал прод, нужен срочный фикс». Вот как это решается с git stash:

			# 1. Сохраняем текущую работу
git stash push -m "feature/payments — реализация формы"

# 2. Переключаемся на main
git checkout main
git pull origin main

# 3. Создаём ветку для hotfix
git checkout -b hotfix/login-crash

# 4. Делаем правку, коммитим, пушим
git add .
git commit -m "fix: исправлен краш при пустом токене"
git push origin hotfix/login-crash

# 5. После мержа возвращаемся к своей задаче
git checkout feature/payments
git stash pop
		

Весь процесс занимает меньше минуты. Незакоммиченная работа сохранена, история не засорена недоделанными коммитами.

git stash branch: создать ветку из stash

Бывает, что изменений в stash накопилось так много, что применить их поверх текущей ветки без конфликтов не получится. Команда git stash branch решает это элегантно: она создаёт новую ветку с того коммита, где был сделан stash, и применяет его туда без конфликтов.

			# Создать ветку из последнего stash
git stash branch feature/new-branch-from-stash

# Или из конкретного stash
git stash branch feature/payments-v2 stash@{1}
		

После успешного применения stash удаляется автоматически. Это лучший вариант, когда работа в stash выросла в самостоятельную задачу или когда конфликты неизбежны.

Если тебе нужно не просто отложить изменения, а откатить уже сделанные коммиты, читай как откатить коммит в Git — там разобраны git reset, git revert и когда что использовать.

Часто задаваемые вопросы
1
Чем git stash pop отличается от git stash apply?

git stash pop применяет верхний stash и удаляет его из стека. git stash apply применяет, но оставляет запись в стеке — её можно применить повторно или удалить позже через git stash drop. Используй apply, когда хочешь перестраховаться до проверки результата.

2
Сохраняется ли stash при переключении между ветками?

Да. Stash хранится в .git/refs/stash и не привязан к конкретной ветке. Ты можешь сохранить изменения на одной ветке и применить на любой другой — именно это делает stash удобным для быстрого переключения контекста.

3
Почему git stash не сохраняет новые файлы?

По умолчанию git stash сохраняет только отслеживаемые файлы — те, что уже есть в индексе Git. Новые файлы (untracked) остаются нетронутыми. Чтобы включить их в stash, используй флаг -u: git stash -u.

git stash — один из самых полезных инструментов в ежедневной работе с Git. Он избавляет от необходимости делать «грязные» коммиты ради переключения контекста, позволяет быстро реагировать на срочные задачи и аккуратно управлять незавершённой работой. Освой эти команды, и переключение между задачами перестанет быть стрессом.

Рекомендуем