Chcesz zmienić mojego mistrza na starszą wersję, jak mogę to zrobić?


92

Chcę cofnąć się do poprzedniego zatwierdzenia, a następnie opublikować ten kod, a następnie wrócić do ostatniego zatwierdzenia.

tzn. mój mistrz wskazuje na starszą wersję commita tylko po to, abym mógł ją skasować, a potem chcę wrócić do ostatniej rewizji, którą byłem na początku.

Jak mogę to zrobić?

Odpowiedzi:


100

Jeśli chcesz to zrobić i przywrócić wzorzec do poprzedniego zatwierdzenia:

git checkout master~1            # Checkout previous commit on master
git checkout -b new_master       # Create branch for new master
git branch -D master             # Delete old master
git branch -mv new_master master # Make new_master master

Alternatywnie:

git reset --hard master~1        # Reset current branch to one commit ago on master

1
Więc rok później patrzę na to i myślę, że to okropny sposób na zrobienie tego. No cóż, przynajmniej jest to dość łatwe do zrozumienia.
Tyler Brock

1
tak, dlatego zagłosowałem za, łatwe do zrozumienia, może powinieneś był przedstawić link do lepszego sposobu?
Andrew Atkinson

1
Musiałem zrobić to samo używając SourceTree. Proces jest podobny. 1) utwórz nową gałąź dla obecnego stanu głównego, aby nic nie stracić. 2) usuń master 3) utwórz nową gałąź master, wybierając żądany commit
Danilo Gomes,

Co się dzieje z zatwierdzeniem, które „usunęliśmy” z mastera po tym?
Arthur Colombini Gusmão,

1
Należy tego unikać, jeśli masz zdalne repozytorium. Powoduje to pewne błędy, jeśli to zrobisz, ponieważ adres pierwszego serwera głównego różni się od nowego utworzonego niedawno.
MAChitgarha

60

Twoje pytanie jest niejasne. Myślę, że o to prosisz:

git push -f origin $old_commit_id:master

Co to zrobi? Będzie nacisnąć $old_commit_idzobowiązać się originjako nowy szef origin„s masteroddziału.

Jeśli tego chciałeś, nie musisz w ogóle dotykać lokalnego masteroddziału.


To spowodowało master (non-fast-forward)dla mnie porażkę. Rozwiązanie @jtdubs zadziałało.
Bobby Norton

3
Po prostu przejdź, -faby to wymusić - chociaż zdalne repozytorium może być skonfigurowane tak, aby tego zabronić. Zaktualizowałem odpowiedź.
Arystoteles Pagaltzis

nie działa dla mnie, ale zaakceptowana odpowiedź działa
MobileMon

Nie powiedziałeś dokładnie, czego chciałeś lub dlaczego to nie zadziałało, więc nie mogę ci powiedzieć, dlaczego tak się nie stało i jak można było to zrobić (jeśli mogło).
Arystoteles Pagaltzis

Wydaje się, że dzięki takiemu podejściu tracisz historię na odległość, dla mnie było w porządku. Po prostu to wołam.
Shawn

43

posługiwać się git reset --hard <old commit number>

zresetuje HEAD do tego starego zatwierdzenia.

dodatkowo musisz użyć go git push -f origindo zmiany zdalnego repozytorium.


34

Jeśli chcesz uniknąć forsowania siły, oto jak przywrócić swoje repozytorium do starszego zatwierdzenia i zachować wszystkie interwencje:

git checkout 307a5cd        # check out the commit that you want to reset to 
git checkout -b fixy        # create a branch named fixy to do the work
git merge -s ours master    # merge master's history without changing any files
git checkout master         # switch back to master
git merge fixy              # and merge in the fixed branch
git push                    # done, no need to force push!

Gotowe! Zastąp 307a5cd dowolnym zatwierdzeniem, które chcesz w swoim repozytorium.

(Wiem, że pierwsze dwie linie można łączyć, ale myślę, że to sprawia, że ​​mniej jasne jest, co się dzieje)

Tutaj jest graficznie:

c1 -- c2 -- c3 -- c4 -- c2' -- c5 ...
        \              /
         '------------'

Skutecznie usuwasz c3 i c4 i ustawiasz projekt z powrotem na c2. Jednak c3 i c4 są nadal dostępne w historii twojego projektu, jeśli kiedykolwiek zechcesz je ponownie zobaczyć.


1
To działało bez problemu! Jeśli dotarłeś tak daleko i czytasz to - wydaje się, że jest to najczystszy sposób na przywrócenie mistrzowi głębszego zatwierdzenia.
ddisqq

Nie mogę znaleźć słów, aby wyjaśnić, jak bardzo cię za to kocham, jestem wielki poza słowami, że mogę naprawić coś, co sprawiło, że podsłuchuję mnie przez 6 godzin i sprawiło mi tyle bólu głowy. Dziękuję Panu!!!!!!!
Kostas Tsakalidis

9

Zakładając taki wykres zatwierdzenia:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                              (master)

Chcesz najpierw zapłacić masteri utworzyć gałąź, która wskazuje, gdzie masterobecnie jest:

git checkout master
git branch pointer master

Powinien teraz wyglądać tak:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                       (HEAD, master, pointer)

Teraz, gdy już jesteś włączony master, powiemy mastergałęzi, aby cofnęła się o jedno zatwierdzenie:

git reset master~1

Teraz masterpowinno zostać cofnięte o jedno miejsce, ale pointergałąź nadal znajduje się na ostatnim zatwierdzeniu:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|           (HEAD, master)    (pointer)

W tym momencie możesz naciskać master do pilota lub gdziekolwiek, a następnie szybko do przodu scalić go z powrotem do pointergałęzi. W pointertym momencie możesz zabić gałąź:

git push origin master
git merge --ff-only pointer
git branch -D pointer

Finał:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)

1
Jeśli źródło / wzorzec znajduje się w C, git push origin masterzakończy się niepowodzeniem, a końcówka bieżącej gałęzi znajduje się za jej zdalnym odpowiednikiem . Powinieneś także przekazać flagę -f.
sassospicco

8

Możesz po prostu git checkout <commit-id>zrobić wszystko, co musisz, a następnie git checkout masterwrócić do nowego kodu.

Jeśli faktycznie potrzebujesz zmodyfikować stary kod, aby go wydać, prawdopodobnie powinieneś:

git checkout -b my_release <commit-id>
... prepare code for release ...
... release code ...
git checkout master
git merge my_release

Nie mogę też wystarczająco polecić Git Flow . To sprawia, że ​​wszystko to jest dość łatwe.


1

Aby przejść do poprzedniej wersji:

git checkout <version hash>

wykonaj swoją pracę tutaj i poświęć ją

git commit --amend

Aby wrócić do mastera :

git checkout master


1
To nie zadziała. git reset --hardwskazał swoją gałąź master z powrotem na stary commit, więc git checkout masternic nie zrobi.
jtdubs

To prawda, dzięki za korektę. +1 do ciebie, usunąłbym też moją odpowiedź, ale myślę, że commit --amendkrok jest wystarczająco przydatny
Pablo Fernandez

Co --amend?
Shafizadeh
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.