open atlas
↑ К треку
Git: от нуля до сеньора GIT · 07 · 01

Прятанье незавершённой работы

git stash прячет незакоммиченные отслеживаемые изменения и даёт чистое дерево, чтобы переключить ветку посреди работы. pop возвращает и удаляет запись; apply возвращает, но оставляет её. Заначки образуют стек, который можно смотреть и удалять, но они локальны и легко забываются.

GIT Middle ◷ 15 min
Уровень
ОсновыJuniorMiddleSenior

Ты на полпути через фичу, файлы повсюду, коммитить нечего — и тут прилетает продакшен-баг, который надо чинить в main прямо сейчас. Git отказывается переключать ветку, потому что checkout затрёт твои правки. Коммитить полусломанный код только ради переключения не хочется. Для ровно этого случая есть парковка: git stash.

К концу этого урока ты сможешь отложить грязные изменения, чтобы получить чистое дерево, сменить контекст и вернуть работу обратно — точно зная, чем различаются pop и apply и где заначка на самом деле живёт.

Цель

После этого урока ты сможешь с помощью git stash отложить незавершённую работу и восстановить её, объяснить стек заначек и разницу между pop и apply, а также избегать классических ловушек с неотслеживаемыми файлами и забытыми заначками.

1

git stash записывает твои незакоммиченные отслеживаемые изменения и сбрасывает рабочее дерево к HEAD. Он берёт всё изменённое-и-отслеживаемое — и проиндексированное, и нет — сохраняет это как скрытый объект вроде коммита и откатывает файлы к чистому состоянию, совпадающему с последним коммитом:

git stash            # сокращение от: git stash push
git status           # теперь чисто — правки припаркованы, а не потеряны

Ключевая идея: ты получаешь чистое дерево без коммита и без потери работы. Теперь git switch main срабатывает.

2

Заначки образуют стек, и его можно посмотреть. Каждый git stash кладёт новую запись наверх, нумерация от самой свежей:

git stash list
# stash@{0}: WIP on feature: 9f3c1a2 Add filter UI
# stash@{1}: WIP on feature: 9f3c1a2 Add filter UI

stash@{0} — самая новая. Поскольку автоматические сообщения выглядят одинаково, давай заначкам имена, чтобы будущий ты их различал:

git stash push -m "наполовину готовая валидация фильтра"
3

pop возвращает и удаляет; apply возвращает и оставляет. Чтобы вернуть работу:

git stash pop            # вернуть stash@{0}, затем удалить его из стека
git stash apply          # вернуть stash@{0}, но ОСТАВИТЬ его в стеке
git stash apply stash@{1}  # вернуть конкретную старую запись

Используй pop для обычного случая «продолжить с того места, где остановился». Используй apply, когда хочешь то же изменение на нескольких ветках или когда нервничаешь из-за конфликтов и хочешь страховочную копию, пока не убедишься, что всё легло чисто.

Граничные случаи

По умолчанию git stash игнорирует неотслеживаемые файлы (новые файлы, которых git ещё не видел) и игнорируемые. Поэтому новенький config.local.js остаётся в рабочем дереве даже после stash — и может заблокировать то самое переключение ветки, ради которого ты всё затевал. Добавь -u (--include-untracked), чтобы захватить и новые файлы, или -a (--all), чтобы включить ещё и игнорируемые. Забыть про это — самый частый сюрприз «но я же всё спрятал!».

4

pop может упасть с конфликтом — и тогда заначку он не удаляет. Если ветка ушла вперёд и спрятанное изменение пересекается, возврат порождает конфликты слияния. Разреши их как любое слияние, затем git add файлы. Заметь, что конфликтный pop оставляет запись заначки (чтобы ты не потерял её посреди конфликта); удали её сам после разрешения. Ещё два полезных инструмента:

git stash drop stash@{1}   # удалить одну запись, не применяя её
git stash branch fix-wip   # создать ветку ИЗ заначки и применить её там

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

Разбор примера

Экстренный хотфикс, от начала до конца.

Ты на feature/search с десятком изменённых файлов и одним новым файлом search.test.js, которого git никогда не отслеживал. Алерт пейджера говорит, что checkout сломан на main.

git stash push -u -m "search WIP + новый тест"   # -u чтобы новый файл теста тоже ушёл
git switch main
# ... чинишь продакшен-баг, коммитишь, пушишь ...
git switch feature/search
git stash pop

После pop все двенадцать правок и новый файл теста на месте — ровно так, как ты их оставил, а стек заначек снова пуст. Если бы pop сообщил о конфликте (скажем, хотфикс из main тоже трогал открытый у тебя файл), ты разрешил бы его, сделал git add результата, затем git stash drop, чтобы убрать запись, которую оставил конфликтный pop.

Частая ошибка

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

Проверь себя
Викторина

Ты хочешь применить спрятанное изменение по очереди на двух разных ветках. Какую команду использовать и почему?

Итог

git stash прячет твои незакоммиченные отслеживаемые изменения и выдаёт чистое рабочее дерево, чтобы можно было переключить ветку или сделать pull, не коммитя недоделанную работу. Заначки складываются в стек (stash@{0} — самая новая), который можно list, именовать через -m и drop. pop возвращает и удаляет запись; apply возвращает, но оставляет её для повторного использования. Помни про -u для неотслеживаемых файлов, про то, что конфликтный pop оставляет запись на месте, и что заначки локальны и легко забываются. Дальше ты скопируешь один коммит с одной ветки на другую с помощью git cherry-pick.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.