Jak wrócić do najnowszej wersji w Git?

303

Niedawno przeprowadziłem się z SVN do Git i jestem nieco zdezorientowany. Musiałem uruchomić poprzednią wersję skryptu przez debugger, więc zrobiłem git checkout <previous version hash>i zrobiłem, co musiałem zrobić.

Teraz chcę wrócić do najnowszej wersji, ale nie znam jej skrótu. Kiedy piszę git log, nie widzę tego.

W jaki sposób mogę to zrobić? Czy jest też łatwiejszy sposób na zmianę wersji niż wpisywanie skrótów - coś w rodzaju „cofnij dwie wersje” lub „przejdź do najnowszego chronologicznie”?

Nathan Long
źródło

Odpowiedzi:

371

git checkout masterpowinien załatwić sprawę. Wracając do dwóch wersji, możesz powiedzieć coś takiego git checkout HEAD~2, ale lepiej utworzyć tymczasową gałąź na podstawie tego czasu, więcgit checkout -b temp_branch HEAD~2

Ana Betts
źródło
7
Fajne! git checkout masterjest dokładnie tak, jak wróciłem z oddziału. Czy to oznacza, że ​​kiedy sprawdzam poprzednią wersję, zasadniczo tworzę gałąź?
Nathan Long
4
@Nathan: W git gałąź jest tak naprawdę głównie ruchomym wskaźnikiem do określonej wersji. Więc koncepcyjnie tworzysz gałąź, ale nie w tym sensie, że git myśli o gałęziach.
DLH
2
Więc w najprostszym przypadku, gdy mam kilka liniowych zmian, kiedy sprawdzam wcześniejszą wersję, przesuwam tam wskaźnik HEAD, co oznacza, git logże wyświetli się w stosunku do tego punktu? A kiedy kasuję wzorzec, przenoszę wskaźnik do najnowszej wersji gałęzi głównej?
Nathan Long
7
@Nathan: Dokładnie. HEAD jest czymś, co nazywa się symbolicznym ref - jest ogólnie wskaźnikiem do innego ref (aktualnie wyewidencjonowanej gałęzi). git checkoutto sposób na przesuwanie głowicy. Kiedy odłączyłeś HEAD, sprawiłeś, że wskazywał prosto na podany zatwierdzenie; przy ponownym sprawdzeniu wzorca wskazuje on na wzorzec. (I wiele wielu poleceń, takich jak git logfaktycznie, przyjmuje zakres zmian, który domyślnie jest ustawiony na HEAD.)
Cascabel
3
Tak - HEAD to „zaimek” używany w odniesieniu do „wersji kodu znajdującego się w katalogu roboczym”. Jest to również zaimek dla „Rodzica tego, co popełnisz później”
Ana Betts,
54

Kiedy kasujesz do konkretnego zatwierdzenia, git tworzy oddzielną gałąź. Więc jeśli zadzwonisz:

$ git branch 

Zobaczysz coś takiego:

* (detached from 3i4j25)
  master
  other_branch

Aby wrócić do głównego oddziału głównego, wystarczy ponownie złożyć zamówienie w głównym oddziale:

$ git checkout master

To polecenie automatycznie usunie odłączoną gałąź.

Jeśli git checkoutnie działa, prawdopodobnie zmodyfikowałeś pliki powodujące konflikt między oddziałami. Aby zapobiec utracie kodu, git wymaga radzenia sobie z tymi plikami. Masz trzy opcje:

  1. Ukryj swoje modyfikacje (możesz je później usunąć):

    $ git stash
    
  2. Odrzuć zmiany resetujące odłączoną gałąź:

    $ git reset --hard
    
  3. Utwórz nowy oddział z poprzednimi modyfikacjami i zatwierdź je:

    $ git checkout -b my_new_branch
    $ git add my_file.ext
    $ git commit -m "My cool msg"
    

Następnie możesz wrócić do głównej gałęzi (najnowsza wersja):

$ git checkout master
Thomio
źródło
36

To załatwiło sprawę (nadal byłem w gałęzi master):

git reset --hard origin/master
averasko
źródło
34
reset --hard to przesada i pokazuje, że nie wiesz o dokonanych modyfikacjach. Może to spowodować utratę kodu.
Thomio
1
W moim przypadku chciałem pozbyć się przypadkowych, przypadkowych zmian. Wiem, że istnieją inne metody osiągnięcia tego celu. Zgadzam się, że jeśli nie chcesz stracić nieprzypisanych zatwierdzonych zmian, oznacza to utratę danych.
Csaba Toth
8

Aby wrócić do najnowszej wersji:

git checkout <branch-name> 

Na przykład git checkout masterlubgit checkout dev

Reggie Pinkham
źródło
7

Po pierwsze, możesz sprawdzić, używając nazw oddziałów.

Wiem, że istnieje kilka sposobów na przesuwanie HEAD, ale zostawię to ekspertowi od gitów, aby je wyliczył.

Chciałem tylko zasugerować gitk --all- uznałem to za niezwykle pomocne, kiedy zaczynałem od git.

Sójka
źródło
7

Ja po prostu zaczynają kopać głębiej git, więc nie wiem, czy dobrze rozumiem, ale myślę, że prawidłowa odpowiedź na pytanie OP jest to, że można uruchomić git log --allze specyfikacją formatu takiego: git log --all --pretty=format:'%h: %s %d'. Oznacza to bieżącą wypisaną wersję jako (HEAD)i możesz po prostu pobrać kolejną z listy.

BTW, dodaj taki alias do swojego .gitconfigz nieco lepszym formatem i możesz uruchomić git hist --all:

  hist = log --pretty=format:\"%h %ai | %s%d [%an]\" --graph

Jeśli chodzi o wersje względne, znalazłem ten post , ale mówi on tylko o starszych wersjach, prawdopodobnie nie ma nic do odniesienia do nowszych wersji.

haridsv
źródło
6

Niektóre odpowiedzi tutaj zakładają, że jesteś w gałęzi master, zanim zdecydowałeś się pobrać starszą wersję zatwierdzenia. Nie zawsze tak jest.

git checkout -

Wskazuje ci powrót do gałęzi, w której byłeś (niezależnie od tego, czy był to master czy nie).

Itai Noam
źródło
Oddział nie jest konieczny, wskaże HEAD tam, gdzie wcześniej wskazywał; jeśli zrobiłeś git checkout hash2później git checkout hash1, git checkout -zabierze Cię z powrotem do hash1.
Michaił Vasin
3

Gdy wrócisz do poprzedniej wersji,

$ git checkout HEAD~2
Previous HEAD position was 363a8d7... Fixed a bug #32

Możesz zobaczyć swój dziennik funkcji (skrót) za pomocą tego polecenia, nawet w tej sytuacji;

$ git log master --oneline -5
4b5f9c2 Fixed a bug #34
9820632 Fixed a bug #33
...

master można zastąpić inną nazwą oddziału.

Następnie sprawdź, będziesz mógł wrócić do tej funkcji.

$ git checkout 4b5f9c2
HEAD is now at 4b5f9c2... Fixed a bug #34
kujiy
źródło
1

W przypadku Git 2.23+ (sierpień 2019 r.) Najlepszą praktyką byłoby używanie git switchzamiast mylącegit checkout polecenia.

Aby utworzyć nowy oddział na podstawie starszej wersji:

git switch -c temp_branch HEAD~2

Aby wrócić do bieżącej gałęzi głównej:

git switch master
VonC
źródło
0

Bardziej eleganckim i prostym rozwiązaniem jest użycie

git stash

Powróci do najbardziej niechętnej lokalnej wersji oddziału, a także zapisze zmiany w skrytce, więc jeśli chcesz cofnąć to działanie, wykonaj:

git stash apply
Ilya Gazman
źródło
Wiem, że jest bardzo stary, ale muszę to skomentować (ponieważ uważam, że tego rozwiązania nie należy stosować) - nie użyłbym tego rozwiązania, ponieważ nie rozwiązuje ono tego problemu, ale inny problem. dzięki temu rozwiązaniu za każdym razem, gdy chcesz przejść do poprzedniego zatwierdzenia, faktycznie „zapisujesz” dane, co w tym przypadku jest bardzo niepotrzebne. Właściwym i bardziej eleganckim sposobem jest (jak wspomniano wcześniej) po prostu zamówienie <branch>.
Maayao