git-stash kontra git-branch

92

W poprzednim pytaniu dotyczącym Gita Daniel Benamy mówił o przepływie pracy w Git:

Pracowałem nad mistrzem i wykonałem kilka rzeczy, a potem zdecydowałem, że chcę wstrzymać tę pracę. Zrobiłem kopię zapasową kilku zatwierdzeń, a następnie rozgałęziłem się zanim zacząłem moją bzdurną pracę.

Chciał przywrócić swój stan pracy do poprzedniego punktu w czasie bez utraty obecnych zmian. Wszystkie odpowiedzi dotyczyły na różne sposoby czegoś w rodzaju

git branch -m master crap_work
git branch -m previous_master master

Jak to się ma do tego git stash? Jestem trochę zdezorientowany, próbując zobaczyć, jaki jest inny przypadek użycia tutaj, kiedy wydaje się, że wszystko git stashjest już obsługiwane przez rozgałęzienie…


@ Jordi Bunster : Dzięki, to wszystko wyjaśnia . Wydaje mi się, że uważałbym „przechowywanie” za lekką, bezimienną gałąź. Więc wszystko może zrobić skrytka, gałąź też może, ale z większą ilością słów. Ładny!

Will Robertson
źródło

Odpowiedzi:

109

„stash” pobiera niezatwierdzone, „ brudne ” rzeczy z kopii roboczej i przechowuje je, pozostawiając czystą kopię roboczą.

Tak naprawdę wcale nie rozgałęzia się. Następnie możesz umieścić tę skrytkę na dowolnej innej gałęzi. Lub, od Git 1.6, możesz:

git stash branch <branchname> [<stash>]

aby umieścić skrytkę na nowej gałęzi, wszystko w jednym poleceniu.

Tak więc skrytka działa świetnie, jeśli jeszcze nie zdecydowałeś się na „ niewłaściwą ” gałąź.

Jeśli już się zaangażowałeś, lepszą alternatywą jest przepływ pracy, który opisujesz w swoim pytaniu. A tak przy okazji, masz rację: Git jest bardzo elastyczny, a wraz z tą elastycznością nakłada się na siebie funkcjonalność.

Jordi Bunster
źródło
1
jedna rzecz, która mnie gryzie ... czy możesz napisać, jak właściwie wygląda [<stash>]! Umieścili to w tej notacji w dokumentach, ale nie jest oczywiste, czy powinno to być 1, @ {1} czy co.
Gregg Lind
1
Jeśli chcesz odnieść się do konkretnej skrytki „N”, użyj skrytki @ {N}
Jordi Bunster
9
Zobacz git stash listnazwy swoich skrytek.
idbrii
6
Gregg, tak, możesz: git stash save (nazwa twojego skrytki). Sprawia, że ​​jest bardziej przydatny, jeśli często go używasz, abyś wiedział, co robi każda skrytka. Możesz użyć git stash show -p (nazwa), aby wyświetlić łatkę skrytki.
Thomas Vander Stichele
7
również, git stash show -uaby pokazać różnicę między zasobem a kopią roboczą.
ken
49

Po przywróceniu skrytki zmiany zostaną ponownie zastosowane, a Ty będziesz kontynuować pracę nad kodem.

Przechowywać aktualne zmiany

$ git stash save 
Saved "WIP on master: e71813e..."

Możesz też mieć więcej niż jedną skrytkę. Skrytka działa jak stos. Za każdym razem, gdy zapisujesz nową skrytkę, jest ona umieszczana na wierzchu stosu.

$ git stash list
stash@{0}: WIP on master: e71813e..."

Zwróć uwagę na stash@{0}część? To twój identyfikator skrytki. Będziesz go później potrzebować, aby go przywrócić. Zróbmy to teraz. Identyfikator skrytki zmienia się z każdą utworzoną skrytką. stash @ {0} odnosi się do ostatniego utworzonego skrytki.

Aby założyć skrytkę

$ git stash apply stash@{0}

Po zastosowaniu możesz zauważyć, że skrytka wciąż tam jest. Możesz go upuścić, jeśli już go nie potrzebujesz.

$ git stash drop stash@{0}

Lub, ponieważ skrytka zachowuje się jak stos, możesz wyjąć ostatnią zapisaną skrytkę:

$ git stash pop

Jeśli chcesz wyczyścić wszystkie skrytki, uruchom polecenie „wyczyść”:

$ git stash clear

Może się zdarzyć, że nie korzystasz tak często ze skrytek. Jeśli chcesz po prostu szybko ukryć swoje zmiany i przywrócić je później, możesz pominąć identyfikator skrytki.

$ git stash
...
$ git stash pop

Możesz poeksperymentować ze skrytką, zanim użyjesz jej do naprawdę ważnej pracy.

Mam też bardziej dogłębną wersję tego opublikowaną na moim blogu .

Ariejan
źródło
o wiele bardziej pomocne źródło niż przypuszczalna
``
9

Zawsze uważam na git stash. Jeśli przechowujesz kilka razy, sprawy stają się nieuporządkowane. git stash list wyświetli numerowaną listę skrytek, które stworzyłeś, wraz z wiadomościami, jeśli je dostarczyłeś ... Ale problem polega na tym, że nie możesz wyczyścić skrytek, z wyjątkiem brutalnego wyczyszczenia skrytki git (co usuwa je wszystkie) . Więc jeśli nie zawsze jesteś analfabetą w podawaniu super-opisowych wiadomości do swoich skrytek (jest to trochę sprzeczne z filozofią skrytki), kończysz z niezrozumiałą grupą skrytek.

Jedyny znany mi sposób, aby dowiedzieć się, który z nich to użyć gitk - wszystko i znaleźć skrytki. Przynajmniej pozwala to zobaczyć, w jakim zatwierdzeniu została utworzona skrytka, a także różnicę wszystkiego, co zawiera ta skrytka.

Zauważ, że używam git 1.5.4.3 i myślę, że 1.6 dodaje git stash pop, który, jak sądzę, zastosowałby wybrany schowek i usunąłby go z listy. Co wydaje się dużo czystsze.

Na razie zawsze staram się rozgałęziać, chyba że jestem absolutnie pewien, że wrócę do tego skrytki tego samego dnia, nawet w ciągu godziny.

webmat
źródło
3
Czy tworzysz gałęzie bez nadawania im przydatnych nazw? Jeśli nie, to nie rozumiem, dlaczego nie robisz tego samego ze skrytką. Jeśli naprawdę chcesz wiedzieć, co zawierają, po prostu użyj git-stash show, aby pokazać, które pliki się zmieniły, lub git-stash zastosuj i git-diff, aby zobaczyć rzeczywiste różnice. Utrzymywanie przyciętych skrytek jest tym samym, co kontrolowanie gałęzi.
Xiong Chiamiov
18
w rzeczywistości możesz usunąć pojedynczy schowek, używającgit stash drop [<stash>]
kumarharsh
1
To prawda, git od dawna ma git stash drop. Obecnie jest to znacznie mniejszy PITA. Używam go codziennie, a teraz nawet przez długi czas.
webmat
3

Jeśli szukasz przepływu pracy, który może być bardziej odpowiedni niż git stash, możesz spojrzeć na git-bottle . Jest to narzędzie służące do zapisywania i przywracania różnych stanów roboczych git jako normalnych zatwierdzeń git, efektywnie wykonując migawkę bieżącego i stosownego stanu twojego drzewa roboczego i wszystkich różnych stanów plików pokazanych w statusie git.

Kluczowe różnice w stosunku do git stash:

  • git stashzapisuje brudny stan git wąsko (zmodyfikowane pliki i dodane pliki w indeksie), podczas gdy git-bottlejest przeznaczony do zapisywania wszystkiego , co różni się HEADi rozróżnia w zachowujący sposób między zmodyfikowanymi, zmodyfikowanymi i nie dodanymi, nie dodanymi, nie scalonymi ścieżkami i pełne stany ponownego bazowania / scalania (tylko ścieżki w ramach .gitignorenie są zapisywane).
  • git stashzapisuje, aby schować przedmioty, które musisz śledzić oddzielnie. Gdybym coś ukrył 2 tygodnie temu, mógłbym tego nie pamiętać, podczas gdy git-bottlezapisuje jako wstępne zatwierdzenie aktualnej gałęzi . Odwrotna akcja jest git-unbottleodpowiednikiem git stashpopu. Możliwe jest wypychanie i udostępnianie tych zatwierdzeń między repozytoriami. Może to być przydatne w przypadku zdalnych kompilacji, w których masz inne repozytorium na zdalnym serwerze tylko do budowania lub do współpracy z innymi osobami przy rozwiązywaniu konfliktów.
Dan Aloni
źródło