Полное руководство по Git Stash
Вы в середине разработки фичи, глубоко погружены в рефакторинг, когда коллега пишет вам о критическом баге в продакшене. Ваша рабочая директория представляет собой хаос из недоделанных изменений. Вы не готовы делать коммит, но и переключить ветку с незакоммиченной работой не можете.
Именно для этого и существует git stash. Это руководство охватывает все команды git stash, которые вы действительно будете использовать, способы разрешения конфликтов и советы по рабочему процессу, благодаря которым стэшинг будет казаться естественным, а не рискованным.
Ключевые выводы
git stashсохраняет незакоммиченные изменения в локальный стек и восстанавливает рабочую директорию в состояниеHEAD, позволяя переключать контекст без необходимости коммитить недоделанную работу.- По умолчанию stash включает только отслеживаемые изменения. Используйте
-uдля неотслеживаемых файлов и-aдля игнорируемых. - Используйте
git stash pop, когда хотите вернуть изменения и удалить stash, илиgit stash apply, когда хотите сохранить stash для повторного использования. - Если конфликты при применении stash становятся неуправляемыми,
git stash branchсоздаёт новую ветку от исходного коммита и применяет stash без проблем. - Всегда добавляйте описательное сообщение с помощью
-m, держите список stash коротким и относитесь к stash как к временному хранилищу, а не к резервной копии.
Что такое Git Stash?
git stash сохраняет ваши незакоммиченные изменения — как проиндексированные (staged), так и непроиндексированные (unstaged) — в локальный стек и возвращает рабочую директорию в состояние последнего коммита (HEAD). Позже вы можете восстановить эти изменения — в той же ветке или в другой.
Stash-записи являются строго локальными. Они не отправляются в удалённый репозиторий через git push и не передаются коллегам.
Что попадает в stash по умолчанию:
- Проиндексированные изменения (index)
- Непроиндексированные изменения отслеживаемых файлов
Что НЕ попадает в stash по умолчанию:
- Неотслеживаемые файлы (новые файлы, ещё не добавленные в Git)
- Игнорируемые файлы
Основные команды Git Stash
Сохранение изменений с помощью git stash push
git stash
Простой git stash — это сокращение для git stash push. Это самый быстрый способ получить чистую рабочую директорию.
Добавьте описательное сообщение, чтобы потом понимать, что в нём содержится:
git stash push -m "WIP: refactor auth middleware"
Примечание: Устаревший синтаксис
git stash saveбольше не рекомендуется. Используйтеgit stash push.
Stash неотслеживаемых файлов
По умолчанию новые файлы, которые вы ещё не проиндексировали, остаются на месте. Используйте -u, чтобы включить их:
git stash push -u -m "WIP: new login component"
Чтобы также сохранить файлы, попадающие под .gitignore, используйте -a (--all). Это редко требуется, но бывает полезно, когда игнорируемые файлы мешают переключению ветки или сборке.
Stash конкретных файлов
Вы можете сохранить в stash только определённые файлы, используя pathspec:
git stash push -m "WIP: api changes" -- src/api/client.js src/api/utils.js
Всё остальное в рабочей директории остаётся нетронутым.
Просмотр списка stash
git stash list
Вывод:
stash@{0}: On main: WIP: refactor auth middleware
stash@{1}: WIP on feature/login: 9ab3c12 Add login form
Stash хранятся в стеке по принципу LIFO (последним пришёл — первым ушёл). stash@{0} всегда самый свежий.
Просмотр stash перед применением
git stash show stash@{0} # сводка
git stash show -p stash@{0} # полный diff
Git Stash Pop или Apply: что выбрать?
Это один из самых частых источников путаницы среди команд git stash.
git stash pop | git stash apply | |
|---|---|---|
| Восстанавливает изменения | ✅ Да | ✅ Да |
| Удаляет из стека | ✅ Да (только если применение прошло без конфликтов) | ❌ Нет |
| При конфликте | Сохраняет stash в стеке | Сохраняет stash в стеке |
| Лучше всего для | Одноразового восстановления | Применения к нескольким веткам |
Используйте pop, когда вы закончили со stash и просто хотите вернуть свои изменения.
Используйте apply, когда хотите применить один и тот же stash к нескольким веткам или когда хотите протестировать результат, прежде чем удалять stash.
Чтобы применить конкретный stash:
git stash pop stash@{1}
git stash apply stash@{1}
Восстановление проиндексированного состояния с --index
По умолчанию при применении stash все изменения восстанавливаются как непроиндексированные. Если хотите сохранить разделение на staged/unstaged в том виде, в котором оно было при создании stash, используйте --index:
git stash pop --index
Discover how at OpenReplay.com.
Разрешение конфликтов при применении stash
Если ветка изменилась после того, как вы сделали stash, могут возникнуть конфликты:
CONFLICT (content): Merge conflict in src/api/client.js
The stash entry is kept in case you need it again.
И pop, и apply сохраняют stash в стеке при возникновении конфликтов. Чтобы их разрешить:
- Запустите
git status, чтобы найти конфликтующие файлы. - Откройте каждый файл и разрешите маркеры конфликтов.
- Проиндексируйте разрешённые файлы:
git add src/api/client.js. - Удалите stash вручную, когда убедитесь, что всё в порядке:
git stash drop stash@{0}.
Когда конфликты становятся слишком запутанными: используйте git stash branch
Если конфликты слишком сложно распутать, git stash branch — это самый чистый запасной выход. Эта команда создаёт новую ветку именно от того коммита, на котором вы делали stash, и затем применяет stash там. Поскольку ветка стартует от коммита, на котором был создан stash, это часто позволяет избежать конфликтов:
git stash branch fix/auth-refactor stash@{0}
Если применение проходит успешно, stash удаляется автоматически.
Управление stash и их очистка
git stash drop stash@{0} # удалить конкретный stash
git stash clear # удалить ВСЕ stash (необратимо)
⚠️
git stash clearнеобратима. Откатить её нельзя. Дважды проверяйте перед запуском.
Продвинутый уровень: частичный stash и stash только проиндексированных изменений
Интерактивный режим патча позволяет выбрать, какие фрагменты (hunks) попадут в stash:
git stash push -p
Git проходит по каждому изменению и спрашивает, добавлять ли его в stash. Полезно, когда файл содержит как связанные, так и несвязанные изменения.
Stash только проиндексированных изменений (Git 2.35 и новее):
git stash push --staged
Эта команда отправляет в stash то, что находится в индексе, оставляя непроиндексированную работу на месте — удобно для изоляции изменения, которое вы хотите отложить, не теряя текущий прогресс.
Сохранить проиндексированные изменения в индексе при stash всего остального:
git stash push --keep-index
Обратите внимание, что --keep-index всё равно отправляет в stash как проиндексированные, так и непроиндексированные изменения; она просто оставляет проиндексированные в рабочей директории после создания stash.
Восстановление удалённого Git Stash
Если вы случайно удалили stash или очистили список, их часто можно восстановить как «висячие» (dangling) коммиты в репозитории. Записи stash хранятся как merge-коммиты, поэтому их можно найти с помощью:
git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs git log --merges --no-walk --grep=WIP
Эта команда выводит недостижимые merge-коммиты, похожие на записи stash. Найдя нужный хэш коммита, восстановите его так:
git stash apply <commit-hash>
Восстановление не гарантировано — сборщик мусора Git рано или поздно удалит недостижимые объекты — поэтому действуйте быстро.
Перенос stash между машинами
В свежих версиях Git появились git stash export и git stash import, позволяющие передавать stash через обычные процессы fetch и push.
Для более старых версий Git или для простых разовых переносов всё ещё актуальны такие альтернативы:
- Экспорт в виде патча:
git stash show -p stash@{0} > my-stash.patch, затем применение в другом месте черезgit apply my-stash.patch. - Коммит во временную ветку: создайте ветку, закоммитьте работу, отправьте её в удалённый репозиторий, затем сделайте pull и reset на другой машине.
Для разовых переносов патчи обычно являются самым простым путём.
Лучшие практики Git Stash
- Всегда добавляйте сообщение.
git stash push -m "WIP: что и зачем"избавит вас от попыток разобраться в списке безымянных записейWIP on main. - Stash — это временное хранилище, а не резервная копия. Коммитьте свою работу, когда она достигает логической контрольной точки.
- Держите список stash коротким. Регулярно просматривайте его и удаляйте ненужные.
- Делайте pull перед pop. Обновление ветки перед восстановлением stash снижает вероятность конфликтов.
- При сомнениях выбирайте
applyвместоpop. Вы всегда можете удалить stash вручную, убедившись, что всё выглядит правильно.
Краткий справочник: команды Git Stash
| Команда | Что делает |
|---|---|
git stash | Stash отслеживаемых изменений (сокращение для push) |
git stash push -m "msg" | Stash с описательным сообщением |
git stash push -u | Включить неотслеживаемые файлы |
git stash push -a | Включить неотслеживаемые и игнорируемые файлы |
git stash push -- <path> | Stash только указанных файлов |
git stash push -p | Интерактивно выбрать фрагменты для stash |
git stash push --staged | Stash только проиндексированных изменений |
git stash push --keep-index | Stash всего, но с сохранением проиндексированных в индексе |
git stash list | Список всех stash |
git stash show -p stash@{n} | Показать полный diff stash |
git stash pop | Применить последний stash и удалить его |
git stash apply stash@{n} | Применить stash без его удаления |
git stash pop --index | Восстановить состояние staged/unstaged |
git stash drop stash@{n} | Удалить конкретный stash |
git stash clear | Удалить все stash |
git stash branch <name> [stash] | Создать ветку из stash |
Заключение
git stash — одна из тех команд, которые кажутся необязательными, пока они действительно не понадобятся, — а потом становятся частью повседневного рабочего процесса. Ключевые привычки: всегда называйте свои stash, держите список в порядке и обращайтесь к git stash branch, когда конфликты делают простой pop непрактичным. При правильном использовании stash сохраняет вашу историю Git чистой, а переключения контекста — безболезненными.
Часто задаваемые вопросы
Нет. По умолчанию git stash сохраняет только отслеживаемые изменения — как проиндексированные, так и непроиндексированные модификации файлов, которые Git уже знает. Новые файлы, которые не были добавлены через git add, остаются в рабочей директории. Чтобы включить их, используйте git stash push -u или --include-untracked. Чтобы также сохранить в stash файлы, попадающие под .gitignore, используйте -a или --all.
Обе команды восстанавливают сохранённые изменения в рабочей директории. Различие — в том, что происходит дальше. git stash pop удаляет stash из стека, если он применился без конфликтов, тогда как git stash apply оставляет его на месте, чтобы вы могли применить его снова позже или к другой ветке. Если во время pop возникает конфликт, stash сохраняется, чтобы вы не потеряли свою работу.
Часто да, если действовать быстро. Записи stash хранятся как merge-коммиты, а удалённые stash становятся недостижимыми объектами, которые сборщик мусора Git рано или поздно удалит. Запустите git fsck --unreachable, чтобы найти висячие коммиты, определите stash по его сообщению WIP, затем восстановите его с помощью git stash apply, указав хэш коммита.
Нет. Stash строго локальны и хранятся в ссылке refs/stash вашего репозитория. Они никогда не включаются в git push, git fetch или git pull. Если вам нужно поделиться незавершённой работой с коллегой, закоммитьте её во временную ветку и отправьте её в удалённый репозиторий, либо экспортируйте изменения в виде патча с помощью git stash show -p.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.