Back

Полное руководство по Git Stash

Полное руководство по 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 popgit 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

Разрешение конфликтов при применении 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 в стеке при возникновении конфликтов. Чтобы их разрешить:

  1. Запустите git status, чтобы найти конфликтующие файлы.
  2. Откройте каждый файл и разрешите маркеры конфликтов.
  3. Проиндексируйте разрешённые файлы: git add src/api/client.js.
  4. Удалите 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 stashStash отслеживаемых изменений (сокращение для 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 --stagedStash только проиндексированных изменений
git stash push --keep-indexStash всего, но с сохранением проиндексированных в индексе
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.

OpenReplay