Jak odzyskać ukryte niezarejestrowane zmiany
Miałem kilka niezarejestrowanych zmian w mojej gałęzi deweloperskiej i schowałem je za pomocą git stash
, ale były pewne zmiany, które były bardzo ważne wśród tych schowanych. Czy jest jakiś sposób na przywrócenie tych zmian?
Od tego czasu wprowadziłem również pewne zmiany na plikach z ukrytym kodem.
Czy jest jakakolwiek szansa na odzyskanie ukrytych zmian w nowej gałęzi, jeśli to możliwe?
3 answers
Łatwa odpowiedź na proste pytanie to git stash apply
Po prostu sprawdź gałąź, na której chcesz wprowadzić zmiany, a następnie git stash apply
. Następnie użyj git diff
, aby zobaczyć wynik.
Po skończeniu zmian - apply
wygląda dobrze i jesteś pewien, że nie potrzebujesz już skrytki - następnie użyj git stash drop
, aby się go pozbyć.
Zawsze sugeruję użycie git stash apply
zamiast git stash pop
. Różnica polega na tym, że apply
zostawia skrytkę wokół dla łatwego ponownego wypróbowania apply
, lub dla patrząc na itp. Jeśli {[13] } jest w stanie wydobyć skrytkę, natychmiast również drop
ją, a jeśli nagle zdasz sobie sprawę, że chcesz wydobyć ją gdzieś indziej (w innej gałęzi), lub z --index
, lub czymś takim, to nie jest takie proste. Jeśli apply
, ty możesz wybrać kiedy drop
.
To wszystko jest dość drobne w ten czy inny sposób, ale dla nowicjusza do Gita, powinno być mniej więcej tak samo. (A resztę możesz pominąć!)
What if robisz bardziej zaawansowane czy bardziej skomplikowane rzeczy?
Istnieją co najmniej trzy lub cztery różne "sposoby użycia Git stash". Powyższe odnosi się do" ścieżki 1","łatwej ścieżki":
-
Zacząłeś od czystej gałęzi, pracowałeś nad pewnymi zmianami, a potem zdałeś sobie sprawę, że robisz je w złej gałęzi. Po prostu chcesz wziąć zmiany, które masz teraz i "przenieść" je do innej gałęzi.
Jest to prosty przypadek, opisany powyżej. Run
git stash save
(or plaingit stash
, to samo). Sprawdź drugą gałąź i użyjgit stash apply
. Dzięki temu git połączy się z Twoimi wcześniejszymi zmianami, używając dość potężnego mechanizmu scalania. sprawdź dokładnie wyniki (zgit diff
), aby zobaczyć, czy ci się podobają, a jeśli Tak, użyjgit stash drop
, aby upuścić skrytkę. Jesteś skończony! -
Zacząłeś pewne zmiany i Ukryłeś je. Potem przełączyłeś się na inną gałąź i zacząłeś kolejne zmiany, zapominając, że masz schowane.
Teraz chcesz aby zachować, a nawet przenieść, te zmiany, i zastosuj również swój Schowek.
Możesz w rzeczywistości
git stash save
ponownie, ponieważgit stash
tworzy "stos" zmian. Jeśli to zrobisz, masz dwa znaki, jeden o nazwiestash
- ale możesz również napisaćstash@{0}
- i jeden pisanystash@{1}
. Użyjgit stash list
(w dowolnym momencie), aby zobaczyć je wszystkie. Najnowszy jest zawsze najniższy. Kiedygit stash drop
, spada najnowszy, a ten, który byłstash@{1}
, przechodzi na szczyt stosu. Gdybyś miał jeszcze więcej, ten to byłostash@{2}
staje sięstash@{1}
, i tak dalej.Możesz
apply
, a następniedrop
także konkretny Schowek:git stash apply stash@{2}
i tak dalej. Upuszczając określony zapas, zmienia numerację tylko tych wyżej ponumerowanych. Ponownie, ten bez numeru jest równieżstash@{0}
.Jeśli zgromadzisz dużo zapasów, może być dość bałagan (czy towar chciałem
stash@{7}
czy był {38]}? Chwila, właśnie nacisnąłem kolejny, teraz są 8 i 5?). Ja osobiście wolę przenieść te zmiany do nowego oddziału, ponieważ oddziały mają imiona, acleanup-attempt-in-December
znaczy dla mnie o wiele więcej niżstash@{12}
. (Poleceniegit stash
pobiera opcjonalny save-message, a to może pomóc, ale jakoś wszystkie moje blokady kończą się nazwamiWIP on branch
.) -
(Extra-advanced) użyłeś
git stash save -p
, lub ostrożniegit add
-ed i/lubgit rm
-ed określonych bitów kodu przed uruchomieniemgit stash save
. Jedna wersja była przechowywana w magazynie Indeks/staging, a druga (Inna) w drzewie roboczym. Chcesz to wszystko zachować. Więc teraz ty użyjgit stash apply --index
, a to czasem zawodzi z:Conflicts in index. Try without --index.
Używasz
git stash save --keep-index
, aby przetestować "co zostanie popełnione". Ta odpowiedź wykracza poza zakres tej odpowiedzi; zobacz inną odpowiedź StackOverflow.
W skomplikowanych przypadkach, polecam zacząć od" czystego " katalogu roboczego, zatwierdzając wszelkie zmiany, które masz teraz (w nowej gałęzi, jeśli chcesz). W ten sposób "gdzieś", które je stosujesz, nie ma nic innego w to, i będziesz tylko próbował ukrytych zmian:
git status # see if there's anything you need to commit
# uh oh, there is - let's put it on a new temp branch
git checkout -b temp # create new temp branch to save stuff
git add ... # add (and/or remove) stuff as needed
git commit # save first set of changes
Teraz jesteś na "czystym" punkcie wyjścia. A może bardziej tak:
git status # see if there's anything you need to commit
# status says "nothing to commit"
git checkout -b temp # optional: create new branch for "apply"
git stash apply # apply stashed changes; see below about --index
Najważniejszą rzeczą do zapamiętania jest to, że "stash" to commit, to tylko nieco" zabawny/dziwny "commit, który nie jest "na gałęzi". Operacja apply
sprawdza, co zmienił commit i próbuje go powtórzyć gdziekolwiek jesteś teraz. Schowek nadal tam będzie (apply
trzyma go w pobliżu), więc możesz spojrzeć na niego więcej lub zdecydować to było złe miejsce, żeby spróbować jeszcze raz.
Za każdym razem, gdy masz skrytkę, możesz użyć git stash show -p
, aby zobaczyć uproszczoną wersję tego, co znajduje się w skrytce. (Ta uproszczona wersja patrzy tylko na zmiany "ostatecznego drzewa pracy", Nie zapisany indeks zmienia się, który --index
jest przywracany oddzielnie.) Polecenie git stash apply
, Bez --index
, próbuje teraz wprowadzić te te same zmiany w Twoim katalogu roboczym.
To prawda, nawet jeśli Mam już pewne zmiany. Polecenie apply
chętnie stosuje stash do zmodyfikowanego katalogu roboczego (a przynajmniej próbuje go zastosować). Można, na przykład, zrobić to:
git stash apply stash # apply top of stash stack
git stash apply stash@{1} # and mix in next stash stack entry too
Możesz wybrać kolejność "apply" tutaj, wybierając poszczególne stasze do zastosowania w określonej kolejności. Zauważ jednak, że za każdym razem robisz "Git merge" i jak ostrzega dokumentacja merge:
Uruchamianie git merge z nietrywialnymi zmianami jest zniechęcony: o ile jest to możliwe, może pozostawić cię w stanie, który jest trudny wycofać się w razie konfliktu.
Jeśli zaczynasz od czystego katalogu i wykonujesz tylko kilka operacji git apply
, łatwo jest się wycofać: użyj git reset --hard
, aby wrócić do stanu czystego i zmienić swoje operacje apply
. (Dlatego polecam zacząć od czystego katalogu roboczego, w tych skomplikowanych przypadkach.)
A co z najgorszym możliwy przypadek?
Załóżmy, że robisz wiele zaawansowanych rzeczy z Gitem, i stworzyłeś skrytkę i chcesz git stash apply --index
, ale nie jest już możliwe zastosowanie zapisanej skrytki z --index
, ponieważ gałąź zbytnio się rozeszła od czasu, kiedy ją zapisałeś.
Po to jest git stash branch
.
Jeśli:
- sprawdź dokładny commit byłeś na kiedy zrobiłeś oryginalny
stash
, a następnie - Utwórz nową gałąź i wreszcie
git stash apply --index
Próba odtworzenia zmian zdecydowaniezadziała. To właśnie robi git stash branch newbranch
. (A następnie upuszcza zapas, ponieważ został pomyślnie zastosowany.)
Kilka ostatnich słów o --index
(co to do cholery jest?)
To, co robi --index
jest proste do wyjaśnienia, ale trochę skomplikowane wewnętrznie:
- kiedy masz zmiany, musisz
git add
(lub "etap") je przedcommit
ing. - Tak więc, kiedy uruchomiłeś
git stash
, mogłeś edytować oba plikifoo
izorg
, ale tylko zainscenizowałeś jeden z nich. - więc Kiedy poprosisz o odzyskanie towaru, może być miło, jeśli
git add
jest toadd
ed rzeczy i robi Niegit add
nie dodanych rzeczy. Oznacza to, że jeśliadd
edfoo
, ale niezorg
przed wykonaniemstash
, może być miło mieć dokładnie taką samą konfigurację. To, co było wystawione, powinno być ponownie wystawione; to, co zostało zmodyfikowane, ale nie wystawione, powinno być ponownie zmodyfikowane, ale nie wystawione.
Flaga --index
do apply
próbuje ustawić rzeczy w ten sposób. Jeśli twoje drzewo pracy jest czyste, to zwykle po prostu działa. Jeśli jednak twoje drzewo pracy ma już rzeczy add
ed, możesz zobaczyć, jak mogą tu być pewne problemy. Jeśli pominiesz --index
, operacja apply
nie podejmie próby zachowania całej konfiguracji staged/unstaged. Zamiast tego, po prostu wywołuje mechanizm scalania Gita, używając commita drzewa roboczego w "stash bag" . Jeśli nie dbałość o zachowanie staged/unstaged, pomijanie --index
sprawia, że o wiele łatwiej jest git stash apply
robić swoje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:15
git stash pop
Wszystko wróci na swoje miejsce
Jak sugerowano w komentarzach, możesz użyć git stash branch newbranch
, Aby zastosować stash do nowej gałęzi, która jest taka sama jak running:
git checkout -b newbranch
git stash pop
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 08:35:42
Aby to uprościć, masz dwie opcje, aby ponownie zastosować swój schowek:
-
git stash pop
- przywraca stan zapisany, ale usuwa skrytkę z tymczasowego magazynu. -
git stash apply
- Przywróć stan zapisany i pozostawia listę skrytek do późniejszego ponownego użycia.
Możesz przeczytać bardziej szczegółowo o Git stashes w tym artykule.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-25 07:49:29