Что такое Git Stash?
Вы в разгаре работы над функциональностью, когда возникает что-то срочное. Нужно исправить баг в основной branch, или коллега просит вас провести ревью его pull request. Вы не готовы сделать commit незавершённой работы, но и переключить branch с незакоммиченными изменениями в рабочей директории не получится. Именно для решения этой проблемы и был создан git stash.
Git stash берёт ваши незакоммиченные изменения -- как находящиеся в staging, так и нет -- и сохраняет их во временном хранилище. Ваша рабочая директория возвращается в чистое состояние, соответствующее последнему commit. Когда вы будете готовы, вы сможете вернуть эти изменения. Представьте, что вы кладёте свою работу на полку, чтобы заняться чем-то другим, а потом возвращаетесь и продолжаете ровно с того места, где остановились.
Базовое использование: Stash, Apply и Pop
Сохранение изменений в stash
Простейшая форма:
git stash
Эта команда берёт все отслеживаемые изменённые файлы и файлы в staging и сохраняет их. Ваша рабочая директория становится чистой. Обратите внимание, что неотслеживаемые файлы (файлы, которые вы никогда не добавляли в Git) по умолчанию не попадают в stash. Чтобы включить их, используйте:
git stash -u
Или чтобы включить всё, даже игнорируемые файлы:
git stash -a
Возврат изменений с помощью apply
Когда вы закончили побочную задачу и хотите вернуть свою работу из stash, используйте:
git stash apply
Это восстанавливает изменения из stash в вашу рабочую директорию, но сохраняет запись stash нетронутой. Stash по-прежнему лежит на полке, что может быть полезно, если вы хотите применить те же изменения к нескольким branch.
Возврат изменений с помощью pop
git stash pop
Pop работает как apply, но также удаляет запись stash после применения. Это более распространённый выбор, когда вы просто хотите вернуть свою работу и не нуждаетесь в сохранении stash.
Ключевое различие: apply сохраняет stash, pop удаляет его после восстановления. Используйте apply, когда stash может понадобиться снова. Используйте pop, когда он вам больше не нужен.
Добавление сообщения к stash
По умолчанию Git помечает stash автоматически сгенерированным описанием вроде WIP on main: a3b4c5d commit message. Это не очень полезно, когда у вас несколько stash. Вы можете добавить описательное сообщение:
git stash push -m "refactoring the auth module"
Это значительно упрощает идентификацию содержимого каждого stash при их просмотре позже.
Управление несколькими stash
Просмотр списка stash
Git поддерживает стек stash. Вы можете увидеть их все командой:
git stash list
Вывод выглядит примерно так:
stash@{0}: On main: refactoring the auth module
stash@{1}: WIP on feature/checkout: 9f2e1d0 add cart logic
stash@{2}: WIP on main: 7c8d9e1 update dependencies
Самый последний stash всегда stash@{0}. Каждый новый stash сдвигает более старые вниз по стеку.
Применение или извлечение конкретного stash
По умолчанию apply и pop работают с самым последним stash. Чтобы обратиться к конкретному, укажите его индекс:
git stash apply stash@{2}
git stash pop stash@{1}
Просмотр содержимого stash
Перед применением stash вы можете захотеть посмотреть, что в нём находится:
git stash show stash@{0}
Это показывает сводку изменённых файлов. Для полного diff добавьте -p:
git stash show -p stash@{0}
Сохранение в stash конкретных файлов
Иногда вы не хотите помещать в stash всё подряд. Возможно, вы хотите отложить изменения только в одном или двух файлах. Начиная с Git 2.13, это можно сделать так:
git stash push -m "sidebar layout changes" src/components/Sidebar.tsx src/styles/sidebar.css
Только указанные файлы попадают в stash. Всё остальное остаётся в вашей рабочей директории.
Удаление и очистка stash
Удаление одного stash
Если конкретный stash вам больше не нужен, удалите его командой:
git stash drop stash@{1}
Это удаляет данную запись stash. Оставшиеся stash автоматически переиндексируются.
Очистка всех stash
Чтобы удалить все stash за один раз:
git stash clear
Будьте осторожны с этой командой. Отменить её нельзя. Все сохранённые в stash изменения будут безвозвратно удалены.
Создание branch из stash
Иногда вы делаете stash изменений, а потом понимаете, что они заслуживают отдельной branch. Вместо того чтобы применять stash и затем создавать branch, Git предлагает сокращённый вариант:
git stash branch new-feature-branch stash@{0}
Это создаёт новую branch от commit, на котором stash был первоначально создан, применяет stash и удаляет его. Это особенно полезно, когда применение stash к текущей branch могло бы вызвать конфликты.
Распространённые ошибки
- Забывать о stash. О stash легко забыть. Периодически выполняйте
git stash list, чтобы проверить, нет ли оставшихся stash, которые нужно применить или удалить. - Конфликты stash. Если код значительно изменился с момента создания stash, его применение может вызвать конфликты merge. Разрешайте их так же, как обычные конфликты merge.
- Полагаться на stash вместо commit. Если вы часто используете stash, рассмотрите возможность делать commit незавершённой работы. Вы всегда сможете сделать amend или squash этих commit позже. Stash лучше всего подходит для быстрых, кратковременных переключений контекста, а не для долгосрочного хранения.
Работа со stash в GitSquid
GitSquid отображает stash прямо на графе commit, поэтому вы можете сразу увидеть, какие stash существуют и от какого commit они были созданы. Щелчок правой кнопкой мыши по stash открывает контекстное меню с опциями apply, pop, drop или очистки всех stash. Это делает управление stash быстрее, чем набор команд, особенно когда у вас несколько stash и нужно их просмотреть или очистить.
Краткий справочник
| Команда | Что делает |
|---|---|
git stash |
Сохраняет отслеживаемые изменения в stash |
git stash -u |
Stash включая неотслеживаемые файлы |
git stash push -m "msg" |
Stash с описательным сообщением |
git stash list |
Показать все stash |
git stash apply |
Восстановить stash, сохранить запись |
git stash pop |
Восстановить stash, удалить запись |
git stash drop stash@{n} |
Удалить конкретный stash |
git stash clear |
Удалить все stash |
git stash show -p |
Показать полный diff stash |
git stash branch <name> |
Создать branch из stash |
Git stash — один из тех инструментов, которые кажутся незначительными, пока они вам не понадобятся. Освоившись с ним, вы будете легко переключаться между задачами. Держите stash организованными с помощью сообщений, регулярно очищайте старые и используйте pop вместо apply, когда не нужно сохранять stash.