Często używam git stash
oraz git stash pop
do zapisywania i przywracania zmian w moim drzewie roboczym. Wczoraj miałem pewne zmiany w moim drzewie roboczym, które ukryłem i wyskoczyłem, a następnie wprowadziłem więcej zmian w moim drzewie roboczym. Chciałbym wrócić i przejrzeć wczorajsze ukryte zmiany, ale git stash pop
wydaje się, że usuwają wszystkie odniesienia do powiązanego zatwierdzenia.
Wiem, że jeśli użyję,git stash
to .git / refs / stash zawiera odniesienie do zatwierdzenia użytego do utworzenia skrytki. A .git / logs / refs / stash zawiera całą skrytkę. Ale tych odniesień już nie ma git stash pop
. Wiem, że zatwierdzenie wciąż jest gdzieś w moim repozytorium, ale nie wiem, co to było.
Czy istnieje prosty sposób na odzyskanie wczorajszego odniesienia do skrytki?
Pamiętaj, że nie jest to dla mnie dzisiaj krytyczne, ponieważ mam codzienne kopie zapasowe i mogę wrócić do wczorajszego drzewa roboczego, aby uzyskać zmiany. Pytam, bo musi być prostszy sposób!
git stash pop
, możesz to zrobićgit stash apply
. Robi to samo, ale nie usuwa odwołania do zastosowanej skrytki.git stash
,git pull -r upstream
,git push -f origin
,git stash pop
, i pop powiedział „fatal: dziennik odn / ukryta jest pusta”. Tried Próbowałem wielu z tych odpowiedzi, nic nie działało. Kiedy zajrzałem do .git / refs / stash , SHA tam był. Może problem z oznaczeniem dysku sieciowego Windows do synchronizacji offline? 🤷♂️Odpowiedzi:
Po poznaniu skrótu, który upuściłeś zatwierdzenie skrytki, możesz zastosować go jako skrytkę:
Możesz też utworzyć dla niego osobną gałąź
Następnie możesz robić, co chcesz, za pomocą wszystkich zwykłych narzędzi. Kiedy skończysz, po prostu zdmuchnij gałąź.
Znajdowanie skrótu
Jeśli właśnie go otworzyłeś, a terminal jest nadal otwarty, nadal
git stash pop
będziesz mieć wydrukowaną wartość skrótu na ekranie (dzięki, Dolda).W przeciwnym razie można go znaleźć, używając tego dla systemu Linux, Unix lub Git Bash dla systemu Windows:
... lub używając Powershell dla Windows:
Spowoduje to wyświetlenie wszystkich zatwierdzeń na końcach wykresu zatwierdzeń, do których nie ma już odniesienia z żadnego odgałęzienia lub tagu - każde utracone zatwierdzenie, w tym każde utworzone przez Ciebie ukryte zatwierdzenie, będzie znajdować się gdzieś na tym wykresie.
Najłatwiejszym sposobem na znalezienie zatwierdzonego skrytki jest prawdopodobnie przekazanie tej listy do
gitk
:... lub zobacz odpowiedź z emragins, jeśli używasz Powershell dla Windows.
Spowoduje to uruchomienie przeglądarki repozytorium pokazującej każde zatwierdzenie w repozytorium , niezależnie od tego, czy jest osiągalne, czy nie.
Możesz
gitk
tam zamienić coś takiego,git log --graph --oneline --decorate
jeśli wolisz ładny wykres na konsoli niż osobną aplikację GUI.Aby wykryć zatwierdzenia ukryć, poszukaj komunikatów zatwierdzania tego formularza:
WIP w somebranch : commithash Jakaś stara wiadomość zatwierdzenia
Uwaga : Komunikat zatwierdzenia będzie w tej formie (zaczynając od „WIP włączony”) tylko wtedy, gdy nie dostarczysz wiadomości w tym momencie
git stash
.źródło
%{ $_.Split(' ')[2]; }
powinno odpowiadać poleceniu PowerShell{print $3}
w tymawk
poleceniu, ale nie mam systemu Windows, który by to przetestował, a nadal potrzebujesz odpowiednika dla tej/dangling commit/
części. W każdym razie po prostu uruchomgit fsck --no-reflog
i spójrz na wynik. Chcesz skróty z linii „wiszące zatwierdzenie <commitID>”.git stash save "<message>"
).git fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
prawdopodobnie ostatni wpis jest tym, którego chceszstash apply
.git stash apply {ref}
przywrócił upuszczoną skrytkę!git
jest tak świetne, że powinno być nielegalne!Jeśli nie zamknąłeś terminala, po prostu spójrz na dane wyjściowe z,
git stash pop
a będziesz miał identyfikator obiektu upuszczonej skrytki. Zwykle wygląda to tak:(Zauważ, że
git stash drop
tworzy również tę samą linię.)Aby odzyskać ten zapas, po prostu biegnij
git branch tmp 2cae03e
, a dostaniesz go jako gałąź. Aby przekonwertować to na ukryty, uruchom:Posiadanie go jako gałęzi pozwala również swobodnie nim manipulować; na przykład, aby wybrać go lub połączyć.
źródło
git stash apply commitid
wtedygit stash
, aby otrzymać nowy zapas.git stash pop
, to również nie zrzuci skrytki, więc zwykle nie stanowi to problemu.git stash pop
. Jeśli chcesz zastosować skrytkę bez upuszczania, użyjgit stash apply
zamiast tego. Dodatkowo, jeśli chcesz zastosować zmianę do kilku gałęzi, możesz również zamiast tego wybrać zatwierdzenie.Chciałem tylko wspomnieć o tym dodatku do zaakceptowanego rozwiązania. Nie było to dla mnie od razu oczywiste za pierwszym razem, gdy wypróbowałem tę metodę (być może powinno być), ale aby zastosować ukrytą wartość z wartości skrótu, po prostu użyj polecenia „zastosuj ukrytą git”:
Kiedy byłem nowy w Git, nie było to dla mnie jasne i próbowałem różnych kombinacji „Git Show”, „Git Apply”, „Patch” itp.
źródło
Aby uzyskać listę skrytek, które nadal znajdują się w twoim repozytorium, ale nie są już dostępne:
Jeśli nadałeś tytuł skrytce, zamień „WIP”
-grep=WIP
na końcu polecenia na część wiadomości, np-grep=Tesselation
.Polecenie wyświetla grep dla „WIP”, ponieważ domyślna wiadomość zatwierdzenia dla skrytki ma postać
WIP on mybranch: [previous-commit-hash] Message of the previous commit.
źródło
!
).Właśnie skonstruowałem polecenie, które pomogło mi znaleźć moje zgubione zatwierdzenie skrytki:
Spowoduje to wyświetlenie listy wszystkich obiektów w drzewie .git / objects, zlokalizowanie obiektów typu commit, a następnie przedstawienie podsumowania każdego z nich. Od tego momentu wystarczyło przejrzeć commits, aby znaleźć odpowiedni „WIP w pracy: 6a9bb2” („work” to moja gałąź, 619bb2 to ostatnie zatwierdzenie).
Zauważam, że jeśli użyję „git stash Apply” zamiast „git stash pop”, nie miałbym tego problemu, a jeśli użyję „git stash save message ”, łatwiej byłoby znaleźć zatwierdzenie.
Aktualizacja: Z pomysłem Nathana staje się on krótszy:
źródło
git fsck --unreachable | grep commit
powinien pokazywać sha1, chociaż lista, którą zwraca, może być dość duża.git show <sha1>
pokaże, czy chcesz zatwierdzić.git cherry-pick -m 1 <sha1>
połączy zatwierdzenie z bieżącą gałęzią.źródło
Odpowiednik Windows PowerShell przy użyciu gitk:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
Prawdopodobnie istnieje bardziej skuteczny sposób, aby to zrobić w jednej rurze, ale to działa.
źródło
Jeśli chcesz przywrócić utraconą skrytkę, najpierw musisz znaleźć skrót utraconej skrytki.
Jak zasugerował Arystoteles Pagaltzis,
git fsck
powinien ci pomóc.Osobiście używam swojego
log-all
aliasu, który pokazuje mi każde zatwierdzenie (odzyskiwalne zatwierdzenia), aby mieć lepszy wgląd w sytuację:Możesz przeprowadzić jeszcze szybsze wyszukiwanie, jeśli szukasz tylko wiadomości „WIP on”.
Gdy poznasz swój sha1, po prostu zmienisz swój dziennik skrytki, aby dodać starą skrytkę:
Prawdopodobnie wolisz mieć powiązaną wiadomość, więc
-m
Będziesz nawet chciał użyć tego jako aliasu:
źródło
-d\\
powinno być-d\
(lub nawet jaśniej-d' '
)git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
Podobało mi się podejście Arystotelesa, ale nie podobało mi się używanie GITK ... ponieważ przyzwyczaiłem się do używania GIT z wiersza poleceń.
Zamiast tego wziąłem wiszące zatwierdzenia i wyprowadziłem kod do pliku DIFF w celu przejrzenia w moim edytorze kodu.
Teraz możesz załadować wynikowy plik diff / txt (znajdujący się w folderze domowym) do edytora txt i zobaczyć rzeczywisty kod i wynikowy SHA.
Więc po prostu użyj
źródło
Możesz wyświetlić listę wszystkich nieosiągalnych zatwierdzeń, pisząc to polecenie w terminalu -
Sprawdź nieosiągalny skrót zatwierdzenia -
Wreszcie zastosuj, jeśli znajdziesz schowany przedmiot -
źródło
Dlaczego ludzie zadają to pytanie? Ponieważ jeszcze nie wiedzą o logu ani go nie rozumieją.
Większość odpowiedzi na to pytanie daje długie polecenia z opcjami, których prawie nikt nie pamięta. Tak więc ludzie wchodzą w to pytanie i kopiują, wklejając wszystko, co ich zdaniem potrzebują, i zapominają o tym niemal natychmiast.
Radziłbym każdemu, kto ma to pytanie, aby po prostu sprawdził rejestr (git reflog), nie więcej. Gdy zobaczysz tę listę wszystkich zatwierdzeń, istnieje sto sposobów, aby dowiedzieć się, czego szukasz, i wybrać ją z wiśni lub utworzyć z niej gałąź. W trakcie tego procesu dowiesz się o ponownym logowaniu i przydatnych opcjach różnych podstawowych poleceń git.
źródło
W OSX z git v2.6.4 po prostu przypadkowo uruchamiam upuszczanie git, a następnie znalazłem go, przechodząc przez poniższe kroki
Jeśli znasz nazwę skrytki, użyj:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>
w przeciwnym razie znajdziesz identyfikator wyniku, ręcznie:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show
Następnie, gdy znajdziesz identyfikator zatwierdzenia, po prostu naciśnij przycisk git stash Apply {commit-id}
Mam nadzieję, że to pomoże komuś szybko
źródło
Chcę dodać do zaakceptowanego rozwiązania kolejną dobrą drogę do przejścia przez wszystkie zmiany, gdy albo nie masz dostępnego gitk, albo nie ma X dla danych wyjściowych.
Następnie otrzymujesz wszystkie różnice dla tych skrótów wyświetlanych jeden po drugim. Naciśnij „q”, aby przejść do następnego porównania.
źródło
Nie mogłem uzyskać żadnej odpowiedzi do pracy w systemie Windows w prostym oknie poleceń (w moim przypadku Windows 7).
awk
,grep
ISelect-string
nie zostały uznane za poleceń. Więc spróbowałem innego podejścia:git fsck --unreachable | findstr "commit"
start cmd /k git show
będzie wyglądać mniej więcej tak:
start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e
git stash apply (your hash)
może nie jest najlepszym rozwiązaniem, ale działało dla mnie
źródło
Akceptowana odpowiedź Arystotelesa pokaże wszystkie dostępne zatwierdzenia, w tym zatwierdzenia inne niż ukryte. Aby odfiltrować hałas:
Dotyczy to tylko zatwierdzeń, które mają dokładnie 3 zatwierdzenia nadrzędne (które będą miały ukrytą zawartość) i których komunikat zawiera „WIP włączone”.
Pamiętaj, że jeśli zapisałeś swoją skrytkę z wiadomością (np
git stash save "My newly created stash"
), Zastąpi to domyślną wiadomość „WIP na ...”.Możesz wyświetlić więcej informacji o każdym zatwierdzeniu, np. Wyświetlić komunikat zatwierdzenia lub przekazać go do
git stash show
:źródło
Moim ulubionym jest ten jednowarstwowy:
Jest to zasadniczo ten sam pomysł, co ta odpowiedź, ale znacznie krótszy. Oczywiście nadal możesz dodać
--graph
aby uzyskać wyświetlanie podobne do drzewa.Po znalezieniu zatwierdzenia na liście zastosuj za pomocą
Dla mnie użycie
--no-reflogs
ujawniło zgubiony wpis skrytki, ale--unreachable
(jak stwierdzono w wielu innych odpowiedziach) nie.Uruchom go na git bash, gdy jesteś w systemie Windows.
Kredyty: Szczegóły powyższych poleceń pochodzą z https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf
źródło
Odzyskano go, wykonując następujące czynności:
Zidentyfikuj usunięty kod skrótu skrytki:
gitk --all $ (git fsck --no-reflog | awk '/ dangling commit / {print $ 3}')
Cherry Pick the Stash:
git cherry-pick -m 1 $ stash_hash_code
Rozwiąż konflikty, jeśli występują, używając:
git scaletool
Dodatkowo możesz mieć problemy z komunikatem zatwierdzenia, jeśli używasz gerrit. Zapisz swoje zmiany przed następnymi alternatywami:
źródło
Poszedłem tu poszukać sposobu odzyskania skrytki, niezależnie od tego, co sprawdziłem. W szczególności schowałam coś, a potem sprawdziłam starszą wersję, a potem wyskoczyłam, ale skrytka była w tym momencie niedostępna, więc skrytka zniknęła; Nie mogłem po prostu
git stash
odłożyć go z powrotem na stos. To działało dla mnie:Z perspektywy czasu powinienem był
git stash apply
nie używaćgit stash pop
. Robiłembisect
i miałem małą łatkę, którą chciałem zastosować na każdymbisect
kroku. Teraz robię to:źródło
stash apply
.