Git stash: как отложить незаконченную работу без коммита
Практика4 минРедакция Innovialabs
Коротко
git stash временно убирает незакоммиченные изменения в отдельный стек и возвращает рабочую копию к последнему коммиту; вернуть их можно через git stash pop или apply, а для работы на несколько дней надёжнее WIP-ветка.
Что делает git stash
git stash берёт ваши незакоммиченные изменения (в рабочей копии и в индексе), сохраняет их в специальный стек и возвращает файлы к состоянию последнего коммита. Типичная ситуация: вы на середине задачи, а нужно срочно переключиться на другую ветку и поправить баг.
git stash push -m "форма оплаты, половина валидации"
git switch hotfix/login
# ...исправили, закоммитили...
git switch feature/payment
git stash pop
Просто git stash — то же самое, что git stash push без сообщения.
Основные команды
| Команда | Что делает |
|---|---|
git stash push -m "текст" | Спрятать изменения с понятным названием |
git stash list | Показать все записи: stash@{0}, stash@{1}… |
git stash show -p stash@{1} | Посмотреть diff конкретной записи |
git stash pop | Применить последнюю запись и удалить её из стека |
git stash apply stash@{1} | Применить запись, но оставить её в стеке |
git stash drop stash@{1} | Удалить одну запись |
git stash clear | Удалить все записи сразу |
pop или apply? pop удобен в обычном случае. apply полезен, когда вы хотите применить одни и те же изменения в нескольких ветках или не уверены, что всё пройдёт гладко.
Индексы сдвигаются: самая свежая запись всегда stash@{0}. Поэтому перед drop или apply с номером сначала смотрите git stash list.
Новые файлы и отдельные пути
По умолчанию stash забирает только отслеживаемые файлы. Новые файлы, которые Git ещё не видел, остаются в рабочей копии.
git stash push -u(или--include-untracked) — прячет и неотслеживаемые файлы.git stash push -a(--all) — дополнительно прячет и игнорируемые файлы. Используйте осторожно: туда попадут, например,node_modulesили сборки.git stash push -- src/api.ts src/utils/— прячет только указанные пути.git stash push -p— интерактивно выбрать отдельные куски изменений.git stash push --keep-index— спрятать всё, кроме того, что уже добавлено в индекс. Удобно, чтобы проверить, работает ли то, что вы собираетесь закоммитить.
Названия для записей
Без -m запись выглядит как WIP on main: 3f2a1c4 последний коммит. Через неделю таких записей несколько, и понять, где что, сложно. Правило простое: всегда пишите сообщение, коротко и по делу — что за задача и в каком она состоянии.
Конфликты при возврате
Если пока изменения лежали в stash, кто-то поменял те же строки, git stash pop закончится конфликтом. Важно: при конфликте запись не удаляется из стека, даже если вы делали pop.
Порядок действий:
- Откройте файлы с маркерами
<<<<<<<и разрешите конфликт, как при обычном merge. - Отметьте файлы как решённые:
git add <файл>(илиgit restore --staged <файл>, если не хотите оставлять их в индексе). - Убедитесь, что всё на месте, и удалите запись вручную:
git stash drop.
Если конфликт слишком запутанный, есть безопасный путь: git stash branch fix-stash stash@{0}. Git создаст ветку от того коммита, на котором делался stash, применит туда изменения без конфликтов и удалит запись, если всё прошло успешно.
Когда лучше WIP-ветка
Stash — инструмент на минуты и часы. Он живёт только в вашем локальном репозитории, не отправляется на удалённый сервер и легко теряется среди других записей.
Сделайте коммит в отдельную ветку, если:
- работа отложена на несколько дней;
- изменения нужно показать коллеге или забрать на другой машине;
- вы хотите, чтобы работа была сохранена на сервере;
- изменений много, и важна история шагов.
git switch -c wip/payment-form
git add -A
git commit -m "WIP: форма оплаты"
git push -u origin wip/payment-form
Позже коммиты можно объединить через git rebase -i или squash при merge.
Частые ошибки
- Забытые записи. Регулярно смотрите
git stash listи удаляйте лишнее. - Новые файлы «пропали». Скорее всего, они не были спрятаны: без
-uони просто остались на месте или вы их случайно удалили. git stash clearпо ошибке. Удалённые записи иногда можно найти черезgit fsck --unreachable, но рассчитывать на это не стоит.- pop не в ту ветку. Изменения применятся туда, где вы сейчас находитесь. Перед возвратом проверьте
git status.