Miałem kilka nieproszonych zmian w mojej gałęzi programistycznej i wykorzystałem je git stash
, ale były pewne zmiany, które były bardzo ważne wśród tych, które zostały ukryte. Czy jest jakiś sposób na odzyskanie tych zmian?
Od tego czasu wprowadziłem pewne zmiany w plikach kodu ukrytego.
Czy jest jakaś szansa na odzyskanie ukrytych zmian w nowej gałęzi, jeśli to możliwe?
Odpowiedzi:
Łatwa odpowiedź na proste pytanie brzmi
git stash apply
Po prostu sprawdź gałąź, w której chcesz wprowadzić zmiany, a następnie
git stash apply
. Następnie użyj,git diff
aby zobaczyć wynik.Po skończysz ze zmiany-z
apply
dobrym wyglądem i masz pewność, że nie trzeba zapas każdy więcej- następnie użyćgit stash drop
, aby pozbyć się go.Zawsze sugeruję używanie
git stash apply
zamiastgit stash pop
. Różnica polega na tym, żeapply
pozostawia skrytkę w celu łatwego ponownego spróbowaniaapply
, lub w celu patrzenia itp. Jeślipop
jest w stanie wyodrębnić skrytkę, natychmiastdrop
ją również zrobi , a jeśli nagle uświadomisz sobie, że chcesz ją gdzieś wyodrębnić w innym (w innej gałęzi), z--index
, lub z innymi, to nie jest takie proste. Jeśli takapply
, możesz wybrać, kiedydrop
.To wszystko jest dość niewielkie w ten czy inny sposób, a dla nowicjusza, powinno być mniej więcej tak samo. (I możesz pominąć resztę tego!)
Co jeśli robisz bardziej zaawansowane lub bardziej skomplikowane rzeczy?
Istnieją co najmniej trzy lub cztery różne „sposoby używania skrytki git”. Powyższe dotyczy „sposobu 1”, „łatwego sposobu”:
Zacząłeś od czystej gałęzi, pracowałeś nad pewnymi zmianami, a potem zdałeś sobie sprawę, że robisz je w niewłaściwej gałęzi. Chcesz tylko wprowadzić zmiany, które już masz, i przenieść je do innej gałęzi.
Jest to łatwy przypadek opisany powyżej. Uruchom
git stash save
(lub zwykłygit stash
, to samo). Sprawdź drugi oddział i skorzystaj z niegogit stash apply
. To powoduje, że git łączy się z twoimi wcześniejszymi zmianami, używając raczej potężnego mechanizmu scalania git. Sprawdź wyniki dokładnie (za pomocągit diff
), aby zobaczyć, czy ci się podobają, a jeśli tak, użyjgit stash drop
upuszczenia skrytki. Jesteś skończony!Zacząłeś pewne zmiany i ukryłeś je. Następnie przeniosłeś się do innej gałęzi i zacząłeś więcej zmian, zapominając, że masz te ukryte.
Teraz chcesz zachować, a nawet przenieść te zmiany, i zastosować również swoją skrytkę.
Możesz w rzeczywistości
git stash save
ponownie, ponieważgit stash
tworzy „stos” zmian. Jeśli to zrobisz, masz dwie skrytki, jedną właśnie nazwanąstash
- ale możesz także pisaćstash@{0}
- i jedną pisownięstash@{1}
. Użyjgit stash list
(w dowolnym momencie), aby zobaczyć je wszystkie. Najnowszy ma zawsze najniższy numer. Kiedy Tygit stash drop
upuszczasz najnowszy, a ten, który był,stash@{1}
przenosi się na szczyt stosu. Jeśli miał nawet więcej, ten, który byłstash@{2}
staniestash@{1}
, i tak dalej.Możesz,
apply
a następniedrop
także konkretną skrytkę:git stash apply stash@{2}
i tak dalej. Porzucenie określonej skrytki przenumeruje tylko te o wyższych numerach. Ponownie, ten bez numeru jest równieżstash@{0}
.Jeśli zgromadzisz dużo skrytek, może stać się dość nieuporządkowany (czy był to schowek, którego chciałem,
stash@{7}
czy byłstash@{4}
? Czekaj, właśnie nacisnąłem inny, teraz są 8 i 5?). Osobiście wolę przenieść te zmiany do nowej gałęzi, ponieważ gałęzie mają nazwy icleanup-attempt-in-December
oznaczają dla mnie znacznie więcejstash@{12}
. (git stash
Polecenie przyjmuje opcjonalną wiadomość zapisu, a te mogą pomóc, ale jakoś wszystkie moje skrytki właśnie się skończyłyWIP on branch
).(Bardzo zaawansowane) Użyłeś
git stash save -p
lub dokładniegit add
i / lubgit rm
-eded określone bity twojego kodu przed uruchomieniemgit stash save
. Miałeś jedną wersję w ukrytym indeksie / obszarze pomostowym, a drugą (inną) wersję w działającym drzewie. Chcesz to wszystko zachować. Więc teraz używaszgit stash apply --index
, a to czasami kończy się niepowodzeniem z:Używasz
git stash save --keep-index
, aby przetestować „co zostanie popełnione”. Ten jest poza zakresem tej odpowiedzi; zamiast tego zobacz inną odpowiedź StackOverflow .W przypadku skomplikowanych przypadków zalecam najpierw rozpocząć pracę w „czystym” katalogu roboczym, wprowadzając wszelkie zmiany, które teraz wprowadzasz (jeśli chcesz, w nowym oddziale). W ten sposób „gdzieś”, w którym je stosujesz, nie ma w tym nic więcej, a będziesz po prostu próbował ukryć zmiany:
Teraz jesteś na „czystym” punkcie wyjścia. A może wygląda to tak:
Najważniejszą rzeczą do zapamiętania jest to, że „skrytka” to zatwierdzenie, to tylko „zabawne / dziwne” zatwierdzenie, które nie jest „na gałęzi”. Do
apply
wygląda praca na co commit zmienione i próbuje powtórzyć go gdziekolwiek jesteś teraz. Skrytka nadal będzie tam (apply
utrzymuje ją w pobliżu), więc możesz na nią spojrzeć więcej lub zdecydować, że to niewłaściwe miejsceapply
i spróbować ponownie inaczej lub cokolwiek innego.Za każdym razem, gdy masz skrytkę, możesz użyć jej,
git stash show -p
aby zobaczyć uproszczoną wersję tego, co jest w skrytce. (Ta uproszczona wersja patrzy tylko na zmiany „ostatecznego drzewa roboczego”, a nie na zapisane zmiany indeksu, które--index
przywracają osobno.) Polecenie „git stash apply
bez”--index
po prostu próbuje teraz dokonać tych samych zmian w katalogu roboczym.Jest to prawdą, nawet jeśli masz już jakieś zmiany.
apply
Komenda chętnie stosują zapas do zmodyfikowanego katalogu roboczym (lub przynajmniej, aby spróbować go zastosować). Możesz na przykład zrobić to:Możesz tutaj wybrać polecenie „zastosuj”, wybierając poszczególne skrytki do zastosowania w określonej kolejności. Zauważ jednak, że za każdym razem, gdy wykonujesz „scalanie git” i jak ostrzega dokumentacja scalania:
Jeśli zaczynasz od czystego katalogu i wykonujesz tylko kilka
git apply
operacji, łatwo jest się wycofać: użyj,git reset --hard
aby wrócić do czystego katalogu i zmienić swojeapply
operacje. (Dlatego właśnie polecam zacząć od czystego katalogu roboczego, w tych skomplikowanych przypadkach).Co z najgorszym możliwym przypadkiem?
Załóżmy, że robisz wiele zaawansowanych rzeczy Git i zrobiłeś skrytkę i chcesz
git stash apply --index
, ale nie możesz już zastosować zapisanej skrytki--index
, ponieważ gałąź odbiegała zbytnio od czasu jej zapisania.Po to
git stash branch
jest.Jeśli ty:
stash
, a następniegit stash apply --index
próba ponownego utworzenia zmiany na pewno będą działać. To właśnie robi. (A następnie upuszcza skrytkę, ponieważ została pomyślnie zastosowana).
git stash branch newbranch
Kilka ostatnich słów na temat
--index
(co to do cholery jest?)To, co
--index
robi, jest proste do wyjaśnienia, ale nieco skomplikowane wewnętrznie:git add
(lub „wystawić”) przed wprowadzeniemcommit
.git stash
, to może być edytowany zarówno plikifoo
izorg
, ale tylko jeden z tych inscenizacji.git add
sadd
rzeczy Ed i robi niegit add
nieokreślone dodane rzeczy. Oznacza to, że jeśliadd
edytowałeś,foo
ale niezorg
wróciłeś, zanim to zrobiłeśstash
, może być miło mieć taką samą konfigurację. To, co zostało zainscenizowane, powinno zostać ponownie zainscenizowane; to, co zostało zmodyfikowane, ale nie ustawione, powinno być ponownie zmodyfikowane, ale nie ustawione.--index
Flagęapply
próbuje ustawić rzeczy ten sposób. Jeśli twoje drzewo robocze jest czyste, zwykle działa to po prostu. Jeśli jednak w twoim drzewie roboczym są już zainstalowane elementyadd
, możesz zobaczyć, jak mogą występować tutaj problemy. Jeśli pominąć--index
Theapply
operacja nie próbuje zachować cały wystawił / Unstaged konfigurację. Zamiast tego po prostu wywołuje maszynę scalającą git, używając zatwierdzenia drzewa roboczego w „stash bag” . Jeśli nie zależy ci na zachowaniu etapowym / niestacjonarnym, pominięcie--index
go znacznie ułatwiagit stash apply
zrobienie tego.źródło
git stash pop
? Czy masz na myśli: edytowałeś niektóre pliki, ale nie uruchomiłeśgit stash
się jeszcze? Czy masz na myśli coś zupełnie innego?apply
umieszczeniem skrytki. Nie musisz tego robić, ale sprawia, że jest ci o wiele łatwiej. Możesz użyćrebase -i
do zmiażdżenia wielu zatwierdzeń lub wybrania poszczególnych zmian, czy cokolwiek, później.git stash apply --index
(pamiętaj o dwóch myślnikach). Jeśli pominiesz--index
, nic wielkiego; Jedynym punktem--index
jest utrzymanie konfiguracji etapowej / niestacjonarnej. (Najprawdopodobniej nie miałeś żadnej specjalnej konfiguracji.) Następniegit status
itd. I dodaj / zatwierdź zgodnie z życzeniem itp. Kiedy (i tylko wtedy) skończysz ze skrytką, użyj,git stash drop
aby ją odrzucić.drop
lubpop
) ukrytą skrzynkę, zawsze masz oryginalny ukryty kod bezpieczny w zatwierdzeniu, ponieważ ukryta jest zatwierdzona! Jeśli chcesz go odzyskać dokładnie, ale na gałęzi, użyjgit stash branch
(zobacz tę sekcję powyżej lub książkę Pro Git w odpowiedzi Shunyi ). Możesz wtedygit checkout
git cherry-pick
przywróci wszystko na miejsce
zgodnie z sugestiami w komentarzach, możesz użyć,
git stash branch newbranch
aby zastosować skrytkę do nowej gałęzi, która jest taka sama jak uruchomienie:źródło
git stash branch newbranch
rzeczywiście to zrobi; ale pamiętaj, że tworzy on nową gałąź z rodzicem ustawionym na zatwierdzenie, które byłoHEAD
w momencie, w którymstash
zostało wykonane. Innymi słowy, dzieje się tak, gdy wracasz po długiej sesji hackerskiej lub czymkolwiekAby to uprościć, masz dwie opcje ponownego zastosowania skrytki:
git stash pop
- Przywróć z powrotem do stanu zapisanego, ale usuwa skrytkę z pamięci tymczasowej.git stash apply
- Przywróć z powrotem do zapisanego stanu i pozostawia listę skrytek do ewentualnego późniejszego ponownego wykorzystania.Możesz przeczytać bardziej szczegółowo o skrytkach git w tym artykule.
źródło
Aby sprawdzić zawartość skrytki: -
zastosuj określony numer skrytki z listy skrytek: -
lub do zastosowania tylko pierwszej skrytki:
Uwaga: git stash pop usunie skrytkę z listy skrytek, podczas gdy git stash nie zostanie zastosowany. Więc używaj ich odpowiednio.
źródło
Na Macu to działało dla mnie:
lista skrytek git (zobacz wszystkie swoje skrytki)
zastosowanie git stash (tylko numer, który chcesz z listy skrytek)
lubię to:
źródło
możesz ukryć niezatwierdzone zmiany za pomocą „git stash”, a następnie przejść do nowego oddziału za pomocą „git checkout -b”, a następnie zastosować ukryte zatwierdzenia „git stash Apply”
źródło