git switch branch bez odrzucania lokalnych zmian


181

W porządku, powiedzmy, że pewnego dnia dokonamy kilku modyfikacji, a kiedy je wprowadzimy, zauważymy, że pracowaliśmy nad niewłaściwą gałęzią.

Jak możemy zmusić git do zmiany gałęzi bez odrzucania lokalnych zmian .

Prawdopodobnie zamierzam to zrobić naiwnie, czekając na odpowiedź, ale chciałbym wiedzieć, czy istnieje poprawna procedura, ponieważ skłamałbym, gdybym powiedział, że wcześniej mi się to nie przytrafiło ...

  • Kopia zapasowa zmieniła repozytorium
  • git reset --hard
  • git checkout right-branch
  • Przywróć zmiany
  • git commit -m "changes"

Odpowiedzi:


342

Istnieje wiele różnych sposobów, w zależności od tego, jak daleko jesteś i w której gałęzi (ach) chcesz je mieć.

Zróbmy klasyczny błąd:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Więc teraz chcesz, aby te zmiany, do których jeszcze się nie zobowiązałeś master, były obecne develop.

  1. Jeśli nie maszdevelop jeszcze metoda jest trywialne:

    $ git checkout -b develop
    

    Tworzy to nową developgałąź, zaczynając od tego, gdzie teraz jesteś. Teraz możesz zatwierdzić i wszystko jest gotowe develop.

  2. Ci majądevelop . Sprawdź, czy Git pozwoli ci się przełączyć bez robienia czegokolwiek:

    $ git checkout develop
    

    To się powiedzie lub będzie narzekać. Jeśli to się uda, świetnie! Po prostu się zaangażuj. Jeśli nie ( error: Your local changes to the following files would be overwritten ...), nadal masz wiele opcji.

    Prawdopodobnie najłatwiej jest git stash(jak powiedzieli wszyscy inni respondenci, którzy pokonali mnie w kliknięciu post). Run git stash savelub git stash push, 1 lub po prostu git stashco jest skrótem save/ push:

    $ git stash
    

    To zatwierdza twój kod (tak, naprawdę robi pewne zatwierdzenia) przy użyciu dziwnej metody nie-rozgałęzienia-y. Wprowadzane przez niego zatwierdzenia nie znajdują się „w” żadnej gałęzi, ale są teraz bezpiecznie przechowywane w repozytorium, więc możesz teraz przełączać gałęzie, a następnie „stosować” skrytkę:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

    Jeśli wszystko pójdzie dobrze i podoba ci się wyniki, powinieneś to zrobić git stash drop. To usuwa odniesienie do dziwnych zatwierdzeń typu non-branch-y. (Nadal znajdują się w repozytorium i czasami można je odzyskać w nagłych wypadkach, ale w większości celów należy uznać, że w tym momencie zniknęły).

Ten applykrok łączy ukryte zmiany, korzystając z potężnego mechanizmu scalającego Git, tego samego rodzaju, którego używa podczas scalania gałęzi. Oznacza to, że możesz uzyskać „konflikty podczas łączenia”, jeśli gałąź, nad którą pracowałeś przez pomyłkę, wystarczająco różni się od gałęzi, nad którą zamierzałeś pracować. Dlatego dobrym pomysłem jest dokładne sprawdzenie wyników, zanim założysz, że skrytka została zastosowana prawidłowo, nawet jeśli sam Git nie wykrył żadnych konfliktów scalania.

Wiele osób używa git stash pop, co jest krótką ręką dla git stash apply && git stash drop. O ile to możliwe, to w porządku, ale oznacza to, że jeśli aplikacja spowoduje bałagan i zdecydujesz, że nie chcesz iść tą ścieżką, nie możesz łatwo odzyskać skrytki. Dlatego polecam oddzielić apply, sprawdzić wyniki, droptylko wtedy, gdy są satysfakcjonujące. (To oczywiście wprowadza kolejny punkt, w którym możesz zrobić kolejną przerwę na kawę i zapomnieć o tym, co robiłeś, wrócić i zrobić coś złego , więc nie jest to doskonałe lekarstwo).


1save w git stash saveto stary czasownik tworzenia nowego zapas. Git w wersji 2.13 wprowadził nowy czasownik, aby uczynić rzeczy bardziej spójnymi popi dodać więcej opcji do polecenia tworzenia. Git w wersji 2.16 formalnie zdezaktualizował stary czasownik (chociaż nadal działa w Git 2.23, który jest najnowszą wersją w czasie, gdy go edytuję).


3
Co jeśli chcę przełączyć się do innej gałęzi bez zatwierdzania bieżącej gałęzi (np. Zmiany nie zostały zakończone), a później wrócić do kontynuacji?
stt106

@ stt106: nadal musisz zatwierdzić, ale możesz to zrobić, tak jak w tej i innych odpowiedziach, przez git stashtak, że zatwierdzenia - ponieważ git stashdostajesz dwa zatwierdzenia na wpis w skrytce, w nietypowym układzie - nie znajdują się na żadnej gałęzi. Z wyjątkiem bardzo krótkoterminowych, specjalnych przypadków, generalnie wolę wykonywać zwykłe zatwierdzenie. Możesz git reset --softlub git reset --mixedpóźniej, lub użyj, git commit --amendaby odłożyć go na bok, kiedy wrócisz do pracy nad tą gałęzią. (W nowoczesnym Gicie można też użyć git worktree add, co może być jeszcze lepszym rozwiązaniem.)
torek

„To się powiedzie, albo będzie narzekać”. Jakie byłyby powody sukcesu lub błędu podczas realizacji transakcji?
nanocv


wszystkie moje zmiany lokalne są gubione, kiedy przełączam się z powyższymi krokami. Jestem w gałęzi <a> i wprowadzam zmiany, a chcę przejść do gałęzi <b> i wypchnąć w niej wszystkie zmiany. kiedy robię git stash i przechodzę do innych gałęzi, ściągam wszystkie pliki <b> gałęzi, a moje lokalne zmiany są gubione
Mukul Munjal

38

Użyj git stash

git stash

Wprowadza zmiany do stosu. Jeśli chcesz je cofnąć, użyj

 git stash apply

Możesz nawet wyciągać pojedyncze elementy. Aby całkowicie zdmuchnąć skrytkę:

 git stash clear

7
Ostatnią komendą powinno być prawdopodobnie git stash drop; git stash clearusunie cały stos skrytek, w tym prawdopodobnie niepowiązane z tym zestawem poleceń.
Leland

15
  • git stash aby zapisać niezatwierdzone zmiany
  • git stash list aby wyświetlić listę zapisanych niezaangażowanych skrytek
  • git stash apply stash@{x} gdzie x może być 0,1,2..nie utworzonych skrytek

4

Możesz albo :

  • Służy git stashdo odkładania zmian na półkę lub

  • Utwórz inną gałąź i zatwierdź tam swoje zmiany, a następnie scal tę gałąź z katalogiem roboczym

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.