Code review przychodzi, gdy trzy pliki są w połowie edytowane, a ruszyć może tylko jeden. Chowanie wszystkiego do stash i przepisywanie dwóch pozostałych plików to rytuał, którego nikt nie tęskni.
TL;DR: git stash push -m "dlaczego" -- <ścieżka> chowa dokładnie wskazane ścieżki i zostawia resztę brudnego drzewa w spokoju. Zmiany odzyskasz przez git stash pop (albo wyjmiesz pojedynczy plik z dowolnego stash przez git restore --source stash@{0} -- <ścieżka>). Forma z pathspec przyszła z git 2.13, wydanym w maju 2017 — każdy toolchain z ostatnich ośmiu lat ją ma.
git stash push -m "app.conf prod tweak" -- app.conf
git stash list
# stash@{0}: On main: app.conf prod tweak
git stash pop Chowaj plik, nie drzewo.
Jak schować do stash tylko jeden plik w git?
Gołe git stash wymiata całe drzewo robocze — każda śledzona modyfikacja idzie do stash, wszystko wraca do HEAD. To zła forma, gdy brudne drzewo jest mieszane: jeden plik jest gotowy do oddania, reszta szczerze niedokończona. Rozwiązaniem jest czasownik push z pathspec, według dokumentacji git-stash:
# przed: trzy brudne pliki
$ git status --short
M app.conf
M notes.md
M main.py
# schowaj tylko app.conf
$ git stash push -m "app.conf prod tweak" -- app.conf
Saved working directory and index state On main: app.conf prod tweak
$ git status --short
M notes.md
M main.py app.conf wraca do stanu z commita i ląduje w stash@{0}; notes.md i main.py drgnęły. Notka -m jest opcjonalna, ale wartą jest tych trzech sekund, gdy git stash list pokaże więcej niż jeden wpis — stash nazwane „WIP” starzeją się źle.
Dwa detale, które się liczą:
- Pathspec idzie po
--. Wszystko po podwójnym myślniku to ścieżki, nie flagi. Ta sama konwencja cogit checkout -- <ścieżka>i nie jest ozdobna:git stash push -- main.pyigit stash push main.pyróżnią się w starszych wersjach, gdzie goła ścieżka mogła zostać źle odczytana. - Pliki nieśledzone wymagają
-u. Świeży plik nie ma śledzonej historii do schowania, więc zwykłypushgo pomija.git stash push -u -- newfile.pygo dołącza;-aidzie dalej i wymiata też pliki ignorowane.
Jak schować część jednego plika?
Gdy sam plik jest w połowie gotowy — trzy dobre hunks, jeden żenujący — interaktywny tryb go kroi:
git stash -p # albo: git stash push -p Git przechodzi przez każdy hunk i pyta Stash this hunk [y,n,q,a,d,j,g,/,e,p,?]?. Odpowiadaj y dla hunków, które idą do stash, n dla tych, co zostają. Efekt: stash tylko z zatwierdzonym, a reszta pliku zostaje brudna w drzewie. Ta sama maszyna hunk po hunku napędza git add -p, więc odruch się przenosi.
git stash push -- <ścieżka> | git stash -p | |
|---|---|---|
| Ziarnistość | całe pliki | pojedyncze hunks |
| Tempo | jedno polecenie, skryptowalne | interaktywnie, hunk po hunku |
| Powtarzalne w CI | tak (ścieżki jako argumenty) | nie — potrzebuje człowieka przy prompcie |
| Najlepsze do | „ten plik, nie reszta” | „ta zmiana, nie tamta” |
| Od | git 2.13 (maj 2017) | dostępne od dawna |
Zasada kciuka z samego modelu dokumentacji: pathspec, gdy granicą jest plik, -p, gdy leży wewnątrz.
Jak odzyskać plik ze stash?
git stash pop odtwarza stash@{0} i usuwa wpis. To normalna droga — ale pop to wszystko-albo-nic na stash, a konflikt przerywa pop, zostawiając wpis. Dwie subtelniejsze opcje:
# 1. zastosuj bez usuwania (bezpiecznie powtarzalne)
git stash apply stash@{0}
# 2. wyjmij JEDEN plik ze stash, wpis zostaje
git restore --source stash@{0} -- app.conf
# starsza pisownia tej samej operacji (przed 2.23):
git checkout stash@{0} -- app.conf Forma restore/checkout odpowiada na przypadek „schowałem trzy zmiany razem, a teraz potrzebuję tylko jednej” — kopiuje schowaną zawartość tej ścieżki do drzewa i zostawia stash@{0} na nogach. Uwaga: nadpisuje kopię w drzewie roboczym; jeśli bieżące zmiany na tej ścieżce się liczą, najpierw diff:
git diff stash@{0} -- app.conf Stashe są przechowywane jako prawdziwe commity na stosie podobnym do refloga — dlatego stash@{0} przyjmuje dowolną składnię commit-ish, a pomyłkowo usunięty stash da się odzyskać z refloga, dopóki garbage collection go nie zje.
Kiedy stash to złe narzędzie?
Stash to brulion, nie gałąź: bez nazwy w git branch, bez review, bez domyślnie pokazywanego diff, a wpisy w milczeniu się piętrzą aż do zapomnienia. Jeśli praca w toku ma przetrwać zmiany kontekstu między maszynami albo dniami, scommituj ją na gałąź — dołączona historia bije bezimienny stos. Gdy te zaparkowane commity będą musiały wylądować gdzie indziej, przeniesie je git cherry-pick. A gdy celem jest cofanie, nie parkowanie, obowiązuje drzewo decyzyjne z cofnij ostatni commit.
Uczciwa księga trybów awarii, wszystkie z udokumentowanego zachowania:
| Objaw | Przyczyna | Fix |
|---|---|---|
| Brak pliku po stash | nieśledzone ścieżki są pomijane | git stash push -u -- <ścieżka> |
error: Your local changes ... would be overwritten przy pop | ścieżka zmieniła się od stash | scommituj lub schowaj nowy stan, potem pop |
| Odzyskane zmiany zniknęły | pop trafił konflikt i przerwał się | rozwiąż, potem git stash apply |
| „Który to był stash?” | bezimienny stos stashy | notki -m, za każdym razem |
Notka z maja 2017, która dodała pathspec do git stash push, ma osiem lat, a większość pamięci mięśniowej git stash jest starsza. Warte ponownej nauki: wymiataczenie całego drzewa to dziś przypadek szczególny, nie domyślny.
FAQ
Jak schować do stash tylko jeden plik w git?
git stash push -m "notka" -- ścieżka/do/pliku — forma z pathspec chowa tylko wskazane ścieżki i zostawia pozostałe zmienione pliki nietknięte. Wymaga git 2.13 lub nowszego (maj 2017).
Jak wyciągnąć pojedynczy plik ze stash?
git restore --source stash@{0} -- ścieżka/do/pliku (albo starsza forma git checkout stash@{0} -- ścieżka/do/pliku). Kopiuje schowaną wersję do drzewa roboczego bez usuwania wpisu stash.
Dlaczego git stash pominął mój nowy plik?
Pliki nieśledzone nie są częścią zwykłego stash. Dodaj -u, by je dołączyć: git stash push -u -- ścieżka/do/pliku. Pliki ignorowane wymagają -a.
— mrsaynothing
— mrsaynothing
Notatki z pogranicza AI, Linuksa i self-hostingu.
Otrzymaj następną instrukcję mailem
Jeden mail na wpis. Napraw i idź dalej.
co to jest?Field Notes #1: strona agentów. Maszyna wydaje. Ja zatwierdzam.
Podobają się teksty? Tak buduję zawodowo. zatrudnij mnie