■ space · прозаичная полоса
git stash push -m "why" -- <path> откладывает ровно названный файл; остальные грязные файлы не сдвигаются никогда.
Один файл обратно из любого стеша: git restore --source stash@{0} -- <path> — запись остаётся.
Форма с путём появилась в git 2.13 (май 2017); неотслеженным файлам нужен -u.
РАСЩЕП
Три грязных файла, один должен уйти. Смотри, как дерево делится — один файл в стеш, два не двигаются:
ДО · git status --short
M app.conf ← must move
M notes.md
M main.py
ПОСЛЕ
M notes.md ← never moved
M main.py ← never moved
stash@{0}: On main: app.conf prod tweak
app.conf вернулся в своё закоммиченное состояние и сидит в stash@{0} — сообщение -m окупает свои три секунды, как только git stash list вмещает больше одной записи; имена вроде «WIP» стареют плохо
ПУТЬ — ВОТ ВЕСЬ ФОКУС
Голый git stash заметает всё рабочее дерево — каждая отслеженная правка уходит, всё возвращается к HEAD. Не той формы надо, когда грязное дерево смешанное: один файл готов к передаче, остальное честно не закончено. Две детали, которые стоит знать:
- Путь идёт после
--. Всё после двойного тире — пути, не флаги — та же конвенция, что и уgit checkout -- <path>, и не для красоты: старые версии git могли неверно прочитать голый путь. - Неотслеженным файлам нужен
-u. У новорождённого файла нет отслеженной истории, чтобы её застешить, поэтому голыйpushего обходит.git stash push -u -- newfile.pyвключает его;-aидёт дальше и замечает ещё и игнорируемые файлы.
ПОЛФАЙЛА: ИНТЕРАКТИВНЫЙ РАСЩЕП
Когда сам файл готов наполовину — три хороших хунка, один стыдный — git stash -p (или git stash push -p) проходит по каждому хунку и спрашивает Stash this hunk [y,n,q,a,d,j,g,/,e,p,?]?. Отвечай y для хунков, которым место в стеше, n для тех, кто остаётся; результат — стеш, содержащий только то, что вы одобрили. Той же хунк-за-хунком машинерией работает git add -p, так что рефлекс переносится. Две гранулярности, бок о бок:
git stash push -- <path> | git stash -p | |
|---|---|---|
| Гранулярность | целые файлы | отдельные хунки |
| Скорость | одна команда, скриптуется | интерактивно, хунк за хунком |
| Повторяемо в CI | да (пути как аргументы) | нет — нужен человек у промпта |
| Лучше всего для | «этот файл, не остальное» | «эта правка, не та» |
| С | git 2.13 (май 2017) | доступно давно |
Правило большого пальца из собственной модели документации: путь, когда граница — файл; -p, когда граница внутри.
ОДИН ФАЙЛ ОБРАТНО
git stash pop восстанавливает stash@{0} и удаляет запись — нормальный путь, но pop — всё-или-ничего по стешу, и конфликт прерывает pop, сохранив запись. Две опции потоньше:
# 1. apply without dropping (safe re-run)
git stash apply stash@{0}
# 2. pull ONE file out of a stash, leave the entry intact
git restore --source stash@{0} -- app.conf
# pre-2.23 spelling of the same operation:
git checkout stash@{0} -- app.conf
проверка: git stash list после restore → stash@{0} всё ещё стоит — запись удаляет только pop
КОГДА СТЕШ — НЕПРАВИЛЬНЫЙ ИНСТРУМЕНТ
Стеш — черновик, не ветка. Стешы живут только на вашей машине, не несут сообщения дальше одной строки и славятся лёгкостью забвения — git stash list остаётся жанром.git switch -c wip-labels Работа, которая должна пережить дни, переезжать между машинами или нести настоящий commit message, — место ей на ветке:
конец одиночного файла · ничего не fetched · всё локально