Czy git stash jest specyficzny dla gałęzi czy dla całego repozytorium?

97

Poszedłem do gałęzi i trochę popracowałem. Chciałem przejść do innej gałęzi, ale nie chciałem się angażować, więc to zrobiłem git stash. Wtedy zrobiłem git checkout <otherbranch>. Pracowałem tam trochę i tak jak w pierwszej oddziale chciałem się z niej wyłączyć przed podjęciem pracy. Więc git stashtam też zrobiłem . Przełączałem się z powrotem na pierwszą gałąź i próbowałem ją rozpakować ( git stash pop) myśląc, że dostanie skrytkę z tej konkretnej gałęzi. Byłem zaskoczony, że otworzył skrytkę z <otherbranch>(najnowszy stashed). Miałem wrażenie, że skrytka jest specyficzna dla gałęzi, ale to zachowanie wskazuje, że jest tylko jedna skrytka dla całego lokalnego repozytorium.

Czy jest git stashspecyficzna dla branży czy dla całego repozytorium? Jeśli dotyczy całego repozytorium, czy mogę przekazać mu opcje, aby było specyficzne dla gałęzi?

amfibia
źródło

Odpowiedzi:

43

Aby zobaczyć aktualny stos skrytki:

git stash list

Aby wybrać konkretną skrytkę ze stosu, odnieś się do niej zgodnie z powyższym.stash@{number}

Jeśli chcesz, aby zachowanie dotyczyło poszczególnych gałęzi, możesz po prostu wykonać zatwierdzenie (lub wiele zatwierdzeń) w gałęzi. Zawsze możesz "cofnąć" zatwierdzenie (a) później (np. Za pomocą git reset, albo --softalbo --mixed; zobacz dokumentację resetowania git ; lubgit rebase -i aby zachować tylko ostateczne "prawdziwe" zatwierdzenie (a) podczas odrzucania tymczasowych).

(Aby naprawdę emulować git stash, potrzebujesz co najmniej dwóch zatwierdzeń, jednego dla stanu indeksu i jednego dla stanu drzewa roboczego. Jeśli jednak nie planujesz zapisywać i przywracać stanu indeksu, możesz po prostu git add -Acały stan drzewa roboczego i umieść to w tymczasowym zatwierdzeniu. Alternatywnie, git stashjest to skrypt powłoki, więc możesz go dość łatwo skopiować i zmodyfikować, aby działał domyślnie dla każdej gałęzi, używając np. jako roboczej przestrzeni nazw, a nie pojedynczej globalnej dla całe repozytorium. Nadal możesz przenosić zasoby z jednej gałęzi do drugiej, nadając jej jawną nazwę).refs/pb-stash/branchrefs/stash

torek
źródło
czy wiesz, jak wyświetlić listę plików każdego stash listelementu oprócz samego opisu?
amfibia
2
git stash show(lub git stash show stash@{<number>}do czegoś innego niż @{0}wersja) daje diff --stat; dodaj, -paby uzyskać większą różnicę. Uwaga: to porównuje "drzewo robocze" w "torbie skrytki" z zatwierdzeniem, z którego wisi; nie ma interfejsu front-end, aby zobaczyć, co znajduje się w „indeksie” w podanym worku.
torek
56

Nie i nie. Magazyn git jest przypisany do repozytorium.

Oto fajna strona o tym, jak go używać.

abasterfield
źródło
czy druga skrytka zastępuje pierwszą? IOW, czy jeśli zrobię dwa skrytki, ale nie będę ich usuwał pomiędzy nimi, czy zgubię pierwszy?
amfibia
1
Nie, dostaniesz stos skrytek (ostatni na wejściu, pierwszy na wyjściu).
Wsuwasz jedną skrytkę
18

git stash nie dotyczy gałęzi.

  • Zamiast git stash(co można łatwo zgubić, gdy masz dużo skrytek i gałęzi)
  • Proponuję zrobić git commit aby zapisać niedokończony kod w swojej gałęzi, a kiedy będziesz gotowy do zakończenia kodu, zrób to, git reset ${COMMIT_HASH_VALUE}aby odzyskać niedokończony kod
  • git commita git resetgdy są używane razem poprawnie, mogą symulować plikgit stash dla określonej gałęzi

Oto typowy scenariusz z prawdziwego życia, który pokazuje wartość i użycie commitreset poleceń i :

  • pracujesz na gałęzi funkcji X, a Twój kod nawet nie kompiluje się ani nie przechodzi testów
  • jest błąd, który ma wyższy priorytet niż obecna nowa funkcja, dlatego musisz natychmiast rozpocząć pracę nad jego naprawą
  • zamiast robić git stash (a skrytka ginie w miksie, ponieważ masz wiele skrytek i wiele gałęzi)
  • możesz zrobić git commitna gałęzi funkcji X
    • zapisz COMMIT_HASH_VALUEna później
  • pobierz nową gałąź Y dla poprawki
  • zakończ poprawkę w gałęzi Y (wykonaj żądanie scalenia, aby uzyskać poprawkę do linii bazowej i usunąć gałąź poprawki)
  • następnie ponownie wyewidencjonuj gałąź funkcji X
  • aby pobrać niedokończoną pracę, która nie skompilowała się lub nie przeszła testów -> po prostu zrób plik git reset ${COMMIT_HASH_VALUE}

(FYI, domyślna wartość git resetto --mixed)

Trevor Boyd Smith
źródło
2
Przydatnym skrótem do resetowania w tym scenariuszu jest git reset HEAD~1.
Sam A. Horvath-Hunt
1
@samHH Miałem o jedną za dużo instancji, w których git reset HEAD ^ 1 przypadkowo został trafiony dwukrotnie ... więc nie używam HEAD^1lub HEAD~1.
Trevor Boyd Smith
12

Nie jestem pewien, dlaczego każda odpowiedź tutaj sugeruje emulowanie skrytki z commit+ reset. Skrytka jest idealna w użyciu, szczególnie podczas pracy na wielu gałęziach. Nie chcę też zatwierdzać, gdy pracuję na wielu gałęziach, ponieważ chcę, aby wszystkie zmodyfikowane zmiany były nadal podświetlane w moim edytorze po powrocie.

Oto przepływ pracy w skrytce:

Ilekroć musisz zmienić gałąź i nie jesteś gotowy do zatwierdzenia, zapisz zmiany na stosie

git stash save "Your custom stash message"

Kiedy wrócisz do oddziału, sprawdź skrytkę

git stash list

wprowadź opis obrazu tutaj

Jeśli jesteś na gałęzi, FixIssue0203możesz użyć, git stash popponieważ spowoduje to nałożenie góry stash@{0}i usunięcie go ze skrytki.

Jeśli jednak jesteś w gałęzi ImproveReadme, powinieneś najpierw umieścić skrytkę 1, git stash apply stash@{1}a następnie usunąć skrytkę 1 ze stosu git stash drop stash@{1}.

Otóż ​​to!

Adam
źródło