Cofnij scalenie Git

225
develop branch
--> dashboard (working branch)

Używam git merge --no-ff developdo scalania wszelkich wcześniejszych zmian w desce rozdzielczej

dziennik git:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <[email protected]>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

Scalanie zawierało około 50+ zatwierdzeń i zastanawiam się, jak po prostu cofnąć scalanie, aby pulpit nawigacyjny powrócił do stanu sprzed scalenia

Druga część tego jest taka, że ​​jeśli się nie połączę --no-ff, nie dostaję zatwierdzenia „ Scal gałąź” rozwijaj się w pulpit nawigacyjny . Jak mógłbym przywrócić to scalenie?

cgmckeever
źródło
3
Możliwy duplikat scalenia Cofnij Git? .

Odpowiedzi:

320

Cofnięcie zatwierdzenia scalania zostało wyczerpująco omówione w innych pytaniach. Podczas scalania szybkiego przewijania, drugiego, który opisujesz, możesz użyć, git resetaby wrócić do poprzedniego stanu:

git reset --hard <commit_before_merge>

Można wybrać <commit_before_merge>z git reflog, git loglub, jeśli czujesz się Moxy (i nie zrobił nic innego):git reset --hard HEAD@{1}

Krzysztof
źródło
6
dzięki za szybką odpowiedź .. patrząc na git log, zatwierdzenie przed scaleniem wynosi 50+ zatwierdza z powrotem, ponieważ wywoływanie scalania git w rzeczywistości nakłada wszystkie pozostałe zatwierdzenia. Chyba nie dostaję, jeśli nie wiem, co / gdzie było to połączenie - jak go znaleźć? Wspominasz o znalezieniu commit_before_merge .. Chyba nie rozumiem tej części
cgmckeever
4
wygląda na to, że z git reflog ładnie podsumowuje ostatnie głowy i pozwala mi wiedzieć, gdzie muszę się zresetować. wydaje się, że git log ma zbyt dużą szczegółowość, aby wskazać miejsce do zresetowania. Dzięki
cgmckeever
1
Tak, reflogratownik. HEAD@{1}po prostu opisuje drugi ostatni stan HEAD, lub bardziej technicznie: „Ref, po którym następuje sufiks @ ze specyfikacją porządkową zawartą w parze nawiasów (np. {1}, {15}) określa n-tą poprzednią wartość tego ref. ”
Christopher
4
Co powiesz na przeniesienie przywracania do pilota? Nie wiem jak to będzie działać.
Anton Savelyev,
2
To jest beznadziejne. Niszczy wszystkie zatwierdzenia po scaleniu.
aaa90210,
151

Stąd:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git revert dodaje nowe zatwierdzenie, które przywraca określone zatwierdzenie.

Użycie -m 1 mówi, że jest to scalenie i chcemy przywrócić do nadrzędnego zatwierdzenia w gałęzi master. Użyj -m 2, aby określić gałąź rozwoju.

robertock
źródło
30
Zauważ, że nie możesz ponownie scalić gałęzi, ponieważ dokumenty mówią: „Cofnięcie zatwierdzenia scalania oświadcza, że ​​nigdy nie będziesz chciał zmian drzewa wprowadzonych przez scalanie. W rezultacie późniejsze scalenia przyniosą tylko wprowadzone zmiany w drzewie przez zatwierdzenia, które nie są przodkami wcześniej cofniętego scalenia. Może to być, lub nie, to, czego chcesz. ”
Dalibor Karlović
23
@ DaliborKarlović To stwierdzenie jest nieco surowe. Możesz zdecydowanie przywrócić te zmiany później, sztuczka polega na cofnięciu zatwierdzenia przywracania. Więcej informacji tutaj w sekcji „
Cofanie cofnięcia
3
Niestety herelink w komentarzu @Hilikus nie jest już prawidłowy. Witryna twierdzi, że treść została przeniesiona do książki ( git-scm.com/book/en/v2 ), ale jeśli tak, zlokalizowanie w niej nie jest trywialne.
Jesse Chisholm
@ DaliborKarlović czy tak jest w przypadku odpowiedzi powyżej z @Christopher?
James B
3
Zawartość scala Cofanie przeniesiono tutaj
SEK
28

Wystarczy zresetować zatwierdzenie scalania za pomocą git reset --hard HEAD^.

Jeśli użyjesz opcji --no-ff git zawsze tworzy scalenie, nawet jeśli nic nie zostało popełnione pomiędzy. Bez --no-ff git zrobi tylko szybkie przewijanie do przodu, co oznacza, że ​​HEAD twoich gałęzi zostanie ustawiony na HEAD połączonej gałęzi. Aby rozwiązać ten problem, znajdź identyfikator zatwierdzenia, do którego chcesz przywrócić i git reset --hard $COMMITID.

Nico Erfurth
źródło
1
Dobre rozwiązanie, jeśli nie znasz zatwierdzenia przed scaleniem.
iglesiasedd
Pracował dla mnie, ponieważ nie wiem identyfikator zatwierdzenia. + 1
Anant Singh --- Alive to Die
jeśli niechciane scalenie zostało już przypisane do zdalnego, użyłem git push -f do aktualizacji zdalnego oddziału po przywróceniu.
zumek
16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

Ale może mieć nieoczekiwane skutki uboczne. Zobacz --mainline parent-numberopcję w git-scm.com/docs/git-revert

Być może brutalnym, ale skutecznym sposobem byłoby sprawdzenie lewego nadrzędnego tego zatwierdzenia, wykonanie kopii wszystkich plików, HEADponowne pobranie i zastąpienie całej zawartości starymi plikami. Następnie git powie ci, co jest wycofywane, i utworzysz własne zatwierdzenie przywrócenia :)!

Jorge Orpinel
źródło
1
+1, ponieważ ta odpowiedź nie psuje historii, podobnie jak reset (bardzo ważne, jeśli już przeszedłeś na zdalne sterowanie). Ale jakich nieoczekiwanych skutków ubocznych powinienem się spodziewać?
pedromanoel
3
Czy to wspomniany efekt uboczny? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
pedromanoel
1
Mówisz, że git resetto rozwiązanie, ale wspomnij również, że może mieć nieoczekiwane skutki uboczne. Jednak ten link pochodzi git revert, a nie git reset:)
Mark
2
Uwaga: git reset nie ma flagi -m. Uwaga: @JorgeOrpinel odwołuje się do dokumentów git-revert, a nie git-reset. Myślę, że on chciał powiedzieć git revertniegit reset
Devin Gleason Lambert
Jak uniknąć Mainline został określony, ale zatwierdzenie 1234xyz nie jest błędem scalania .
Achal
0

Jeśli scaliłeś gałąź, to cofnąłeś scalenie za pomocą żądania ściągnięcia i scaliłeś to żądanie ściągnięcia, aby przywrócić.

Najłatwiej czułem:

  1. Wyjmij nowy oddział z develop / master (gdzie się połączyłeś)
  2. Cofnij „przywróć” za pomocą git revert -m 1 xxxxxx(jeśli przywrócenie zostało scalone za pomocą oddziału) lub za pomocą, git revert xxxxxxjeśli było to proste przywrócenie
  3. Nowy oddział powinien teraz mieć zmiany, które chcesz scalić ponownie.
  4. Wprowadź zmiany lub połącz tę gałąź w celu opracowania / opanowania
Rohin Tak
źródło